idp_oidc: refactor cleaning of claim values (#57525)
This commit is contained in:
parent
bea7640b8e
commit
7d2c4ef181
|
@ -17,6 +17,7 @@
|
|||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import urllib.parse
|
||||
import uuid
|
||||
|
||||
|
@ -33,6 +34,8 @@ from authentic2.utils.template import Template
|
|||
|
||||
from . import app_settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def base64url(content):
|
||||
return base64.urlsafe_b64encode(content).strip(b'=')
|
||||
|
@ -170,15 +173,14 @@ def reverse_pairwise_sub(client, sub):
|
|||
return None
|
||||
|
||||
|
||||
def normalize_claim_values(values):
|
||||
values_list = []
|
||||
if isinstance(values, str) or not hasattr(values, '__iter__'):
|
||||
return values
|
||||
for value in values:
|
||||
if isinstance(value, bool):
|
||||
value = str(value).lower()
|
||||
values_list.append(value)
|
||||
return values_list
|
||||
def clean_claim_value(value):
|
||||
if isinstance(value, (int, float, str, bool)):
|
||||
return value
|
||||
if isinstance(value, dict):
|
||||
return {clean_claim_value(k): clean_claim_value(v) for k, v in value.items()}
|
||||
if hasattr(value, '__iter__'):
|
||||
return [clean_claim_value(v) for v in value]
|
||||
return str(value)
|
||||
|
||||
|
||||
def create_user_info(request, client, user, scope_set, id_token=False):
|
||||
|
@ -206,13 +208,23 @@ def create_user_info(request, client, user, scope_set, id_token=False):
|
|||
else:
|
||||
if claim.value not in attributes:
|
||||
continue
|
||||
attribute_value = attributes[claim.value]
|
||||
try:
|
||||
attribute_value = attributes[claim.value]
|
||||
except KeyError:
|
||||
msg = f'idp_oidc: could not map claim "{claim.name}", claim value "{claim.value}" not found'
|
||||
logger.exception(msg)
|
||||
if attribute_value is None:
|
||||
continue
|
||||
user_info[claim.name] = normalize_claim_values(attribute_value)
|
||||
try:
|
||||
user_info[claim.name] = clean_claim_value(attribute_value)
|
||||
except Exception:
|
||||
msg = f'idp_oidc: could not map claim {claim.name}'
|
||||
logger.exception(msg)
|
||||
continue
|
||||
# check if attribute is verified
|
||||
if claim.value + ':verified' in attributes:
|
||||
user_info[claim.name + '_verified'] = True
|
||||
|
||||
for claim in claims_to_show:
|
||||
if claim.name not in user_info:
|
||||
default_value = None
|
||||
|
|
|
@ -27,6 +27,7 @@ from django.core.files import File
|
|||
from django.http import QueryDict
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from django.utils.dateparse import parse_datetime
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.timezone import now
|
||||
from jwcrypto.jwk import JWK, JWKSet
|
||||
|
@ -289,12 +290,16 @@ def test_authorization_code_sso(
|
|||
OIDCClaim.objects.create(
|
||||
client=oidc_client, name='cityscape_image', value='django_user_cityscape_image', scopes='profile'
|
||||
)
|
||||
OIDCClaim.objects.create(
|
||||
client=oidc_client, name='date_joined', value='django_user_date_joined', scopes='profile'
|
||||
)
|
||||
simple_user.roles.add(
|
||||
get_role_model().objects.create(name='Whatever', slug='whatever', ou=get_default_ou())
|
||||
)
|
||||
response = app.get(user_info_url, headers=bearer_authentication_headers(access_token))
|
||||
assert response.json['ou'] == simple_user.ou.name
|
||||
assert response.json['roles'][0] == 'Whatever'
|
||||
assert parse_datetime(response.json['date_joined'])
|
||||
assert response.json.get('cityscape_image') is None
|
||||
with open('tests/200x200.jpg', 'rb') as fd:
|
||||
simple_user.attributes.cityscape_image = File(fd)
|
||||
|
|
Loading…
Reference in New Issue