Projet

Général

Profil

0001-idp_oidc-revoke-oidc-claims-authorization-45200.patch

Nicolas Roche, 20 juillet 2020 15:18

Télécharger (6,69 ko)

Voir les différences:

Subject: [PATCH] idp_oidc: revoke oidc claims authorization (#45200)

 .../authentic2/authorized_oauth_apps.html     | 36 +++++++++++++++++++
 src/authentic2/urls.py                        |  3 ++
 src/authentic2/views.py                       | 24 +++++++++++++
 tests/test_idp_oidc.py                        | 29 +++++++++++++++
 4 files changed, 92 insertions(+)
 create mode 100644 src/authentic2/templates/authentic2/authorized_oauth_apps.html
src/authentic2/templates/authentic2/authorized_oauth_apps.html
1
{% extends "authentic2/base-page.html" %}
2
{% load i18n %}
3

  
4
{% block content %}
5
{% block oidc-authorized-oauth-apps-pre %}{% endblock %}
6
<div id="oidc-authorized-oauth-apps" class="authorized-oauth-apps">
7
  {% block oidc-authorized-oauth-apps-top %}{% endblock %}
8
  {% if authorized_oauth_apps|length_is:0 %}
9
  {% trans "You have no granted application access to your account." %}
10
  {% else %}
11
  <ul>
12
    {% for auth in authorized_oauth_apps %}
13
    <li>
14
      <form method="post">
15
        {% csrf_token %}
16
        <input type="hidden" id="auth-id" name="auth_id" value="{{ auth.id }}">
17
        <span class="oidc-authorized-oauth-apps-client">
18
          {{ auth.client }}
19
        </span>
20
        <span class="oidc-authorized-oauth-apps-since">
21
          allowed since {{ auth.created }}
22
        </span>
23
        <span class="oidc-authorized-oauth-apps-expired">
24
          (expire on {{ auth.expired }})
25
        </span>
26
        <button class="delete-button">{% trans 'Delete' %}</button>
27
      </form>
28
    </li>
29
    {% endfor %}
30
  </ul>
31
  </table>
32
  {% endif %}
33
  {% block oidc-authorized-oauth-apps-bottom %}{% endblock %}
34
</div>
35
{% block oidc-authorized-oauth-apps-post %}{% endblock %}
36
{% endblock %}
src/authentic2/urls.py
64 64
        views.edit_profile,
65 65
        name='profile_edit_with_scope'),
66 66
    url(r'^change-email/$',
67 67
        views.email_change,
68 68
        name='email-change'),
69 69
    url(r'^change-email/verify/$',
70 70
        views.email_change_verify,
71 71
        name='email-change-verify'),
72
    url(r'^authorizations/$',
73
        login_required(views.authorized_oauth_apps),
74
        name='authorized-oauth-apps'),
72 75
    url(r'^$',
73 76
        views.profile,
74 77
        name='account_management'),
75 78

  
76 79
    # Password change
77 80
    url(r'^password/change/$',
78 81
        views.password_change,
79 82
        name='password_change'),
src/authentic2/views.py
50 50
from django.http import Http404
51 51
from django.utils.http import urlsafe_base64_decode
52 52
from django.views.generic.edit import CreateView
53 53
from django.forms import CharField
54 54
from django.http import HttpResponseBadRequest
55 55
from django.template import loader
56 56

  
57 57
from authentic2.compat.misc import default_token_generator
58
from authentic2_idp_oidc.models import OIDCAuthorization
58 59
from . import (utils, app_settings, decorators, constants,
59 60
               models, cbv, hooks, validators)
60 61
from .utils import switch_user
61 62
from .a2_rbac.utils import get_default_ou
62 63
from .a2_rbac.models import OrganizationalUnit as OU
63 64
from .forms import (
64 65
    passwords as passwords_forms,
65 66
    registration as registration_forms,
......
1264 1265
class SuView(View):
1265 1266
    def get(self, request, uuid):
1266 1267
        user = switch_user.resolve_token(uuid)
1267 1268
        if not user:
1268 1269
            raise Http404
1269 1270
        return utils.simulate_authentication(request, user, 'su')
1270 1271

  
1271 1272
su = SuView.as_view()
1273

  
1274

  
1275
class AuthorizedOauthAppsView(TemplateView):
1276
    template_name = 'authentic2/authorized_oauth_apps.html'
1277
    title = _('Granted Applications')
1278

  
1279
    def get_context_data(self, **kwargs):
1280
        context = super(AuthorizedOauthAppsView, self).get_context_data(**kwargs)
1281
        context['authorized_oauth_apps'] = OIDCAuthorization.objects.filter(
1282
            user=self.request.user)
1283
        return context
1284

  
1285
    def post(self, request, *args, **kwargs):
1286
        if request.user:
1287
            qs = OIDCAuthorization.objects.filter(user=request.user)
1288
            auth_id = request.POST.get('auth_id')
1289
            if auth_id:
1290
                qs = qs.filter(id=auth_id)
1291
            qs.delete()
1292
        return HttpResponseRedirect(reverse('authorized-oauth-apps'))
1293

  
1294

  
1295
authorized_oauth_apps = AuthorizedOauthAppsView.as_view()
tests/test_idp_oidc.py
1599 1599
    with pytest.raises(ValidationError, match=r'same domain'):
1600 1600
        OIDCClient(
1601 1601
            redirect_uris='https://example.com/ https://example2.com/',
1602 1602
            identifier_policy=OIDCClient.POLICY_PAIRWISE).clean()
1603 1603

  
1604 1604
    OIDCClient(
1605 1605
        redirect_uris='https://example.com/ https://example2.com/',
1606 1606
        sector_identifier_uri='https://example.com/').clean()
1607

  
1608

  
1609
def test_oidc_authorized_oauth_apps_views(app, oidc_client, simple_user):
1610
    url = make_url('authorized-oauth-apps')
1611
    response = app.get(url, status=302)
1612
    assert '/login/' in response.location
1613

  
1614
    utils.login(app, simple_user)
1615
    response = app.get(url, status=200)
1616
    assert "You have no granted application access to your account." in response.text
1617

  
1618
    OIDCAuthorization.objects.create(
1619
        client=oidc_client, user=simple_user, scopes='openid',
1620
        expired=now() + datetime.timedelta(days=2))
1621
    OIDCAuthorization.objects.create(
1622
        client=oidc_client, user=simple_user, scopes='openid profile',
1623
        expired=now() + datetime.timedelta(days=2))
1624
    OIDCAuthorization.objects.create(
1625
        client=oidc_client, user=simple_user, scopes='openid profile email',
1626
        expired=now() + datetime.timedelta(days=2))
1627

  
1628
    response = app.get(url, status=200)
1629
    assert "You have no granted application access to your account." not in response.text
1630
    assert len(response.html.find_all('button', {'class': 'delete-button'})) == 3
1631

  
1632
    # revoke one
1633
    response = response.forms[1].submit()
1634
    response = response.follow()
1635
    assert len(response.html.find_all('button', {'class': 'delete-button'})) == 2
1607
-