0001-idp_oidc-discard-any-extra-scopes-at-profile-selecti.patch
src/authentic2_idp_oidc/templates/authentic2_idp_oidc/authorization.html | ||
---|---|---|
23 | 23 |
</ul> |
24 | 24 |
{% endif %} |
25 | 25 |
{% if needs_profile_validation %} |
26 |
<div id="profile-validation"> |
|
27 |
<p>{% trans "You may authenticate as owner of the following juridical entity management profile, which may change the aforementioned information." %}</p> |
|
26 |
<div id="profile-validation"> |
|
27 |
<p>{% trans "You may authenticate as owner of the following management profile, which may change the aforementioned information." %}</p> |
|
28 |
{% if "email" in scopes %} |
|
29 |
<p>{% blocktrans with client_name=client.name %}In this case, {{ client_name }} will collect your managenement profile email address instead of your personal email address.{% endblocktrans %}</p> |
|
30 |
{% endif %} |
|
31 |
{% if "profile" in scopes %} |
|
32 |
<p>{% blocktrans with client_name=client.name %}{{ client_name }} will still collect your first name, your last name and your username.{% endblocktrans %}</p> |
|
33 |
{% endif %} |
|
34 |
{% if extra_scopes %} |
|
35 |
{% blocktrans with client_name=client.name %}Additional personal info will not be sent to {{ client_name }}.{% endblocktrans %} |
|
36 |
{% endif %} |
|
28 | 37 |
<div class="profile" id="profile-validation-none"> |
29 | 38 |
<input type="radio" id="_none" name="profile-validation" value="" checked> |
30 | 39 |
<label for="_none">{% trans "Keep my default user profile." %}</label> |
src/authentic2_idp_oidc/views.py | ||
---|---|---|
306 | 306 |
if not scope: |
307 | 307 |
raise MissingParameter('scope') |
308 | 308 |
scopes = utils.scope_set(scope) |
309 |
extra_scopes = scopes - {'openid', 'email', 'profile'} |
|
309 | 310 |
if 'openid' not in scopes: |
310 | 311 |
raise InvalidScope(_('Scope must contain "openid", received "%s"') % ', '.join(sorted(scopes))) |
311 | 312 |
if not is_scopes_allowed(scopes, client): |
... | ... | |
405 | 406 |
) |
406 | 407 |
except Profile.DoesNotExist: |
407 | 408 |
pass |
409 |
if profile and extra_scopes: |
|
410 |
logger.info( |
|
411 |
'idp_oidc: profile of type %s chosen by user %s for client %s, discarding scopes %s', |
|
412 |
profile.profile_type, |
|
413 |
request.user, |
|
414 |
client, |
|
415 |
' '.join(extra_scopes), |
|
416 |
) |
|
417 |
scopes = scopes - extra_scopes |
|
408 | 418 |
if 'accept' in request.POST: |
409 | 419 |
if 'do_not_ask_again' in request.POST: |
410 | 420 |
pk_to_deletes = [] |
... | ... | |
441 | 451 |
'needs_scope_validation': needs_scope_validation, |
442 | 452 |
'client': client, |
443 | 453 |
'scopes': scopes - {'openid'}, |
454 |
'extra_scopes': extra_scopes, |
|
444 | 455 |
}, |
445 | 456 |
) |
446 | 457 |
if response_type == 'code': |
tests/idp_oidc/test_user_profiles.py | ||
---|---|---|
423 | 423 |
) |
424 | 424 |
response = app.get(authorize_url) |
425 | 425 |
assert 'do_not_ask_again' not in response.text |
426 | ||
427 | ||
428 |
def test_scopes_minimization(app, oidc_client, profile_user, profile_settings): |
|
429 |
oidc_client.idtoken_algo = oidc_client.ALGO_HMAC |
|
430 |
oidc_client.activate_user_profiles = True |
|
431 |
oidc_client.perform_sub_profile_substitution = True |
|
432 |
oidc_client.scope = 'openid profile email custom1 custom2 custom3' |
|
433 |
oidc_client.save() |
|
434 |
redirect_uri = oidc_client.redirect_uris.split()[0] |
|
435 |
params = { |
|
436 |
'client_id': oidc_client.client_id, |
|
437 |
'scope': 'openid profile email custom1 custom2 custom3', |
|
438 |
'redirect_uri': redirect_uri, |
|
439 |
'state': 'xxx', |
|
440 |
'nonce': 'yyy', |
|
441 |
'login_hint': 'backoffice john@example.com', |
|
442 |
'response_type': 'code', |
|
443 |
} |
|
444 | ||
445 |
assert not OIDCCode.objects.count() |
|
446 |
assert not OIDCAuthorization.objects.count() |
|
447 | ||
448 |
# firt attempt with no profile: all scopes are saved |
|
449 |
authorize_url = make_url('oidc-authorize', params=params) |
|
450 |
utils.login(app, profile_user) |
|
451 |
response = app.get(authorize_url) |
|
452 |
response.form.set('profile-validation', '') |
|
453 |
response = response.form.submit('accept') |
|
454 |
assert OIDCCode.objects.get(user=profile_user).scope_set() == set( |
|
455 |
'openid profile email custom1 custom2 custom3'.split(' ') |
|
456 |
) |
|
457 |
OIDCCode.objects.get(user=profile_user).delete() |
|
458 | ||
459 |
# second attempt while selection profile: extra scopes are discarded |
|
460 |
authorize_url = make_url('oidc-authorize', params=params) |
|
461 |
utils.login(app, profile_user) |
|
462 |
response = app.get(authorize_url) |
|
463 |
response.form.set('profile-validation', profile_user.profiles.first().id) |
|
464 |
response = response.form.submit('accept') |
|
465 |
assert OIDCCode.objects.get(user=profile_user).scope_set() == set('openid profile email'.split(' ')) |
|
426 |
- |