1145 lines
46 KiB
Python
1145 lines
46 KiB
Python
# -*- coding: utf-8 -*-
|
|
# authentic2 - versatile identity manager
|
|
# Copyright (C) 2010-2019 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
import pytest
|
|
import json
|
|
|
|
from django.core import mail
|
|
from django.urls import reverse
|
|
from django.utils.encoding import force_str
|
|
|
|
from webtest import Upload
|
|
|
|
from authentic2.a2_rbac.models import MANAGE_MEMBERS_OP
|
|
from authentic2.a2_rbac.utils import get_default_ou
|
|
from authentic2.validators import EmailValidator
|
|
|
|
from django_rbac.utils import (get_ou_model, get_role_model,
|
|
get_permission_model, get_operation)
|
|
from django_rbac.models import VIEW_OP
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.utils.encoding import force_bytes
|
|
from django.utils.six.moves.urllib.parse import urlparse
|
|
from .utils import login, get_link_from_mail, request_select2
|
|
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
OU = get_ou_model()
|
|
User = get_user_model()
|
|
Role = get_role_model()
|
|
|
|
|
|
def test_manager_login(superuser_or_admin, app):
|
|
manager_home_page = login(app, superuser_or_admin, reverse('a2-manager-homepage'))
|
|
|
|
sections = ['users', 'roles', 'ous', 'services']
|
|
|
|
for section in sections:
|
|
path = reverse('a2-manager-%s' % section)
|
|
assert manager_home_page.pyquery.remove_namespaces()('.apps a[href=\'%s\']' % path)
|
|
|
|
|
|
def test_manager_create_ou(superuser_or_admin, app):
|
|
ou_add = login(app, superuser_or_admin, path=reverse('a2-manager-ou-add'))
|
|
form = ou_add.form
|
|
assert 'name' in form.fields
|
|
assert 'slug' not in form.fields
|
|
form.set('name', 'New OU')
|
|
response = form.submit().follow()
|
|
assert 'New OU' in response
|
|
assert OU.objects.count() == 2
|
|
assert OU.objects.get(name='New OU').slug == 'new-ou'
|
|
|
|
# Test slug collision
|
|
OU.objects.filter(name='New OU').update(name='Old OU')
|
|
response = form.submit().follow()
|
|
assert 'Old OU' in response
|
|
assert 'New OU' in response
|
|
assert OU.objects.get(name='Old OU').slug == 'new-ou'
|
|
assert OU.objects.get(name='New OU').slug == 'new-ou1'
|
|
assert OU.objects.count() == 3
|
|
|
|
|
|
def test_manager_create_role(superuser_or_admin, app):
|
|
non_admin_roles = Role.objects.exclude(slug__startswith='_')
|
|
|
|
ou_add = login(app, superuser_or_admin, reverse('a2-manager-role-add'))
|
|
form = ou_add.form
|
|
assert 'name' in form.fields
|
|
assert 'description' in form.fields
|
|
assert 'ou' not in form.fields
|
|
assert 'slug' not in form.fields
|
|
form.set('name', 'New role')
|
|
response = form.submit().follow()
|
|
assert non_admin_roles.count() == 1
|
|
role = non_admin_roles.get()
|
|
assert response.request.path == reverse('a2-manager-role-members', kwargs={'pk': role.pk})
|
|
role_list = app.get(reverse('a2-manager-roles'))
|
|
assert 'New role' in role_list
|
|
|
|
# Test slug collision
|
|
non_admin_roles.update(name='Old role')
|
|
response = form.submit().follow()
|
|
role_list = app.get(reverse('a2-manager-roles'))
|
|
assert 'New role' in role_list
|
|
assert 'Old role' in role_list
|
|
assert non_admin_roles.count() == 2
|
|
assert non_admin_roles.get(name='New role').slug == 'new-role1'
|
|
assert non_admin_roles.get(name='Old role').slug == 'new-role'
|
|
|
|
# Test multi-ou form
|
|
OU.objects.create(name='New OU', slug='new-ou')
|
|
ou_add = app.get(reverse('a2-manager-role-add'))
|
|
form = ou_add.form
|
|
assert 'name' in form.fields
|
|
assert 'description' in form.fields
|
|
assert 'ou' in form.fields
|
|
options = [o[2] for o in form.fields['ou'][0].options]
|
|
assert len(options) == 3
|
|
assert '---------' in options
|
|
assert 'New OU' in options
|
|
|
|
|
|
def test_manager_edit_role_slug(superuser_or_admin, app, simple_role):
|
|
assert Role.objects.get(name='simple role').slug == 'simple-role'
|
|
resp = login(app, superuser_or_admin,
|
|
reverse('a2-manager-role-edit', kwargs={'pk': simple_role.pk}))
|
|
form = resp.form
|
|
assert 'slug' in form.fields
|
|
form.set('slug', 'new-simple-role-slug')
|
|
form.submit().follow()
|
|
assert Role.objects.get(name='simple role').slug == 'new-simple-role-slug'
|
|
|
|
|
|
def test_manager_user_password_reset(app, superuser, simple_user):
|
|
resp = login(app, superuser,
|
|
reverse('a2-manager-user-detail', kwargs={'pk': simple_user.pk}))
|
|
assert len(mail.outbox) == 0
|
|
resp = resp.forms['object-actions'].submit('password_reset')
|
|
assert 'A mail was sent to' in resp
|
|
assert len(mail.outbox) == 1
|
|
url = get_link_from_mail(mail.outbox[0])
|
|
relative_url = url.split('testserver')[1]
|
|
resp = app.get('/logout/').maybe_follow()
|
|
resp = app.get(relative_url, status=200)
|
|
resp.form.set('new_password1', '1234==aA')
|
|
resp.form.set('new_password2', '1234==aA')
|
|
resp = resp.form.submit().follow()
|
|
assert str(app.session['_auth_user_id']) == str(simple_user.pk)
|
|
|
|
|
|
def test_manager_user_detail_by_uuid(app, superuser, simple_user, simple_role):
|
|
simple_user.roles.add(simple_role)
|
|
url = reverse('a2-manager-user-by-uuid-detail', kwargs={'slug': simple_user.uuid})
|
|
resp = login(app, superuser, url)
|
|
assert '<h3>Actions</h3>' in resp.text
|
|
assert simple_user.first_name.encode('utf-8') in resp.content
|
|
assert 'simple role' in resp.html.find('div', {'class': 'user-roles'}).ul.li.text
|
|
|
|
# if user has roles on multiple, roles are grouped by OU
|
|
simple_user.roles.add(Role.objects.create(name='global role', slug='global-role', ou=None))
|
|
resp = app.get(url)
|
|
html_roles = resp.html.find('div', {'class': 'user-roles'})
|
|
assert 'Default organizational unit' in html_roles.ul.find_all('li', recursive=False)[0].next
|
|
assert 'simple role' in html_roles.ul.find_all('li', recursive=False)[0].ul.li.text
|
|
assert 'All organizational units' in html_roles.ul.find_all('li', recursive=False)[1].next
|
|
assert 'global role' in html_roles.ul.find_all('li', recursive=False)[1].ul.li.text
|
|
|
|
|
|
def test_manager_user_edit_by_uuid(app, superuser, simple_user):
|
|
url = reverse('a2-manager-user-by-uuid-edit', kwargs={'slug': simple_user.uuid})
|
|
resp = login(app, superuser, url)
|
|
assert '<h3>Actions</h3>' not in resp.text
|
|
assert simple_user.first_name.encode('utf-8') in resp.content
|
|
|
|
|
|
@pytest.mark.slow
|
|
def test_manager_stress_create_user(superuser_or_admin, app, mailoutbox):
|
|
new_ou = OU.objects.create(name='new ou', slug='new-ou')
|
|
url = reverse('a2-manager-user-add', kwargs={'ou_pk': new_ou.pk})
|
|
# create first user with john.doe@gmail.com ou OU1 : OK
|
|
|
|
assert len(mailoutbox) == 0
|
|
assert User.objects.filter(ou_id=new_ou.id).count() == 0
|
|
for i in range(100):
|
|
ou_add = login(app, superuser_or_admin, url)
|
|
form = ou_add.form
|
|
form.set('first_name', 'John')
|
|
form.set('last_name', 'Doe')
|
|
form.set('email', 'john.doe@gmail.com')
|
|
form.set('password1', 'ABcd1234')
|
|
form.set('password2', 'ABcd1234')
|
|
form.set('send_mail', True)
|
|
form.submit().follow()
|
|
app.get('/logout/').form.submit()
|
|
assert User.objects.filter(ou_id=new_ou.id).count() == 100
|
|
assert len(mailoutbox) == 100
|
|
|
|
|
|
def test_role_members_from_ou(app, superuser, simple_user, settings):
|
|
assert superuser.ou is None and simple_user.ou == get_default_ou()
|
|
r = Role.objects.create(name='role', slug='role', ou=get_default_ou())
|
|
url = reverse('a2-manager-role-members', kwargs={'pk': r.pk})
|
|
|
|
response = login(app, superuser, url)
|
|
assert not response.context['form'].fields['user'].queryset.query.where
|
|
select2_json = request_select2(app, response)
|
|
assert len(select2_json['results']) == 2
|
|
|
|
settings.A2_MANAGER_ROLE_MEMBERS_FROM_OU = True
|
|
response = app.get(url)
|
|
assert response.context['form'].fields['user'].queryset.query.where
|
|
select2_json = request_select2(app, response)
|
|
assert len(select2_json['results']) == 1
|
|
assert select2_json['results'][0]['id'] == simple_user.pk
|
|
|
|
|
|
def test_manager_create_user(superuser_or_admin, app, settings):
|
|
ou1 = OU.objects.create(name='OU1', slug='ou1')
|
|
ou2 = OU.objects.create(name='OU2', slug='ou2', email_is_unique=True)
|
|
|
|
assert User.objects.filter(ou=ou1).count() == 0
|
|
assert User.objects.filter(ou=ou2).count() == 0
|
|
|
|
# create first user with john.doe@gmail.com ou OU1 : OK
|
|
url = reverse('a2-manager-user-add', kwargs={'ou_pk': ou1.pk})
|
|
ou_add = login(app, superuser_or_admin, url)
|
|
form = ou_add.form
|
|
form.set('first_name', 'John')
|
|
form.set('last_name', 'Doe')
|
|
form.set('email', 'john.doe@gmail.com')
|
|
form.set('password1', 'ABcd1234')
|
|
form.set('password2', 'ABcd1234')
|
|
response = form.submit().follow()
|
|
assert User.objects.filter(ou=ou1).count() == 1
|
|
|
|
# create second user with john.doe@gmail.com ou OU1 : OK
|
|
ou_add = app.get(url)
|
|
form = ou_add.form
|
|
form.set('first_name', 'John')
|
|
form.set('last_name', 'Doe')
|
|
form.set('email', 'john.doe@gmail.com')
|
|
form.set('password1', 'ABcd1234')
|
|
form.set('password2', 'ABcd1234')
|
|
response = form.submit().follow()
|
|
assert User.objects.filter(ou=ou1).count() == 2
|
|
|
|
# create first user with john.doe@gmail.com ou OU2 : OK
|
|
url = reverse('a2-manager-user-add', kwargs={'ou_pk': ou2.pk})
|
|
ou_add = app.get(url)
|
|
form = ou_add.form
|
|
form.set('first_name', 'John')
|
|
form.set('last_name', 'Doe')
|
|
form.set('email', 'john.doe@gmail.com')
|
|
form.set('password1', 'ABcd1234')
|
|
form.set('password2', 'ABcd1234')
|
|
response = form.submit().follow()
|
|
assert User.objects.filter(ou=ou2).count() == 1
|
|
|
|
# create second user with john.doe@gmail.com ou OU2 : NOK
|
|
ou_add = app.get(url)
|
|
form = ou_add.form
|
|
form.set('first_name', 'John')
|
|
form.set('last_name', 'Doe')
|
|
form.set('email', 'john.doe@gmail.com')
|
|
form.set('password1', 'ABcd1234')
|
|
form.set('password2', 'ABcd1234')
|
|
response = form.submit()
|
|
assert User.objects.filter(ou=ou2).count() == 1
|
|
assert 'This email address is already in use.' in response
|
|
|
|
# first user with john.doe@gmail.com/ou2 marked as deleted
|
|
john = User.objects.get(email='john.doe@gmail.com', ou=ou2)
|
|
john.mark_as_deleted()
|
|
john.save()
|
|
ou_add = app.get(url)
|
|
form = ou_add.form
|
|
form.set('first_name', 'John')
|
|
form.set('last_name', 'Doe')
|
|
form.set('email', 'john.doe@gmail.com')
|
|
form.set('password1', 'ABcd1234')
|
|
form.set('password2', 'ABcd1234')
|
|
response = form.submit()
|
|
assert User.objects.filter(ou=ou2).count() == 2
|
|
assert User.objects.filter(ou=ou2, deleted__isnull=True).count() == 1
|
|
|
|
# create first user with john.doe2@gmail.com ou OU2 : OK
|
|
ou_add = app.get(url)
|
|
form = ou_add.form
|
|
form.set('first_name', 'Jane')
|
|
form.set('last_name', 'Doe')
|
|
form.set('email', 'john.doe2@gmail.com')
|
|
form.set('password1', 'ABcd1234')
|
|
form.set('password2', 'ABcd1234')
|
|
response = form.submit().follow()
|
|
assert User.objects.filter(ou=ou2, deleted__isnull=True).count() == 2
|
|
|
|
# try to change user email from john.doe2@gmail.com to
|
|
# john.doe@gmail.com in OU2 : NOK
|
|
response.forms['id_user_edit_form'].set('email', 'john.doe@gmail.com')
|
|
response = form.submit()
|
|
assert 'This email address is already in use.' in response
|
|
|
|
# create first user with email john.doe@gmail.com in OU1: NOK
|
|
settings.A2_EMAIL_IS_UNIQUE = True
|
|
url = reverse('a2-manager-user-add', kwargs={'ou_pk': ou1.pk})
|
|
User.objects.filter(ou=ou1).delete()
|
|
assert User.objects.filter(ou=ou1).count() == 0
|
|
ou_add = app.get(url)
|
|
form = ou_add.form
|
|
form.set('first_name', 'John')
|
|
form.set('last_name', 'Doe')
|
|
form.set('email', 'john.doe@gmail.com')
|
|
form.set('password1', 'ABcd1234')
|
|
form.set('password2', 'ABcd1234')
|
|
response = form.submit()
|
|
assert User.objects.filter(ou=ou1).count() == 0
|
|
assert 'This email address is already in use.' in response
|
|
|
|
form = response.form
|
|
form.set('email', 'john.doe3@gmail.com')
|
|
form.set('password1', 'ABcd1234')
|
|
form.set('password2', 'ABcd1234')
|
|
response = form.submit().follow()
|
|
assert User.objects.filter(ou=ou1).count() == 1
|
|
|
|
# try to change user email from john.doe3@gmail.com to
|
|
# john.doe@gmail.com in OU2 : NOK
|
|
response.forms['id_user_edit_form'].set('email', 'john.doe@gmail.com')
|
|
response = form.submit()
|
|
assert 'This email address is already in use.' in response
|
|
|
|
# check redirect to default ou
|
|
url1 = reverse('a2-manager-user-add-default-ou')
|
|
url2 = reverse('a2-manager-user-add', kwargs={'ou_pk': get_default_ou().pk})
|
|
resp = app.get(url1)
|
|
assert urlparse(resp['Location']).path == url2
|
|
|
|
|
|
def test_manager_create_user_email_validation(superuser_or_admin, app, settings, monkeypatch):
|
|
settings.A2_VALIDATE_EMAIL_DOMAIN = True
|
|
monkeypatch.setattr(EmailValidator, 'query_mxs', lambda x, y: [])
|
|
ou1 = OU.objects.create(name='OU1', slug='ou1')
|
|
|
|
url = reverse('a2-manager-user-add', kwargs={'ou_pk': ou1.pk})
|
|
resp = login(app, superuser_or_admin, url)
|
|
resp.form.set('first_name', 'John')
|
|
resp.form.set('last_name', 'Doe')
|
|
resp.form.set('email', 'john.doe@entrouvert.com')
|
|
resp.form.set('password1', 'ABcd1234')
|
|
resp.form.set('password2', 'ABcd1234')
|
|
resp = resp.form.submit()
|
|
assert 'domain is invalid' in resp.text
|
|
|
|
monkeypatch.setattr(EmailValidator, 'query_mxs', lambda x, y: ['mx1.entrouvert.org'])
|
|
resp.form.submit()
|
|
assert User.objects.filter(email='john.doe@entrouvert.com').count() == 1
|
|
|
|
|
|
def test_app_setting_login_url(app, settings):
|
|
settings.A2_MANAGER_LOGIN_URL = '/other_login/'
|
|
response = app.get('/manage/')
|
|
assert urlparse(response['Location']).path == settings.A2_MANAGER_LOGIN_URL
|
|
assert urlparse(response['Location']).query == 'next=/manage/'
|
|
|
|
|
|
def test_manager_one_ou(app, superuser, admin, simple_role, settings):
|
|
def test_user_listing(user):
|
|
response = login(app, user, '/manage/')
|
|
|
|
# test user listing ou search
|
|
response = response.click(href='users')
|
|
assert 'search-ou' not in response.form.fields
|
|
assert len(response.form.fields['search-text']) == 1
|
|
# verify table shown
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 2
|
|
assert set([e.text for e in q('table tbody td.username')]) == {'admin', 'superuser'}
|
|
|
|
# test user's role page
|
|
response = app.get('/manage/users/%d/roles/' % admin.pk)
|
|
form = response.forms['search-form']
|
|
assert 'search-ou' not in form.fields
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 1
|
|
assert q('table tbody tr').text() == u'simple role'
|
|
assert q('table tbody tr').attr('data-url') == '/manage/roles/%s/' % simple_role.pk
|
|
|
|
form.set('search-internals', True)
|
|
response = form.submit()
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 6
|
|
# admin enroled only in the Manager role, other roles are inherited
|
|
assert len(q('table tbody tr td.via')) == 6
|
|
assert len(q('table tbody tr td.via:empty')) == 2
|
|
for elt in q('table tbody td.name a'):
|
|
assert 'Manager' in elt.text or elt.text == 'simple role'
|
|
|
|
# test role listing
|
|
response = app.get('/manage/roles/')
|
|
assert [x.text for x in response.pyquery('td.slug')] == ['simple-role']
|
|
assert 'search-ou' not in response.form.fields
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 1
|
|
assert q('table tbody td.name').text() == u'simple role'
|
|
|
|
response.form.set('search-internals', True)
|
|
response = response.form.submit()
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 6
|
|
for elt in q('table tbody td.name a'):
|
|
assert 'Manager' in elt.text or elt.text == u'simple role'
|
|
|
|
test_user_listing(admin)
|
|
app.session.flush()
|
|
test_user_listing(superuser)
|
|
|
|
|
|
def test_manager_many_ou(app, superuser, admin, simple_role, role_ou1, admin_ou1, settings, ou1):
|
|
def test_user_listing_admin(user):
|
|
response = login(app, user, '/manage/')
|
|
|
|
# test user listing ou search
|
|
response = response.click(href='users')
|
|
assert len(response.form.fields['search-ou']) == 1
|
|
assert len(response.form.fields['search-text']) == 1
|
|
field = response.form['search-ou']
|
|
options = field.options
|
|
assert len(options) == 4
|
|
for key, checked, label in options:
|
|
assert not checked or key == 'all'
|
|
assert 'all' in [o[0] for o in options]
|
|
assert 'none' in [o[0] for o in options]
|
|
# verify table shown
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 3
|
|
assert set([e.text for e in q('table tbody td.username')]) == {'admin', 'superuser',
|
|
'admin.ou1'}
|
|
|
|
# test user's role page
|
|
response = app.get('/manage/users/%d/roles/' % admin.pk)
|
|
assert len(response.form.fields['search-ou']) == 1
|
|
field = response.form['search-ou']
|
|
options = field.options
|
|
assert len(options) == 4
|
|
for key, checked, label in options:
|
|
assert not checked or key == str(get_default_ou().pk)
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 1
|
|
assert q('table tbody tr').text() == u'simple role'
|
|
|
|
response.form.set('search-ou', 'all')
|
|
response = response.form.submit()
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 1
|
|
assert q('table tbody tr').text() == 'None'
|
|
|
|
form = response.forms['search-form']
|
|
form.set('search-internals', True)
|
|
response = form.submit()
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 5
|
|
# admin enroled only in the Manager role, other roles are inherited
|
|
assert len(q('table tbody tr td.via')) == 5
|
|
assert len(q('table tbody tr td.via:empty')) == 1
|
|
for elt in q('table tbody td.name a'):
|
|
assert 'Manager' in elt.text
|
|
|
|
form = response.forms['search-form']
|
|
form.set('search-ou', 'none')
|
|
form.set('search-internals', True)
|
|
response = form.submit()
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 7
|
|
for elt in q('table tbody td.name a'):
|
|
assert 'Manager' in elt.text
|
|
|
|
# test role listing
|
|
response = app.get('/manage/roles/')
|
|
assert len(response.form.fields['search-ou']) == 1
|
|
field = response.form['search-ou']
|
|
options = field.options
|
|
assert len(options) == 4
|
|
for key, checked, label in options:
|
|
if key == 'all':
|
|
assert checked
|
|
else:
|
|
assert not checked
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 2
|
|
names = [elt.text for elt in q('table tbody td.name a')]
|
|
assert set(names) == {u'simple role', u'role_ou1'}
|
|
|
|
response.form.set('search-ou', 'all')
|
|
response.form.set('search-internals', True)
|
|
response = response.form.submit()
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 15
|
|
for elt in q('table tbody td.name a'):
|
|
assert ('OU1' in elt.text or 'Default' in elt.text or 'Manager' in elt.text
|
|
or elt.text == u'simple role' or elt.text == u'role_ou1')
|
|
|
|
response.form.set('search-ou', 'none')
|
|
response.form.set('search-internals', True)
|
|
response = response.form.submit()
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 7
|
|
for elt in q('table tbody td.name a'):
|
|
assert 'Manager' in elt.text
|
|
|
|
test_user_listing_admin(admin)
|
|
app.session.flush()
|
|
|
|
test_user_listing_admin(superuser)
|
|
app.session.flush()
|
|
|
|
def test_user_listing_ou_admin(user):
|
|
response = login(app, user, '/manage/')
|
|
|
|
# test user listing ou search
|
|
response = response.click(href='users')
|
|
assert len(response.form.fields['search-ou']) == 1
|
|
assert len(response.form.fields['search-text']) == 1
|
|
field = response.form['search-ou']
|
|
options = field.options
|
|
assert len(options) == 1
|
|
# ou1 is selected
|
|
key, checked, label = options[0]
|
|
assert checked
|
|
assert key == str(ou1.pk)
|
|
# verify table shown
|
|
q = response.pyquery.remove_namespaces()
|
|
# only admin.ou1 is visible
|
|
assert len(q('table tbody tr')) == 1
|
|
assert set([e.text for e in q('table tbody td.username')]) == {'admin.ou1'}
|
|
|
|
# test user's role page
|
|
response = app.get('/manage/users/%d/roles/' % admin.pk)
|
|
assert len(response.form.fields['search-ou']) == 1
|
|
field = response.form['search-ou']
|
|
options = field.options
|
|
assert len(options) == 1
|
|
key, checked, label = options[0]
|
|
assert checked
|
|
assert key == str(ou1.pk)
|
|
q = response.pyquery.remove_namespaces()
|
|
# only role_ou1 is visible
|
|
assert len(q('table tbody tr')) == 1
|
|
assert q('table tbody tr').text() == role_ou1.name
|
|
|
|
response.form.set('search-internals', True)
|
|
response = response.form.submit()
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 4
|
|
names = {elt.text for elt in q('table tbody td.name a')}
|
|
assert names == {'Roles - OU1', 'Users - OU1', 'Services - OU1', 'role_ou1'}
|
|
|
|
# test role listing
|
|
response = app.get('/manage/roles/')
|
|
assert len(response.form.fields['search-ou']) == 1
|
|
field = response.form['search-ou']
|
|
options = field.options
|
|
assert len(options) == 1
|
|
key, checked, label = options[0]
|
|
assert checked
|
|
assert key == str(ou1.pk)
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 1
|
|
names = [elt.text for elt in q('table tbody td.name a')]
|
|
assert set(names) == {u'role_ou1'}
|
|
|
|
response.form.set('search-internals', True)
|
|
response = response.form.submit()
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 4
|
|
names = {elt.text for elt in q('table tbody td.name a')}
|
|
assert names == {'Roles - OU1', 'Users - OU1', 'Services - OU1', 'role_ou1'}
|
|
|
|
test_user_listing_ou_admin(admin_ou1)
|
|
|
|
|
|
def test_manager_many_ou_auto_admin_role(app, ou1, admin, user_with_auto_admin_role, auto_admin_role):
|
|
def test_user_listing_auto_admin_role(user):
|
|
response = login(app, user, '/manage/')
|
|
|
|
# users are not visible
|
|
with pytest.raises(IndexError):
|
|
response = response.click(href='users')
|
|
|
|
# test user's role page
|
|
response = app.get('/manage/users/%d/roles/' % admin.pk)
|
|
assert len(response.form.fields['search-ou']) == 1
|
|
field = response.form['search-ou']
|
|
options = field.options
|
|
assert len(options) == 1
|
|
key, checked, label = options[0]
|
|
assert checked
|
|
assert key == str(ou1.pk)
|
|
q = response.pyquery.remove_namespaces()
|
|
# only role_ou1 is visible
|
|
assert len(q('table tbody tr')) == 1
|
|
assert q('table tbody tr').text() == auto_admin_role.name
|
|
|
|
response.form.set('search-internals', True)
|
|
response = response.form.submit()
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 1
|
|
names = {elt.text for elt in q('table tbody td.name a')}
|
|
assert names == {'Auto Admin Role'}
|
|
|
|
# test role listing
|
|
response = app.get('/manage/roles/')
|
|
assert len(response.form.fields['search-ou']) == 1
|
|
field = response.form['search-ou']
|
|
options = field.options
|
|
assert len(options) == 1
|
|
key, checked, label = options[0]
|
|
assert checked
|
|
assert key == str(ou1.pk)
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 1
|
|
names = [elt.text for elt in q('table tbody td.name a')]
|
|
assert set(names) == {u'Auto Admin Role'}
|
|
|
|
response.form.set('search-internals', True)
|
|
response = response.form.submit()
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 1
|
|
names = {elt.text for elt in q('table tbody td.name a')}
|
|
assert set(names) == {u'Auto Admin Role'}
|
|
|
|
test_user_listing_auto_admin_role(user_with_auto_admin_role)
|
|
|
|
|
|
def test_manager_search_user(app, admin, simple_role, settings):
|
|
default_ou = OU.objects.get()
|
|
User.objects.create(username='user1', ou=default_ou)
|
|
response = login(app, admin, '/manage/users/')
|
|
|
|
# search without anything specified returns every user
|
|
form = response.forms['search-form']
|
|
response = form.submit()
|
|
query = response.pyquery.remove_namespaces()
|
|
assert len(query('table tbody td.username')) == 2
|
|
names = {elt.text for elt in query('table tbody td.username')}
|
|
assert names == {'admin', 'user1'}
|
|
|
|
# search a non matching string returns nothing
|
|
response = app.get('/manage/users/')
|
|
form = response.forms['search-form']
|
|
form.set('search-text', 'unkown')
|
|
response = form.submit()
|
|
query = response.pyquery.remove_namespaces()
|
|
assert len(query('table tbody td.username')) == 0
|
|
|
|
# search a string matching exactly a username returns this user
|
|
response = app.get('/manage/users/')
|
|
form = response.forms['search-form']
|
|
form.set('search-text', 'user1')
|
|
response = form.submit()
|
|
query = response.pyquery.remove_namespaces()
|
|
assert len(query('table tbody td.username')) == 1
|
|
assert query('table tbody td.username')[0].text == 'user1'
|
|
|
|
# search a string matching partially a username returns this user
|
|
response = app.get('/manage/users/')
|
|
form = response.forms['search-form']
|
|
form.set('search-text', 'user')
|
|
response = form.submit()
|
|
query = response.pyquery.remove_namespaces()
|
|
assert len(query('table tbody td.username')) == 1
|
|
assert query('table tbody td.username')[0].text == 'user1'
|
|
|
|
|
|
def test_manager_site_export(app, superuser):
|
|
response = login(app, superuser, '/manage/site-export/')
|
|
assert 'roles' in response.json
|
|
assert 'ous' in response.json
|
|
|
|
|
|
def test_manager_site_export_forbidden(app, simple_user):
|
|
login(app, simple_user)
|
|
app.get('/manage/site-export/', status=403)
|
|
|
|
|
|
def test_manager_site_import(app, db, superuser):
|
|
site_import = login(app, superuser, '/manage/site-import/')
|
|
form = site_import.form
|
|
site_export = {
|
|
'roles': [
|
|
{
|
|
"description": "", "service": None, "name": "basic",
|
|
"attributes": [],
|
|
"ou": {
|
|
"slug": "default",
|
|
"uuid": "ba60d9e6c2874636883bdd604b23eab2",
|
|
"name": "Collectivit\u00e9 par d\u00e9faut"
|
|
},
|
|
"external_id": "",
|
|
"slug": "basic",
|
|
"uuid": "6eb7bbf64bf547119120f925f0e560ac"
|
|
}]
|
|
}
|
|
form['site_json'] = Upload(
|
|
'site_export.json', force_bytes(json.dumps(site_export).encode('ascii')), 'application/octet-stream')
|
|
res = form.submit()
|
|
assert res.status_code == 302
|
|
assert Role.objects.get(slug='basic')
|
|
|
|
|
|
def test_manager_site_import_error(app, db, superuser):
|
|
site_import = login(app, superuser, '/manage/site-import/')
|
|
form = site_import.form
|
|
site_export = {
|
|
'roles': [
|
|
{
|
|
"description": "", "service": None, "name": "basic",
|
|
"attributes": [],
|
|
"ou": {
|
|
"slug": "unkown-ou",
|
|
"uuid": "ba60d9e6c2874636883bdd604b23eab2",
|
|
"name": "unkown ou"
|
|
},
|
|
"external_id": "",
|
|
"slug": "basic",
|
|
"uuid": "6eb7bbf64bf547119120f925f0e560ac"
|
|
}]
|
|
}
|
|
form['site_json'] = Upload(
|
|
'site_export.json', force_bytes(json.dumps(site_export).encode('ascii')), 'application/octet-stream')
|
|
res = form.submit()
|
|
assert res.status_code == 200
|
|
assert 'missing Organizational Unit' in res.text
|
|
with pytest.raises(Role.DoesNotExist):
|
|
Role.objects.get(slug='basic')
|
|
|
|
form['site_json'] = Upload(
|
|
'site_export.json', force_bytes(json.dumps([])), 'application/octet-stream')
|
|
res = form.submit()
|
|
assert res.status_code == 200
|
|
|
|
|
|
def test_manager_site_import_forbidden(app, simple_user):
|
|
login(app, simple_user)
|
|
app.get('/manage/site-import/', status=403)
|
|
|
|
|
|
def test_manager_homepage_import_export(superuser, app):
|
|
manager_home_page = login(app, superuser, reverse('a2-manager-homepage'))
|
|
assert 'site-import' in manager_home_page.text
|
|
assert 'site-export' in manager_home_page.text
|
|
|
|
|
|
def test_manager_homepage_import_export_hidden(admin, app):
|
|
manager_home_page = login(app, admin, reverse('a2-manager-homepage'))
|
|
assert 'site-import' not in manager_home_page.text
|
|
assert 'site-export' not in manager_home_page.text
|
|
|
|
|
|
def test_manager_ou(app, superuser_or_admin, ou1):
|
|
manager_home_page = login(app, superuser_or_admin, reverse('a2-manager-homepage'))
|
|
ou_homepage = manager_home_page.click(href='organizational-units')
|
|
assert set([e.text for e in ou_homepage.pyquery('td.name')]) == set(['OU1', 'Default organizational unit'])
|
|
assert [x.text for x in ou_homepage.pyquery('td.slug')] == ['default', 'ou1']
|
|
|
|
# add a new ou
|
|
add_ou_page = ou_homepage.click('Add')
|
|
add_ou_page.form.set('name', 'ou2')
|
|
add_ou_page.form.set('default', True)
|
|
ou_homepage = add_ou_page.form.submit().follow()
|
|
ou2 = OU.objects.get(name='ou2')
|
|
assert set([e.text for e in ou_homepage.pyquery('td.name')]) == set(['OU1', 'Default organizational unit', 'ou2'])
|
|
assert len(ou_homepage.pyquery('tr[data-pk="%s"] td.default span.true' % ou2.pk)) == 1
|
|
assert len(ou_homepage.pyquery('tr[data-url="%s/"] td.default span.true' % ou2.pk)) == 1
|
|
|
|
# FIXME: table lines are not clickable as they do not contain an anchor
|
|
# default ou cannot be deleted
|
|
ou2_detail_page = app.get(reverse('a2-manager-ou-detail', kwargs={'pk': ou2.pk}))
|
|
assert ou2_detail_page.pyquery('a.disabled').text() == 'Delete'
|
|
|
|
# but ou1 can be deleted
|
|
ou1_detail_page = app.get(reverse('a2-manager-ou-detail', kwargs={'pk': ou1.pk}))
|
|
ou1_delete_page = ou1_detail_page.click('Delete')
|
|
ou_homepage = ou1_delete_page.form.submit().follow()
|
|
assert set([e.text for e in ou_homepage.pyquery('td.name')]) == set(['Default organizational unit', 'ou2'])
|
|
|
|
# remake old default ou the default one
|
|
old_default = OU.objects.get(name__contains='Default')
|
|
old_default_detail_page = app.get(reverse('a2-manager-ou-detail', kwargs={'pk': old_default.pk}))
|
|
assert not old_default_detail_page.pyquery('input[name="default"][checked="checked"]')
|
|
old_default_edit_page = old_default_detail_page.click('Edit')
|
|
old_default_edit_page.form.set('default', True)
|
|
old_default_detail_page = old_default_edit_page.form.submit().follow()
|
|
# check detail page has changed
|
|
assert old_default_detail_page.pyquery('input[name="default"][checked="checked"]')
|
|
# check ou homepage has changed too
|
|
ou_homepage = old_default_detail_page.click('Organizational unit')
|
|
assert set([e.text for e in ou_homepage.pyquery('td.name')]) == set(['Default organizational unit', 'ou2'])
|
|
assert len(ou_homepage.pyquery('span.true')) == 1
|
|
assert len(ou_homepage.pyquery('tr[data-pk="%s"] td.default span.true' % ou2.pk)) == 0
|
|
assert len(ou_homepage.pyquery('tr[data-pk="%s"] td.default span.true' % old_default.pk)) == 1
|
|
|
|
# edit ou slug
|
|
assert OU.objects.get(name='ou2').slug == 'ou2'
|
|
ou2_detail_page = app.get(reverse('a2-manager-ou-edit', kwargs={'pk': ou2.pk}))
|
|
form = ou2_detail_page.form
|
|
assert 'slug' in form.fields
|
|
form.set('slug', 'new-ou2-slug')
|
|
form.submit().follow()
|
|
assert OU.objects.get(name='ou2').slug == 'new-ou2-slug'
|
|
|
|
|
|
def test_return_on_logout(superuser, app):
|
|
'''Verify we will return to /manage/ after logout/login cycle'''
|
|
manager_home_page = login(app, superuser, reverse('a2-manager-homepage'))
|
|
response = manager_home_page.click(href='logout').maybe_follow()
|
|
assert response.request.query_string == 'next=/manage/'
|
|
|
|
|
|
def test_roles_widget(admin, app, db):
|
|
from authentic2.manager.forms import ChooseRoleForm
|
|
|
|
login(app, admin, '/manage/')
|
|
cassis = OU.objects.create(name=u'Cassis')
|
|
la_bedoule = OU.objects.create(name=u'La Bédoule')
|
|
cuges = OU.objects.create(name=u'Cuges')
|
|
Role.objects.create(ou=cassis, name=u'Administrateur')
|
|
Role.objects.create(ou=la_bedoule, name=u'Administrateur')
|
|
Role.objects.create(ou=cuges, name=u'Administrateur')
|
|
|
|
form = ChooseRoleForm(request=None)
|
|
assert form.as_p()
|
|
field_id = form.fields['role'].widget.build_attrs({})['data-field_id']
|
|
url = reverse('django_select2-json')
|
|
response = app.get(url, params={'field_id': field_id, 'term': 'Admin'})
|
|
assert len(response.json['results']) == 3
|
|
response = app.get(url, params={'field_id': field_id, 'term': 'Admin cass'})
|
|
assert len(response.json['results']) == 1
|
|
assert response.json['results'][0]['text'] == u'Cassis - Administrateur'
|
|
response = app.get(url, params={'field_id': field_id, 'term': force_str('Admin édou')})
|
|
assert len(response.json['results']) == 1
|
|
assert response.json['results'][0]['text'] == u'La Bédoule - Administrateur'
|
|
|
|
|
|
def test_roles_for_change_widget(admin, app, db):
|
|
from authentic2.manager.forms import RoleParentsForm
|
|
|
|
login(app, admin, '/manage/')
|
|
Role.objects.create(name=u'admin 1')
|
|
Role.objects.create(name=u'user 1')
|
|
|
|
form = RoleParentsForm(request=None)
|
|
assert form.as_p()
|
|
field_id = form.fields['roles'].widget.build_attrs({})['data-field_id']
|
|
url = reverse('django_select2-json')
|
|
response = app.get(url, params={'field_id': field_id, 'term': 'admin'})
|
|
assert len(response.json['results']) == 1
|
|
response = app.get(url, params={'field_id': field_id, 'term': '1'})
|
|
assert len(response.json['results']) == 2
|
|
response = app.get(url, params={'field_id': field_id, 'term': 'user 1'})
|
|
assert len(response.json['results']) == 1
|
|
|
|
|
|
def test_manager_ajax_form_view_mixin_response(superuser_or_admin, app):
|
|
app.set_user(superuser_or_admin.username)
|
|
resp = app.get('/manage/roles/add/', xhr=True, status=200)
|
|
assert resp.content_type == 'application/json'
|
|
assert resp.json['content']
|
|
|
|
|
|
def test_manager_role_username_column(app, admin, simple_role):
|
|
login(app, admin, '/manage/')
|
|
|
|
resp = app.get('/manage/roles/%s/' % simple_role.id)
|
|
assert resp.html.find('th', {'class': 'orderable username'})
|
|
|
|
ou = get_default_ou()
|
|
ou.show_username = False
|
|
ou.save()
|
|
|
|
resp = app.get('/manage/roles/%s/' % simple_role.id)
|
|
assert not resp.html.find('th', {'class': 'asc orderable username'})
|
|
|
|
|
|
def test_manager_role_admin_permissions(app, simple_user, admin, simple_role):
|
|
admin_role = simple_role.get_admin_role()
|
|
simple_user.roles.add(admin_role)
|
|
login(app, simple_user, '/manage/')
|
|
|
|
# user can view users
|
|
response = app.get('/manage/users/')
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 2
|
|
assert set([e.text for e in q('table tbody td.username')]) == {'admin', 'user'}
|
|
|
|
# user can view administered roles
|
|
response = app.get('/manage/roles/')
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 1
|
|
assert q('table tbody td.name').text() == 'simple role'
|
|
|
|
# user can add members
|
|
response = app.get('/manage/roles/%s/' % simple_role.pk)
|
|
form = response.forms['add-user']
|
|
form['user'].force_value(admin.pk)
|
|
response = form.submit().follow()
|
|
assert simple_role in admin.roles.all()
|
|
|
|
# user can delete members
|
|
q = response.pyquery.remove_namespaces()
|
|
assert q('table tbody tr td .icon-remove-sign')
|
|
token = str(response.context['csrf_token'])
|
|
params = {'action': 'remove', 'user': admin.pk, 'csrfmiddlewaretoken': token}
|
|
app.post('/manage/roles/%s/' % simple_role.pk, params=params)
|
|
assert simple_role not in admin.roles.all()
|
|
|
|
# user can act on role inheritance
|
|
role = Role.objects.create(name='test_role')
|
|
view_role_perm = get_permission_model().objects.create(
|
|
operation=get_operation(VIEW_OP),
|
|
target_ct=ContentType.objects.get_for_model(Role),
|
|
target_id=role.pk)
|
|
simple_role.permissions.add(view_role_perm)
|
|
simple_user.roles.add(simple_role)
|
|
admin.roles.add(role)
|
|
response = app.get('/manage/roles/%s/add-child/' % simple_role.pk)
|
|
form = response.form
|
|
form['roles'].force_value(role.pk)
|
|
form.submit().follow()
|
|
assert role in simple_role.children()
|
|
|
|
url = '/manage/roles/%s/remove-child/%s/' % (simple_role.pk, role.pk)
|
|
token = str(response.context['csrf_token'])
|
|
app.post(url, params={'csrfmiddlewaretoken': token})
|
|
assert not role in simple_role.children()
|
|
|
|
response = app.get('/manage/roles/%s/add-parent/' % role.pk)
|
|
form = response.form
|
|
form['roles'].force_value(simple_role.pk)
|
|
form.submit().follow()
|
|
assert simple_role in role.parents()
|
|
|
|
url = '/manage/roles/%s/remove-parent/%s/' % (role.pk, simple_role.pk)
|
|
token = str(response.context['csrf_token'])
|
|
app.post(url, params={'csrfmiddlewaretoken': token})
|
|
assert simple_role not in role.parents()
|
|
|
|
# user roles view works
|
|
response = app.get('/manage/users/%s/roles/' % admin.pk)
|
|
q = response.pyquery.remove_namespaces()
|
|
assert len(q('table tbody tr')) == 1
|
|
assert q('table tbody td.name').text() == 'simple role'
|
|
|
|
token = str(response.context['csrf_token'])
|
|
params = {'action': 'add', 'role': simple_role.pk, 'csrfmiddlewaretoken': token}
|
|
response = app.post('/manage/users/%s/roles/' % admin.pk, params=params)
|
|
assert simple_role in admin.roles.all()
|
|
|
|
app.get('/manage/roles/add/', status=403)
|
|
app.get('/manage/roles/%s/edit/' % simple_role.pk, status=403)
|
|
app.get('/manage/roles/%s/delete/' % simple_role.pk, status=403)
|
|
|
|
|
|
def test_manager_permission_inheritance(app, simple_user, admin, simple_role):
|
|
admin_role = Role.objects.get(slug='_a2-manager')
|
|
view_role_perm = get_permission_model().objects.create(
|
|
operation=get_operation(VIEW_OP),
|
|
target_ct=ContentType.objects.get_for_model(Role),
|
|
target_id=simple_role.pk)
|
|
simple_role.permissions.add(view_role_perm)
|
|
simple_user.roles.add(simple_role)
|
|
login(app, simple_user, '/manage/')
|
|
|
|
response = app.get('/manage/roles/%s/add-parent/' % simple_role.pk)
|
|
form = response.form
|
|
form['roles'].force_value(admin_role.pk)
|
|
response = form.submit()
|
|
|
|
assert response.status_code == 200
|
|
assert not admin_role in simple_role.parents()
|
|
|
|
|
|
def test_manager_widget_fields_validation(app, simple_user, simple_role):
|
|
'''Verify that fields corresponding to widget implement queryset restrictions.'''
|
|
from authentic2.manager.forms import (ChooseUserForm, ChooseRoleForm,
|
|
UsersForm, RolesForm, ChooseUserRoleForm,
|
|
RoleParentsForm)
|
|
error_message = 'Select a valid choice'
|
|
|
|
class DummyRequest:
|
|
user = simple_user
|
|
request = DummyRequest()
|
|
|
|
visible_role = Role.objects.create(name='visible_role', ou=simple_user.ou)
|
|
visible_user = User.objects.create(username='visible_user', ou=simple_user.ou)
|
|
forbidden_role = Role.objects.create(name='forbidden_role', ou=simple_user.ou)
|
|
forbidden_user = User.objects.create(username='forbidden_user', ou=simple_user.ou)
|
|
|
|
view_role_perm = get_permission_model().objects.create(
|
|
operation=get_operation(VIEW_OP),
|
|
target_ct=ContentType.objects.get_for_model(Role),
|
|
target_id=visible_role.pk)
|
|
view_user_perm = get_permission_model().objects.create(
|
|
operation=get_operation(VIEW_OP),
|
|
target_ct=ContentType.objects.get_for_model(User),
|
|
target_id=visible_user.pk)
|
|
simple_role.permissions.add(view_role_perm)
|
|
simple_role.permissions.add(view_user_perm)
|
|
simple_user.roles.add(simple_role)
|
|
|
|
form = ChooseUserForm(request=request, data={'user': visible_user.pk, 'action': 'add'})
|
|
assert form.is_valid()
|
|
form = ChooseUserForm(request=request, data={'user': forbidden_user.pk, 'action': 'add'})
|
|
assert error_message in form.errors['user'][0]
|
|
|
|
form = ChooseRoleForm(request=request, data={'role': visible_role.pk, 'action': 'add'})
|
|
assert form.is_valid()
|
|
form = ChooseRoleForm(request=request, data={'role': forbidden_role.pk, 'action': 'add'})
|
|
assert error_message in form.errors['role'][0]
|
|
|
|
form = UsersForm(request=request, data={'users': [visible_user.pk]})
|
|
assert form.is_valid()
|
|
form = UsersForm(request=request, data={'users': [forbidden_user.pk]})
|
|
assert error_message in form.errors['users'][0]
|
|
|
|
form = RolesForm(request=request, data={'roles': [visible_role.pk]})
|
|
assert form.is_valid()
|
|
form = RolesForm(request=request, data={'roles': [forbidden_role.pk]})
|
|
assert error_message in form.errors['roles'][0]
|
|
|
|
# For those we need manage_members permission
|
|
form = RoleParentsForm(request=request, data={'roles': [visible_role.pk]})
|
|
assert error_message in form.errors['roles'][0]
|
|
|
|
form = ChooseUserRoleForm(request=request, data={'role': visible_role.pk, 'action': 'add'})
|
|
assert error_message in form.errors['role'][0]
|
|
|
|
change_role_perm = get_permission_model().objects.create(
|
|
operation=get_operation(MANAGE_MEMBERS_OP),
|
|
target_ct=ContentType.objects.get_for_model(Role),
|
|
target_id=visible_role.pk)
|
|
simple_role.permissions.add(change_role_perm)
|
|
del simple_user._rbac_perms_cache
|
|
|
|
form = RoleParentsForm(request=request, data={'roles': [visible_role.pk]})
|
|
assert form.is_valid()
|
|
|
|
form = ChooseUserRoleForm(request=request, data={'role': visible_role.pk, 'action': 'add'})
|
|
assert form.is_valid()
|
|
|
|
|
|
def test_manager_role_widgets_choices(app, simple_user, simple_role):
|
|
|
|
def get_choices(response):
|
|
select2_json = request_select2(app, response)
|
|
assert select2_json['more'] is False
|
|
return set(result['id'] for result in select2_json['results'])
|
|
|
|
visible_role = Role.objects.create(name='visible_role', ou=simple_user.ou)
|
|
Role.objects.create(name='invisible_role', ou=simple_user.ou)
|
|
admin_of_simple_role = simple_role.get_admin_role()
|
|
|
|
admin_of_simple_role.members.add(simple_user)
|
|
view_role_perm = get_permission_model().objects.create(
|
|
operation=get_operation(VIEW_OP),
|
|
target_ct=ContentType.objects.get_for_model(Role),
|
|
target_id=visible_role.pk)
|
|
simple_role.permissions.add(view_role_perm)
|
|
simple_user.roles.add(simple_role)
|
|
|
|
response = login(app, simple_user, '/manage/roles/')
|
|
|
|
# all visible roles are shown
|
|
response = app.get('/manage/roles/%s/add-child/' % simple_role.pk)
|
|
assert set([visible_role.pk, simple_role.pk]) == get_choices(response)
|
|
|
|
# all roles with manage_members permissions are shown
|
|
response = app.get('/manage/roles/%s/add-parent/' % simple_role.pk)
|
|
assert set([simple_role.pk, admin_of_simple_role.pk]) == get_choices(response)
|
|
|
|
response = app.get('/manage/roles/%s/add-parent/' % visible_role.pk)
|
|
assert set([simple_role.pk, admin_of_simple_role.pk]) == get_choices(response)
|
|
|
|
|
|
def test_manager_widgets_field_id_other_user(app, admin, simple_user, simple_role):
|
|
other_role = Role.objects.create(name='visible_role', ou=simple_user.ou)
|
|
simple_role.get_admin_role().members.add(simple_user)
|
|
|
|
response = login(app, admin, '/manage/roles/%s/add-child/' % simple_role.pk)
|
|
select2_json = request_select2(app, response)
|
|
assert select2_json['more'] is False
|
|
|
|
# admin can see every roles
|
|
assert set([simple_role.pk, other_role.pk]) == \
|
|
set(result['id'] for result in select2_json['results'])
|
|
|
|
login(app, simple_user)
|
|
# same request from the page served for admin
|
|
select2_json = request_select2(app, response)
|
|
# simple_user doesn't see all roles
|
|
assert simple_role.pk == select2_json['results'][0]['id']
|
|
|
|
# anymous user receive 404
|
|
app.session.flush()
|
|
select2_json = request_select2(app, response, get_kwargs={'status': 404})
|
|
|
|
|
|
def test_display_parent_roles_on_role_page(app, superuser, settings):
|
|
ou1 = get_default_ou()
|
|
ou1.name = ('ou1')
|
|
ou1.save()
|
|
|
|
child = Role.objects.create(name='child', slug='role', ou=ou1)
|
|
parent1 = Role.objects.create(name='parent1', slug='role1', ou=None)
|
|
parent2 = Role.objects.create(name='parent2', slug='role2', ou=ou1)
|
|
child.add_parent(parent1)
|
|
child.add_parent(parent2)
|
|
child.save()
|
|
|
|
# do not display roles if we have a single OU
|
|
url = reverse('a2-manager-role-members', kwargs={'pk': child.pk})
|
|
login(app, superuser)
|
|
response = app.get(url, status=200)
|
|
parent_roles_html = response.html.find_all('div', {'class': 'role-inheritance'})[3]
|
|
assert 'Parent roles:' in parent_roles_html.text
|
|
assert [x.text.strip() for x in parent_roles_html.find_all('a', {'class': 'role'})] == \
|
|
['parent1', 'parent2']
|
|
|
|
# display parent roles if we have multiple OUs
|
|
ou2 = OU.objects.create(name='ou2')
|
|
response = app.get(url, status=200)
|
|
parent_roles_html = response.html.find_all('div', {'class': 'role-inheritance'})[3]
|
|
assert 'Parent roles:' in parent_roles_html.text
|
|
assert [x.text.strip() for x in parent_roles_html.find_all('a', {'class': 'role'})] == \
|
|
['parent1', 'ou1 - parent2']
|
|
|
|
# display parent roles sorted by OU
|
|
parent3 = Role.objects.create(name='parent3', slug='role3', ou=ou2)
|
|
child.add_parent(parent3)
|
|
parent4 = Role.objects.create(name='parent4', slug='role4', ou=ou1)
|
|
child.add_parent(parent4)
|
|
child.save()
|
|
response = app.get(url, status=200)
|
|
parent_roles_html = response.html.find_all('div', {'class': 'role-inheritance'})[3]
|
|
assert 'Parent roles:' in parent_roles_html.text
|
|
assert [x.text.strip() for x in parent_roles_html.find_all('a', {'class': 'role'})] == \
|
|
['parent1', 'ou1 - parent2', 'ou1 - parent4', 'ou2 - parent3']
|