hooks: add userinfo relevant crown attributes when profile is selected (#75398)
gitea/authentic2-cut/pipeline/head This commit looks good Details

This commit is contained in:
Paul Marillonnet 2023-03-14 09:17:11 +01:00
parent a0b75fafb7
commit 49ba23f4b0
2 changed files with 73 additions and 64 deletions

View File

@ -497,72 +497,64 @@ class AppConfig(django.apps.AppConfig):
return queryset
def a2_hook_idp_oidc_modify_user_info(self, client, user, scope_set, user_info, profile=None):
if profile:
return
sub = user_info['sub']
user_info.clear()
user_info['sub'] = sub
if 'email' in scope_set:
user_info['email'] = user.email
if 'profile' in scope_set:
user_info['first_name'] = user.first_name
user_info['last_name'] = user.last_name
user_info['given_name'] = user.first_name
user_info['family_name'] = user.last_name
user_info['title'] = user.attributes.title
user_info['gender'] = {'Monsieur': 'male', 'Madame': 'female'}.get(user.attributes.title)
user_info['birthdate'] = user.attributes.birthdate and user.attributes.birthdate.isoformat()
user_info['birthplace'] = user.attributes.birthplace
user_info['birthcountry'] = user.attributes.birthcountry
user_info['birthplace_insee'] = user.attributes.birthplace_insee
user_info['birthcountry_insee'] = user.attributes.birthcountry_insee
user_info['validated'] = user.attributes.validated
user_info['validation_date'] = (
user.attributes.validation_date and user.attributes.validation_date.isoformat()
)
user_info['validation_context'] = user.attributes.validation_context
# pass user.ou.slug for agent's users
if user.ou:
if user.ou.slug != 'usagers':
user_info['ou'] = user.ou.slug
else:
if user.attributes.validated:
for name in [
'first_name',
'last_name',
'given_name',
'family_name',
'title',
'gender',
'birthdate',
'birthplace_insee',
'birthplace',
'birthcountry_insee',
'birthcountry',
]:
user_info['%s_verified' % name] = True
if not profile:
sub = user_info['sub']
user_info.clear()
user_info['sub'] = sub
if 'email' in scope_set:
user_info['email'] = user.email
if 'profile' in scope_set:
user_info['first_name'] = user.first_name
user_info['last_name'] = user.last_name
user_info['given_name'] = user.first_name
user_info['family_name'] = user.last_name
user_info['title'] = user.attributes.title
user_info['gender'] = {'Monsieur': 'male', 'Madame': 'female'}.get(user.attributes.title)
user_info['birthdate'] = user.attributes.birthdate and user.attributes.birthdate.isoformat()
user_info['birthplace'] = user.attributes.birthplace
user_info['birthcountry'] = user.attributes.birthcountry
user_info['birthplace_insee'] = user.attributes.birthplace_insee
user_info['birthcountry_insee'] = user.attributes.birthcountry_insee
user_info['validated'] = user.attributes.validated
user_info['validation_date'] = (
user.attributes.validation_date and user.attributes.validation_date.isoformat()
)
user_info['validation_context'] = user.attributes.validation_context
# pass user.ou.slug for agent's users
if user.ou:
if user.ou.slug != 'usagers':
user_info['ou'] = user.ou.slug
else:
if user.attributes.validated:
for name in [
'first_name',
'last_name',
'given_name',
'family_name',
'title',
'gender',
'birthdate',
'birthplace_insee',
'birthplace',
'birthcountry_insee',
'birthcountry',
]:
user_info['%s_verified' % name] = True
if 'crown' in scope_set:
user_info['preferred_username'] = user.attributes.preferred_username
user_info['preferred_givenname'] = user.attributes.preferred_givenname
user_info['address_number'] = user.attributes.address_number
user_info['address_street'] = user.attributes.address_street
user_info['address_complement'] = user.attributes.address_complement
user_info['address_zipcode'] = user.attributes.address_zipcode
user_info['address_city'] = user.attributes.address_city
user_info['address_country'] = user.attributes.address_country
user_info['home_mobile_phone'] = user.attributes.home_mobile_phone
user_info['home_phone'] = user.attributes.home_phone
user_info['professional_mobile_phone'] = user.attributes.professional_mobile_phone
user_info['professional_phone'] = user.attributes.professional_phone
user_info['birthdepartment'] = user.attributes.birthdepartment
if user.fc_accounts.exists():
import json
try:
fc_user_info = json.loads(user.fc_accounts.all()[0].user_info)
except ValueError:
fc_user_info = {}
if not profile:
user_info['address_number'] = user.attributes.address_number
user_info['address_street'] = user.attributes.address_street
user_info['address_complement'] = user.attributes.address_complement
user_info['address_zipcode'] = user.attributes.address_zipcode
user_info['address_city'] = user.attributes.address_city
user_info['address_country'] = user.attributes.address_country
user_info['home_mobile_phone'] = user.attributes.home_mobile_phone
user_info['home_phone'] = user.attributes.home_phone
user_info['birthdepartment'] = user.attributes.birthdepartment
def a2_hook_event(self, name, **kwargs):
method_name = 'cut_event_' + name.replace('-', '_')

View File

@ -48,6 +48,14 @@ def test_a2_hook_idp_oidc_modify_user_info(db, rf, app):
dummy = DummyModule()
User = get_user_model()
user = User.objects.create(email='john.doe@example.org', first_name='John', last_name='Doe')
user.attributes.preferred_username = 'Current name'
user.attributes.preferred_givenname = 'Current givenname'
user.attributes.professional_phone = '0123456789'
user.attributes.professional_mobile_phone = '0623456789'
user.attributes.home_phone = '0133456789'
user.attributes.home_mobile_phone = '0633456789'
user.save()
app_config = AppConfig('authentic2_cut', dummy)
client = None # unused in hook
scope_set = {'email', 'profile', 'openid', 'crown'}
@ -65,12 +73,18 @@ def test_a2_hook_idp_oidc_modify_user_info(db, rf, app):
assert user_info['given_name'] == 'John'
assert user_info['last_name'] == 'Doe'
assert user_info['family_name'] == 'Doe'
assert user_info['preferred_username'] == 'Current name'
assert user_info['preferred_givenname'] == 'Current givenname'
assert user_info['professional_phone'] == '0123456789'
assert user_info['professional_mobile_phone'] == '0623456789'
assert user_info['home_phone'] == '0133456789'
assert user_info['home_mobile_phone'] == '0633456789'
# phone- & address-related user information is not provided by FC by any means
assert 'phone' not in user_info
assert 'address' not in user_info
for claim, value in user_info.items():
if claim.endswith('_phone') or claim.startswith('address_'):
if claim.startswith('address_'):
assert value is None
profile_type = ProfileType.objects.create(
@ -89,17 +103,20 @@ def test_a2_hook_idp_oidc_modify_user_info(db, rf, app):
'first_name': 'Original first name',
'last_name': 'Original last name',
}
# second attempt with profile, whose presence is detected by the hook, thus bypassed
app_config.a2_hook_idp_oidc_modify_user_info(client, user, scope_set, user_info, profile=profile)
assert user_info['email'] == 'abc@ad.dre.ss'
assert user_info['first_name'] == 'Original first name'
assert user_info['last_name'] == 'Original last name'
assert user_info['preferred_username'] == 'Current name'
assert user_info['preferred_givenname'] == 'Current givenname'
assert user_info['professional_phone'] == '0123456789'
assert user_info['professional_mobile_phone'] == '0623456789'
assert 'phone' not in user_info
assert 'address' not in user_info
for claim, value in user_info.items():
if claim.endswith('_phone') or claim.startswith('address_'):
if claim.startswith('home_') and claim.endswith('_phone') or claim.startswith('address_'):
assert value is None