auth_oidc: add hook to modify user before login (fixes #22209)

Hook is named a2_hook_auth_oidc_backend_modify_user, it takes
parameters:
- user
- access_token
- user_info
- id_token
- provider
This commit is contained in:
Benjamin Dauvergne 2018-03-01 16:16:19 +01:00
parent 9eb98fad5f
commit b7274d2ddc
2 changed files with 10 additions and 2 deletions

View File

@ -14,7 +14,7 @@ from django.contrib.auth.backends import ModelBackend
from django_rbac.utils import get_ou_model
from authentic2.crypto import base64url_encode
from authentic2 import app_settings
from authentic2 import app_settings, hooks
from . import models, utils
@ -227,6 +227,11 @@ class OIDCBackend(ModelBackend):
user.ou = user_ou
save_user = True
if any(hooks.call_hooks(
'auth_oidc_backend_modify_user',
user=user, user_info=user_info, access_token=access_token, id_token=id_token, provider=provider)):
save_user = True
if save_user:
user.save()

View File

@ -245,7 +245,7 @@ def check_simple_qs(qs):
return qs
def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, login_url, login_callback_url):
def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, login_url, login_callback_url, hooks):
OU = get_ou_model()
cassis = OU.objects.create(name='Cassis', slug='cassis')
OU.cached.cache.clear()
@ -291,9 +291,12 @@ def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, login_url,
with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code,
extra_id_token={'aud': 'zz'}):
response = app.get(login_callback_url, params={'code': code, 'state': query['state']})
assert not hooks.auth_oidc_backend_modify_user
with utils.check_log(caplog, 'created user'):
with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code):
response = app.get(login_callback_url, params={'code': code, 'state': query['state']})
assert len(hooks.auth_oidc_backend_modify_user) == 1
assert set(hooks.auth_oidc_backend_modify_user[0]['kwargs']) >= set(['user', 'provider', 'user_info', 'id_token', 'access_token'])
assert urlparse.urlparse(response['Location']).path == '/admin/'
assert User.objects.count() == 1
user = User.objects.get()