0001-idp_oidc-fix-profile-suffix-during-sub-generation-62.patch
src/authentic2_idp_oidc/apps.py | ||
---|---|---|
88 | 88 |
sub = smart_bytes(view.kwargs[lookup_url_kwarg]) |
89 | 89 |
decrypted = utils.reverse_pairwise_sub(client, sub) |
90 | 90 |
if decrypted: |
91 |
view.kwargs[lookup_url_kwarg] = uuid.UUID(bytes=decrypted.split(b'#')[0]).hex
|
|
91 |
view.kwargs[lookup_url_kwarg] = uuid.UUID(bytes=decrypted).hex |
|
92 | 92 | |
93 | 93 |
def a2_hook_api_modify_serializer_after_validation(self, view, serializer): |
94 | 94 |
import uuid |
... | ... | |
111 | 111 |
for u in serializer.validated_data['known_uuids']: |
112 | 112 |
decrypted = utils.reverse_pairwise_sub(client, smart_bytes(u)) |
113 | 113 |
if decrypted: |
114 |
new_known_uuid = uuid.UUID(bytes=decrypted.split(b'#')[0]).hex
|
|
114 |
new_known_uuid = uuid.UUID(bytes=decrypted).hex |
|
115 | 115 |
new_known_uuids.append(new_known_uuid) |
116 | 116 |
uuid_map[new_known_uuid] = u |
117 | 117 |
else: |
src/authentic2_idp_oidc/utils.py | ||
---|---|---|
175 | 175 |
sector_identifier, |
176 | 176 |
] |
177 | 177 |
if profile and client.perform_sub_profile_substitution: |
178 |
cipher_args[1] += b'#%s' % str(profile.id).encode() |
|
178 |
cipher_args[1] += b'#profile-id:%s' % str(profile.id).encode()
|
|
179 | 179 |
return crypto.aes_base64url_deterministic_encrypt(*cipher_args).decode('utf-8') |
180 | 180 | |
181 | 181 | |
182 | 182 |
def reverse_pairwise_sub(client, sub): |
183 | 183 |
sector_identifier = client.get_sector_identifier() |
184 | 184 |
try: |
185 |
return crypto.aes_base64url_deterministic_decrypt(
|
|
185 |
reversed_id = crypto.aes_base64url_deterministic_decrypt(
|
|
186 | 186 |
settings.SECRET_KEY.encode('utf-8'), sub, sector_identifier |
187 | 187 |
) |
188 |
return reversed_id.split(b'#profile-id:')[0] |
|
188 | 189 |
except crypto.DecryptionError: |
189 | 190 |
return None |
190 | 191 |
tests/idp_oidc/test_user_profiles.py | ||
---|---|---|
17 | 17 |
import base64 |
18 | 18 |
import json |
19 | 19 |
import urllib.parse |
20 |
from uuid import UUID |
|
20 | 21 | |
21 | 22 |
import pytest |
22 | 23 |
from django.contrib.auth import get_user_model |
... | ... | |
29 | 30 |
from authentic2.custom_user.models import Profile, ProfileType |
30 | 31 |
from authentic2.utils.misc import make_url |
31 | 32 |
from authentic2_idp_oidc.models import OIDCAccessToken, OIDCCode |
32 |
from authentic2_idp_oidc.utils import get_jwkset, make_sub |
|
33 |
from authentic2_idp_oidc.utils import get_jwkset, make_pairwise_sub, make_sub, reverse_pairwise_sub
|
|
33 | 34 | |
34 | 35 |
from .. import utils |
35 | 36 |
from .conftest import client_authentication_headers |
... | ... | |
334 | 335 |
claims = json.loads(jwt.claims) |
335 | 336 |
assert claims['sub'] != make_sub(oidc_client, profile_user) |
336 | 337 |
assert claims['sub'] == make_sub(oidc_client, profile_user, profile=profile_user.profiles.first()) |
338 | ||
339 | ||
340 |
def test_full_sub_reversibility(app, oidc_client, profile_settings): |
|
341 |
from django.utils.encoding import smart_bytes |
|
342 | ||
343 |
oidc_client.idtoken_algo = oidc_client.ALGO_EC |
|
344 |
oidc_client.activate_user_profiles = True |
|
345 |
oidc_client.perform_sub_profile_substitution = True |
|
346 |
oidc_client.identifier_policy = oidc_client.POLICY_PAIRWISE_REVERSIBLE |
|
347 |
oidc_client.save() |
|
348 |
profile_type_manager = ProfileType.objects.create( |
|
349 |
name='One Manager Type', |
|
350 |
slug='one-manager-type', |
|
351 |
) |
|
352 |
# first with no profiles |
|
353 |
for i in range(10): |
|
354 |
user = User.objects.create( |
|
355 |
first_name='john-%s' % i, |
|
356 |
last_name='doe', |
|
357 |
email='john.doe.%s@example.org' % i, |
|
358 |
) |
|
359 |
sub = make_pairwise_sub(oidc_client, user, profile=None) |
|
360 |
uuid = reverse_pairwise_sub(oidc_client, smart_bytes(sub)) |
|
361 |
assert uuid == UUID(user.uuid).bytes |
|
362 | ||
363 |
# then adding user profile information |
|
364 |
for i in range(100): |
|
365 |
user = User.objects.create( |
|
366 |
first_name='john-%s' % i, |
|
367 |
last_name='doe', |
|
368 |
email='john.doe.%s@example.org' % i, |
|
369 |
) |
|
370 |
profile = Profile.objects.create( |
|
371 |
user=user, |
|
372 |
profile_type=profile_type_manager, |
|
373 |
identifier='manager %s' % i, |
|
374 |
email='manager-%s@example.org' % i, |
|
375 |
) |
|
376 |
sub_with_profile = make_pairwise_sub(oidc_client, user, profile=profile) |
|
377 |
sub_without_profile = make_pairwise_sub(oidc_client, user, profile=None) |
|
378 |
uuid_with_profile = reverse_pairwise_sub(oidc_client, smart_bytes(sub_with_profile)) |
|
379 |
uuid_without_profile = reverse_pairwise_sub(oidc_client, smart_bytes(sub_without_profile)) |
|
380 |
assert sub_with_profile != sub_without_profile |
|
381 |
assert uuid_with_profile == uuid_without_profile |
|
382 |
assert uuid_with_profile == UUID(user.uuid).bytes |
|
337 |
- |