0001-idp_oidc-add-do-not-ask-again-authorization-checkbox.patch
src/authentic2_idp_oidc/templates/authentic2_idp_oidc/authorization.html | ||
---|---|---|
1 | 1 |
{% extends "authentic2/base-page.html" %} |
2 | 2 |
{% load i18n %} |
3 | 3 |
{% block content %} |
4 |
<form method="post" id="a2-oidc-authorization-form">
|
|
4 |
<form method="post" id="a2-oidc-authorization-form"> |
|
5 | 5 |
<p>{% blocktrans with client_name=client.name %}Do you want to be authenticated on service {{ client_name }} ?{% endblocktrans %}</p> |
6 | 6 |
{% if scopes %} |
7 | 7 |
<p>{% trans "The following informations will be sent to the service:" %}</p> |
... | ... | |
16 | 16 |
</ul> |
17 | 17 |
{% endif %} |
18 | 18 |
{% csrf_token %} |
19 |
<p class="a2-oidc-authorization-form--do-not-ask-again"> |
|
20 |
<label for="id_do_not_ask_again"><input type="checkbox" name="do_not_ask_again" value="on"/><span>{% trans "Do not ask again" %}</span></label> |
|
21 |
</p> |
|
19 | 22 |
<button name="accept">{% trans "Accept" %}</button> |
20 | 23 |
<button name="refuse">{% trans "Refuse" %}</button> |
21 | 24 |
</form> |
src/authentic2_idp_oidc/views.py | ||
---|---|---|
270 | 270 |
fragment=fragment) |
271 | 271 |
if request.method == 'POST': |
272 | 272 |
if 'accept' in request.POST: |
273 |
pk_to_deletes = [] |
|
274 |
for authorization in qs: |
|
275 |
# clean obsolete authorizations |
|
276 |
if authorization.scope_set() <= scopes: |
|
277 |
pk_to_deletes.append(authorization.pk) |
|
278 |
auth_manager.create( |
|
279 |
user=request.user, scopes=u' '.join(sorted(scopes)), |
|
280 |
expired=start + datetime.timedelta(days=365)) |
|
281 |
if pk_to_deletes: |
|
282 |
auth_manager.filter(pk__in=pk_to_deletes).delete() |
|
283 |
logger.info(u'authorized scopes %s for service %s', ' '.join(scopes), |
|
284 |
client.name) |
|
273 |
if 'do_not_ask_again' in request.POST: |
|
274 |
pk_to_deletes = [] |
|
275 |
for authorization in qs: |
|
276 |
# clean obsolete authorizations |
|
277 |
if authorization.scope_set() <= scopes: |
|
278 |
pk_to_deletes.append(authorization.pk) |
|
279 |
auth_manager.create( |
|
280 |
user=request.user, scopes=u' '.join(sorted(scopes)), |
|
281 |
expired=start + datetime.timedelta(days=365)) |
|
282 |
if pk_to_deletes: |
|
283 |
auth_manager.filter(pk__in=pk_to_deletes).delete() |
|
284 |
logger.info(u'authorized scopes %s saved for service %s', ' '.join(scopes), |
|
285 |
client.name) |
|
286 |
else: |
|
287 |
logger.info(u'authorized scopes %s for service %s', ' '.join(scopes), |
|
288 |
client.name) |
|
285 | 289 |
else: |
286 | 290 |
logger.info(u'refused scopes %s for service %s', ' '.join(scopes), |
287 | 291 |
client.name) |
tests/test_idp_oidc.py | ||
---|---|---|
31 | 31 |
from django.db import connection |
32 | 32 |
from django.db.migrations.executor import MigrationExecutor |
33 | 33 |
from django.utils.timezone import now |
34 |
from django.test.client import RequestFactory |
|
35 | 34 |
from django.contrib.auth import get_user_model |
36 | 35 |
from django.utils.six.moves.urllib import parse as urlparse |
37 |
from ratelimit.utils import is_ratelimited |
|
38 | 36 | |
39 | 37 | |
40 |
User = get_user_model() |
|
41 | ||
42 | 38 |
from authentic2.models import Attribute, AuthorizedRole |
43 | 39 |
from authentic2_idp_oidc.models import OIDCClient, OIDCAuthorization, OIDCCode, OIDCAccessToken, OIDCClaim |
44 |
from authentic2_idp_oidc.utils import (make_sub, get_first_rsa_sig_key, |
|
45 |
base64url) |
|
40 |
from authentic2_idp_oidc.utils import make_sub, get_first_rsa_sig_key, base64url |
|
46 | 41 |
from authentic2.a2_rbac.utils import get_default_ou |
47 | 42 |
from authentic2.utils import make_url |
48 | 43 |
from authentic2_auth_oidc.utils import parse_timestamp |
49 | 44 |
from django_rbac.utils import get_role_model |
50 | 45 | |
46 |
User = get_user_model() |
|
47 | ||
51 | 48 |
pytestmark = pytest.mark.django_db |
52 | 49 | |
53 | 50 |
JWKSET = { |
... | ... | |
174 | 171 |
return {'Authorization': 'Bearer %s' % str(access_token)} |
175 | 172 | |
176 | 173 | |
174 |
@pytest.mark.parametrize('do_not_ask_again', [(True,), (False,)]) |
|
177 | 175 |
@pytest.mark.parametrize('login_first', [(True,), (False,)]) |
178 |
def test_authorization_code_sso(login_first, oidc_settings, oidc_client, simple_user, app): |
|
176 |
def test_authorization_code_sso(login_first, do_not_ask_again, oidc_settings, oidc_client, simple_user, app):
|
|
179 | 177 |
redirect_uri = oidc_client.redirect_uris.split()[0] |
180 | 178 |
params = { |
181 | 179 |
'client_id': oidc_client.client_id, |
... | ... | |
207 | 205 |
assert OIDCAuthorization.objects.count() == 0 |
208 | 206 |
assert OIDCCode.objects.count() == 0 |
209 | 207 |
assert OIDCAccessToken.objects.count() == 0 |
208 |
response.form['do_not_ask_again'] = do_not_ask_again |
|
210 | 209 |
response = response.form.submit('accept') |
211 |
assert OIDCAuthorization.objects.count() == 1 |
|
212 |
authz = OIDCAuthorization.objects.get() |
|
213 |
assert authz.client == oidc_client |
|
214 |
assert authz.user == simple_user |
|
215 |
assert authz.scope_set() == set('openid profile email'.split()) |
|
216 |
assert authz.expired >= now() |
|
210 |
if do_not_ask_again: |
|
211 |
assert OIDCAuthorization.objects.count() == 1 |
|
212 |
authz = OIDCAuthorization.objects.get() |
|
213 |
assert authz.client == oidc_client |
|
214 |
assert authz.user == simple_user |
|
215 |
assert authz.scope_set() == set('openid profile email'.split()) |
|
216 |
assert authz.expired >= now() |
|
217 |
else: |
|
218 |
assert OIDCAuthorization.objects.count() == 0 |
|
217 | 219 |
if oidc_client.authorization_flow == oidc_client.FLOW_AUTHORIZATION_CODE: |
218 | 220 |
assert OIDCCode.objects.count() == 1 |
219 | 221 |
code = OIDCCode.objects.get() |
... | ... | |
645 | 647 |
authorize.scopes = 'openid profile' |
646 | 648 |
authorize.save() |
647 | 649 |
assert OIDCAuthorization.objects.count() == 1 |
650 |
response.form['do_not_ask_again'] = True |
|
648 | 651 |
response = response.form.submit('accept') |
649 | 652 |
assert OIDCAuthorization.objects.count() == 1 |
650 | 653 |
# old authorizations have been deleted |
... | ... | |
845 | 848 |
response = response.form.submit(name='login-password-submit') |
846 | 849 |
response = response.follow() |
847 | 850 |
if oidc_client.authorization_mode != oidc_client.AUTHORIZATION_MODE_NONE: |
851 |
response.form['do_not_ask_again'] = True |
|
848 | 852 |
response = response.form.submit('accept') |
849 | 853 |
assert OIDCAuthorization.objects.get() |
850 | 854 |
if oidc_client.authorization_flow == oidc_client.FLOW_AUTHORIZATION_CODE: |
851 |
- |