Projet

Général

Profil

0001-manager-filter-api-client-qs-on-user-s-admin-ou-perm.patch

Paul Marillonnet, 21 décembre 2022 17:36

Télécharger (8,11 ko)

Voir les différences:

Subject: [PATCH 1/2] manager: filter api client qs on user's admin ou
 permissions (#72688)

 src/authentic2/manager/apiclient_views.py     | 16 ++++-
 .../authentic2/manager/api_client_detail.html |  1 +
 .../authentic2/manager/api_clients.html       |  2 +-
 tests/test_manager_apiclient.py               | 71 +++++++++++++++++--
 4 files changed, 81 insertions(+), 9 deletions(-)
src/authentic2/manager/apiclient_views.py
20 20
from django.utils.translation import gettext_lazy as _
21 21
from django.views.generic import CreateView, DeleteView, DetailView, ListView, UpdateView
22 22

  
23
from authentic2.a2_rbac.models import OrganizationalUnit
23 24
from authentic2.manager import forms
24 25
from authentic2.manager.views import MediaMixin, PermissionMixin, TitleMixin
25 26
from authentic2.models import APIClient
......
28 29
class APIClientsMixin(PermissionMixin, MediaMixin, TitleMixin):
29 30
    model = APIClient
30 31
    permissions = ['authentic2.admin_apiclient']
31
    permissions_global = True
32
    permissions_global = False
32 33

  
33 34
    def get_queryset(self):
34
        return self.model.objects.all()
35
        if not self.request.user:
36
            return self.model.objects.none()
37

  
38
        qs = self.model.objects.all()
39
        if self.request.user.has_perm('authentic2.admin_apiclient'):
40
            return qs
41

  
42
        allowed_ous = []
43
        for ou in OrganizationalUnit.objects.all():
44
            if self.request.user.has_ou_perm('authentic2.admin_apiclient', ou):
45
                allowed_ous.append(ou)
46
        return qs.filter(ou__in=allowed_ous)
35 47

  
36 48

  
37 49
class APIClientsView(APIClientsMixin, ListView):
src/authentic2/manager/templates/authentic2/manager/api_client_detail.html
23 23
    <ul>
24 24
      <li>{% trans "Identifier" %}{% trans ":" %} {{api_client.identifier}}</li>
25 25
      <li>{% trans "Password" %}{% trans ":" %} {{api_client.password}}</li>
26
      <li>{% trans "Organizational unit" %}{% trans ":" %} {{ api_client.ou.name }}</li>
26 27
      {% if api_client.restrict_to_anonymised_data %}<li>{% trans "Restricted to anonymised data" %}</li>{% endif %}
27 28
      {% if api_client.apiclient_roles.count %}
28 29
        <li>{% trans "Roles:" %}
src/authentic2/manager/templates/authentic2/manager/api_clients.html
13 13
    <ul class="objects-list single-links">
14 14
      {% for api_client in object_list %}
15 15
        <li>
16
          <a href="{% url 'a2-manager-api-client-detail' pk=api_client.pk %}">{{api_client.name}} ({{api_client.identifier}})</a>
16
          <a href="{% url 'a2-manager-api-client-detail' pk=api_client.pk %}">{{ api_client.name }} ({{ api_client.identifier }}) - {{ api_client.ou.name }}</a>
17 17
        </li>
18 18
      {% endfor %}
19 19
    </ul>
tests/test_manager_apiclient.py
32 32
        return app
33 33

  
34 34
    @pytest.fixture
35
    def api_client(self, db):
35
    def api_client(self, db, ou1):
36 36
        return APIClient.objects.create(
37
            name='foo', description='foo-description', identifier='foo-description', password='foo-password'
37
            name='foo',
38
            description='foo-description',
39
            identifier='foo-description',
40
            password='foo-password',
41
            ou=ou1,
38 42
        )
39 43

  
40 44
    class Mixin:
41 45
        status_code = -1
46
        existing_client_status_code = -1
42 47

  
43 48
        def test_list(self, app):
44 49
            app.get(reverse('a2-manager-api-clients'), status=self.status_code)
......
48 53

  
49 54
        def test_detail(self, app, api_client):
50 55
            app.get(
51
                reverse('a2-manager-api-client-detail', kwargs={'pk': api_client.pk}), status=self.status_code
56
                reverse('a2-manager-api-client-detail', kwargs={'pk': api_client.pk}),
57
                status=self.existing_client_status_code,
52 58
            )
53 59

  
54 60
        def test_edit(self, app, api_client):
55 61
            app.get(
56
                reverse('a2-manager-api-client-edit', kwargs={'pk': api_client.pk}), status=self.status_code
62
                reverse('a2-manager-api-client-edit', kwargs={'pk': api_client.pk}),
63
                status=self.existing_client_status_code,
57 64
            )
58 65

  
59 66
        def test_delete(self, app, api_client):
60 67
            app.get(
61
                reverse('a2-manager-api-client-delete', kwargs={'pk': api_client.pk}), status=self.status_code
68
                reverse('a2-manager-api-client-delete', kwargs={'pk': api_client.pk}),
69
                status=self.existing_client_status_code,
62 70
            )
63 71

  
64 72
    class TestAuthorization(Mixin):
65 73
        status_code = 403
74
        existing_client_status_code = 404
66 75

  
67 76
        @pytest.fixture
68 77
        def user(self, simple_user):
69 78
            return simple_user
70 79

  
80
    class TestAuthorizationLocalAdminWrongOu(Mixin):
81
        status_code = 200
82
        existing_client_status_code = 404
83

  
84
        @pytest.fixture
85
        def user(self, admin_ou2):
86
            return admin_ou2
87

  
88
    class TestAuthorizationLocalAdminRightOu(Mixin):
89
        status_code = 200
90
        existing_client_status_code = 200
91

  
92
        @pytest.fixture
93
        def user(self, admin_ou1):
94
            return admin_ou1
95

  
71 96
    class TestAuthorizationAdmin(Mixin):
72 97
        status_code = 200
98
        existing_client_status_code = 200
73 99

  
74 100
        @pytest.fixture
75 101
        def user(self, simple_user):
......
95 121
    url = '/manage/api-clients/%s/' % api_client.pk
96 122
    resp = login(app, superuser, 'a2-manager-api-clients')
97 123
    anchor = resp.pyquery('div.content ul.objects-list a[href="%s"]' % url)
98
    assert anchor.text() == 'foo (foo-description)'
124
    assert anchor.text() == 'foo (foo-description) - Default organizational unit'
125

  
126

  
127
def test_list_show_objects_local_admin(admin_ou1, app, ou1, ou2):
128
    api_client_ou1 = APIClient.objects.create(
129
        name='foo',
130
        description='foo-description',
131
        identifier='foo-description',
132
        password='foo-password',
133
        ou=ou1,
134
    )
135
    api_client_ou2 = APIClient.objects.create(
136
        name='bar',
137
        description='bar-description',
138
        identifier='bar-description',
139
        password='bar-password',
140
        ou=ou2,
141
    )
142
    url = '/manage/api-clients/%s/' % api_client_ou1.pk
143
    resp = login(app, admin_ou1, 'a2-manager-api-clients')
144
    assert len(resp.pyquery('div.content ul.objects-list li')) == 1
145
    anchor = resp.pyquery('div.content ul.objects-list a[href="%s"]' % url)
146
    assert anchor.text() == 'foo (foo-description) - OU1'
147

  
148
    role = Role.objects.get(slug='_a2-manager-of-api-clients-%s' % ou2.slug)
149
    admin_ou1.roles.add(role)
150
    admin_ou1.save()
151
    resp = app.get(reverse('a2-manager-api-clients'))
152
    assert len(resp.pyquery('div.content ul.objects-list li')) == 2
153
    anchor = resp.pyquery('div.content ul.objects-list a[href="%s"]' % url)
154
    assert anchor.text() == 'foo (foo-description) - OU1'
155
    url = '/manage/api-clients/%s/' % api_client_ou2.pk
156
    anchor = resp.pyquery('div.content ul.objects-list a[href="%s"]' % url)
157
    assert anchor.text() == 'bar (bar-description) - OU2'
99 158

  
100 159

  
101 160
def test_add(superuser, app):
102
-