0002-idp_oidc-discard-profile-selection-from-do-not-ask-a.patch
src/authentic2_idp_oidc/templates/authentic2_idp_oidc/authorization.html | ||
---|---|---|
35 | 35 |
<label for="{{ profile.id }}"> |
36 | 36 |
{% with identifier=profile.identifier type_name=profile.profile_type.name %} |
37 | 37 |
{% trans "Unknown entity" as fallback_identifier %} |
38 |
<div> |
|
38 | 39 |
{% blocktrans %}Profile of type {{ type_name }}: {% endblocktrans %} |
39 |
{% firstof identifier fallback_identifier %}<br /> |
|
40 |
{% firstof identifier fallback_identifier %} |
|
41 |
</div> |
|
40 | 42 |
{% endwith %} |
41 | 43 |
{% if profile.email %} |
42 |
{% blocktrans with email=profile.email %}Email address: {{ email }}{% endblocktrans %}<br /> |
|
44 |
<div> |
|
45 |
{% blocktrans with email=profile.email %}Email address: {{ email }}{% endblocktrans %} |
|
46 |
</div> |
|
43 | 47 |
{% endif %}</label> |
44 | 48 |
</div> |
45 | 49 |
{% endfor %} |
46 | 50 |
</div> |
47 |
{% endif %} |
|
48 |
{% csrf_token %} |
|
51 |
{% else %} |
|
49 | 52 |
<p class="a2-oidc-authorization-form--do-not-ask-again"> |
50 | 53 |
<label for="id_do_not_ask_again"><input id="id_do_not_ask_again" type="checkbox" name="do_not_ask_again" value="on"/><span>{% trans "Do not ask again" %}</span></label> |
51 | 54 |
</p> |
55 |
{% endif %} |
|
56 |
{% csrf_token %} |
|
52 | 57 |
<div class="buttons"> |
53 | 58 |
<button name="accept">{% trans "Accept" %}</button> |
54 | 59 |
<button name="refuse">{% trans "Refuse" %}</button> |
src/authentic2_idp_oidc/views.py | ||
---|---|---|
384 | 384 |
else: |
385 | 385 |
qs = qs.filter(expired__gte=iat) |
386 | 386 |
authorized_scopes = set() |
387 |
authorized_profile = None |
|
388 | 387 |
for authorization in qs: |
389 | 388 |
authorized_scopes |= authorization.scope_set() |
390 |
# load first authorized profile |
|
391 |
if not authorized_profile and authorization.profile: |
|
392 |
authorized_profile = authorization.profile |
|
393 |
if request.user.profiles.count() and not authorized_profile and client.activate_user_profiles: |
|
389 |
if request.user.profiles.count() and client.activate_user_profiles: |
|
394 | 390 |
needs_profile_validation = True |
395 |
else: |
|
396 |
profile = authorized_profile |
|
397 | 391 |
if (authorized_scopes & scopes) < scopes: |
398 | 392 |
needs_scope_validation = True |
399 | 393 |
if needs_scope_validation or needs_profile_validation: |
... | ... | |
417 | 411 |
pk_to_deletes.append(authorization.pk) |
418 | 412 |
auth_manager.create( |
419 | 413 |
user=request.user, |
420 |
profile=profile, |
|
421 | 414 |
scopes=' '.join(sorted(scopes)), |
422 | 415 |
expired=iat + datetime.timedelta(days=365), |
423 | 416 |
) |
tests/idp_oidc/test_user_profiles.py | ||
---|---|---|
30 | 30 | |
31 | 31 |
from authentic2.custom_user.models import Profile, ProfileType |
32 | 32 |
from authentic2.utils.misc import make_url |
33 |
from authentic2_idp_oidc.models import OIDCAccessToken, OIDCCode |
|
33 |
from authentic2_idp_oidc.models import OIDCAccessToken, OIDCAuthorization, OIDCCode
|
|
34 | 34 |
from authentic2_idp_oidc.utils import get_jwkset, make_pairwise_sub, make_sub, reverse_pairwise_sub |
35 | 35 | |
36 | 36 |
from .. import utils |
... | ... | |
428 | 428 |
assert claims['email'] == 'def@ad.dre.ss' |
429 | 429 |
assert claims['profile'] == profile_user.profiles.first().id |
430 | 430 |
assert claims['customclaim'] == 'whatever' |
431 | ||
432 | ||
433 |
def test_do_no_ask_again(app, oidc_client, profile_user, profile_settings): |
|
434 |
oidc_client.idtoken_algo = oidc_client.ALGO_HMAC |
|
435 |
oidc_client.activate_user_profiles = True |
|
436 |
oidc_client.perform_sub_profile_substitution = True |
|
437 |
oidc_client.save() |
|
438 |
redirect_uri = oidc_client.redirect_uris.split()[0] |
|
439 |
params = { |
|
440 |
'client_id': oidc_client.client_id, |
|
441 |
'scope': 'openid profile email', |
|
442 |
'redirect_uri': redirect_uri, |
|
443 |
'state': 'xxx', |
|
444 |
'nonce': 'yyy', |
|
445 |
'login_hint': 'backoffice john@example.com', |
|
446 |
'response_type': 'code', |
|
447 |
} |
|
448 | ||
449 |
authorize_url = make_url('oidc-authorize', params=params) |
|
450 |
utils.login(app, profile_user) |
|
451 | ||
452 |
# attempt with profile, 'do not ask again' checkbox absent |
|
453 |
response = app.get(authorize_url) |
|
454 |
assert 'do_not_ask_again' not in response.text |
|
455 | ||
456 |
# when no profile is set, fallback to usual 'do not ask again' logic |
|
457 |
Profile.objects.filter(user=profile_user).delete() |
|
458 |
response = app.get(authorize_url) |
|
459 |
assert 'do_not_ask_again' in response.text |
|
460 |
assert OIDCAuthorization.objects.filter(user=profile_user).count() == 0 |
|
461 |
response.form['do_not_ask_again'] = True |
|
462 |
response.form.submit('accept') |
|
463 | ||
464 |
# when an authorization has been defined yet the user posesses profiles, |
|
465 |
# the authorization form is still displayed |
|
466 |
assert OIDCAuthorization.objects.filter(user=profile_user).count() == 1 |
|
467 |
Profile.objects.create( |
|
468 |
user=profile_user, |
|
469 |
profile_type=ProfileType.objects.first(), |
|
470 |
email='entity123@example.org', |
|
471 |
) |
|
472 |
response = app.get(authorize_url) |
|
473 |
assert 'do_not_ask_again' not in response.text |
|
431 |
- |