manager: filter apiclient's available ous on user's ou perms (#72688)
gitea/authentic/pipeline/head This commit looks good Details

This commit is contained in:
Paul Marillonnet 2022-12-21 16:20:38 +01:00
parent ba5602efc0
commit af77cf8157
3 changed files with 62 additions and 2 deletions

View File

@ -46,6 +46,18 @@ class APIClientsMixin(PermissionMixin, MediaMixin, TitleMixin):
return qs.filter(ou__in=allowed_ous)
class APIClientsFormViewMixin(APIClientsMixin):
def get_form(self, form_class=None):
form = super().get_form(form_class=form_class)
if not self.request.user.has_perm('authentic2.admin_apiclient'):
allowed_ous = []
for ou in OrganizationalUnit.objects.all():
if self.request.user.has_ou_perm('authentic2.admin_apiclient', ou):
allowed_ous.append(ou.id)
form.fields['ou'].queryset = OrganizationalUnit.objects.filter(id__in=allowed_ous)
return form
class APIClientsView(APIClientsMixin, ListView):
template_name = 'authentic2/manager/api_clients.html'
title = _('API Clients')
@ -71,7 +83,7 @@ class APIClientDetailView(APIClientsMixin, DetailView):
detail = APIClientDetailView.as_view()
class APIClientAddView(APIClientsMixin, CreateView):
class APIClientAddView(APIClientsFormViewMixin, CreateView):
template_name = 'authentic2/manager/api_client_form.html'
title = _('New API client')
form_class = forms.APIClientForm
@ -93,7 +105,7 @@ class APIClientAddView(APIClientsMixin, CreateView):
add = APIClientAddView.as_view()
class APIClientEditView(APIClientsMixin, UpdateView):
class APIClientEditView(APIClientsFormViewMixin, UpdateView):
template_name = 'authentic2/manager/api_client_form.html'
title = _('Edit API client')
form_class = forms.APIClientForm

View File

@ -934,6 +934,7 @@ class APIClientForm(forms.ModelForm):
'description',
'identifier',
'password',
'ou',
'restrict_to_anonymised_data',
'apiclient_roles',
)
@ -945,6 +946,7 @@ class APIClientForm(forms.ModelForm):
'description',
'identifier',
'password',
'ou',
'restrict_to_anonymised_data',
'apiclient_roles',
)

View File

@ -177,6 +177,19 @@ def test_add(superuser, app):
assert urlparse(response.request.url).path == api_client.get_absolute_url()
def test_add_local_admin(admin_ou1, app, ou1, ou2):
assert APIClient.objects.count() == 0
resp = login(app, admin_ou1, 'a2-manager-api-client-add')
form = resp.form
assert len(form['ou'].options) == 1
assert form['ou'].options[0][2] == 'OU1'
role = Role.objects.get(slug='_a2-manager-of-api-clients-%s' % ou2.slug)
admin_ou1.roles.add(role)
resp = app.get(reverse('a2-manager-api-client-add'))
assert len(resp.form['ou'].options) == 2
def test_add_description_non_mandatory(superuser, app):
assert APIClient.objects.count() == 0
role_1 = Role.objects.create(name='role-1')
@ -241,6 +254,39 @@ def test_edit(superuser, app):
assert api_client.identifier == 'foo-identifier'
def test_edit_local_admin(admin_ou1, app, ou1, ou2):
api_client_ou1 = APIClient.objects.create(
name='foo',
description='foo-description',
identifier='foo-description',
password='foo-password',
ou=ou1,
)
api_client_ou2 = APIClient.objects.create(
name='bar',
description='bar-description',
identifier='bar-description',
password='bar-password',
ou=ou2,
)
resp = login(app, admin_ou1, 'a2-manager-api-client-edit', kwargs={'pk': api_client_ou1.pk})
form = resp.form
assert form.get('password').value == 'foo-password'
resp.form.set('password', 'easy')
response = form.submit().follow()
assert urlparse(response.request.url).path == api_client_ou1.get_absolute_url()
api_client = APIClient.objects.get(password='easy')
assert api_client.identifier == 'foo-description'
role = Role.objects.get(slug='_a2-manager-of-api-clients-%s' % ou2.slug)
admin_ou1.roles.add(role)
resp = app.get(reverse('a2-manager-api-client-edit', kwargs={'pk': api_client_ou2.pk}))
assert resp.form.get('password').value == 'bar-password'
resp.form.set('ou', ou1.id)
resp.form.submit().follow()
assert APIClient.objects.filter(ou=ou1).count() == 2
def test_delete(superuser, app):
api_client = APIClient.objects.create(
name='foo', description='foo-description', identifier='foo-identifier', password='foo-password'