idp_oidc: add a profile reference in modify_user_info hook (#63164)

This commit is contained in:
Paul Marillonnet 2022-03-25 11:36:14 +01:00
parent 9e3ebc339f
commit be7d250b87
2 changed files with 62 additions and 1 deletions

View File

@ -269,7 +269,7 @@ def create_user_info(request, client, user, scope_set, id_token=False, profile=N
flat_data = profile.data.copy()
flatten_dict(flat_data)
user_info.update(flat_data)
hooks.call_hooks('idp_oidc_modify_user_info', client, user, scope_set, user_info)
hooks.call_hooks('idp_oidc_modify_user_info', client, user, scope_set, user_info, profile=profile)
return user_info

View File

@ -17,6 +17,7 @@
import base64
import json
import urllib.parse
from unittest import mock
from uuid import UUID
import pytest
@ -367,3 +368,63 @@ def test_full_sub_reversibility(app, oidc_client, profile_settings):
assert sub_with_profile != sub_without_profile
assert uuid_with_profile == uuid_without_profile
assert uuid_with_profile == UUID(user.uuid).bytes
def test_modify_user_info_hook(app, oidc_client, profile_settings, profile_user, hooks):
class MockAppConfig:
def a2_hook_idp_oidc_modify_user_info(self, client, user, scope_set, user_info, profile=None):
user_info.clear()
user_info['email'] = 'def@ad.dre.ss'
user_info['profile'] = profile.id
user_info['customclaim'] = 'whatever'
def mock_get_hooks(hook_name):
app_config = MockAppConfig()
return [app_config.a2_hook_idp_oidc_modify_user_info]
oidc_client.idtoken_algo = oidc_client.ALGO_HMAC
oidc_client.activate_user_profiles = True
oidc_client.save()
redirect_uri = oidc_client.redirect_uris.split()[0]
params = {
'client_id': oidc_client.client_id,
'scope': 'openid profile email',
'redirect_uri': redirect_uri,
'state': 'xxx',
'nonce': 'yyy',
'login_hint': 'backoffice john@example.com',
'response_type': 'code',
}
authorize_url = make_url('oidc-authorize', params=params)
utils.login(app, profile_user)
response = app.get(authorize_url)
response.form.set('profile-validation', profile_user.profiles.first().id)
response = response.form.submit('accept')
location = urllib.parse.urlparse(response['Location'])
query = urllib.parse.parse_qs(location.query)
code = query['code'][0]
token_url = make_url('oidc-token')
with mock.patch('authentic2.hooks.get_hooks') as get_hooks:
get_hooks.return_value = mock_get_hooks('')
response = app.post(
token_url,
params={
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': oidc_client.redirect_uris.split()[0],
},
headers=client_authentication_headers(oidc_client),
)
id_token = response.json['id_token']
k = base64.b64encode(oidc_client.client_secret.encode('utf-8'))
key = JWK(kty='oct', k=force_text(k))
algs = ['HS256']
jwt = JWT(jwt=id_token, key=key, algs=algs)
claims = json.loads(jwt.claims)
assert claims['email'] == 'def@ad.dre.ss'
assert claims['profile'] == profile_user.profiles.first().id
assert claims['customclaim'] == 'whatever'