# 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 . import json from webtest import Upload from django.utils.encoding import force_bytes, force_text from authentic2.custom_user.models import User from authentic2.a2_rbac.models import Role, OrganizationalUnit from authentic2.a2_rbac.utils import get_default_ou from .utils import login, text_content def test_manager_role_export(app, admin, ou1, role_ou1, ou2, role_ou2): import csv response = login(app, admin, 'a2-manager-roles') export_response = response.click('Export') export = export_response.json assert list(export.keys()) == ['roles'] assert len(export['roles']) == 2 assert set([role['slug'] for role in export['roles']]) == set(['role_ou1', 'role_ou2']) export_response = response.click('CSV') reader = csv.reader([force_text(line) for line in export_response.body.split(force_bytes('\r\n'))], delimiter=',') rows = [row for row in reader] assert rows[0] == ['name', 'slug', 'members'] assert len(rows)-2 == 2 # csv header and last EOL assert set([row[1] for row in rows[1:3]]) == set(['role_ou1', 'role_ou2']) response.form.set('search-text', 'role_ou1') search_response = response.form.submit() export_response = search_response.click('Export') export = export_response.json assert list(export.keys()) == ['roles'] assert len(export['roles']) == 1 assert export['roles'][0]['slug'] == 'role_ou1' export_response = search_response.click('CSV') reader = csv.reader([force_text(line) for line in export_response.body.split(force_bytes('\r\n'))], delimiter=',') rows = [row for row in reader] assert rows[0] == ['name', 'slug', 'members'] assert len(rows)-2 == 1 # csv header and last EOL assert rows[1][1] == 'role_ou1' def test_manager_role_name_uniqueness_single_ou(app, admin): response = login(app, admin, 'a2-manager-roles') response = response.click('Add') response.form.set('name', 'Role1') response = response.form.submit('Save').follow() response = response.click('Roles') assert response.pyquery('td.name').text() == 'Role1' response = response.click('Add') response.form.set('name', 'Role1') response = response.form.submit('Save') assert response.pyquery('.error').text() == 'Name already used' def test_manager_role_name_uniqueness_multiple_ou(app, admin, ou1): response = login(app, admin, 'a2-manager-roles') response = response.click('Add') response.form.set('ou', str(ou1.id)) response.form.set('name', 'Role1') response = response.form.submit('Save').follow() response = response.click('Roles') assert response.pyquery('td.name').text() == 'Role1' response = response.click('Add') response.form.set('ou', str(ou1.id)) response.form.set('name', 'Role1') response = response.form.submit('Save') assert response.pyquery('.error').text() == 'Name already used' def test_role_members_via(app, admin): user1 = User.objects.create(username='user1') user2 = User.objects.create(username='user2') role1 = Role.objects.create(name='role1') role2 = Role.objects.create(name='role2') role1.add_child(role2) user1.roles.add(role1) user2.roles.add(role2) response = login(app, admin, '/manage/roles/%s/' % role1.id) rows = list(zip([text_content(el) for el in response.pyquery('tr td.username')], [text_content(el) for el in response.pyquery('tr td.direct')], [text_content(el) for el in response.pyquery('tr td.via')])) assert rows == [ ('user1', '✔', ''), ('user2', '✘', 'role2'), ] def test_manager_role_import(app, admin, ou1, role_ou1, ou2, role_ou2): response = login(app, admin, 'a2-manager-roles') export_response = response.click('Export') export = export_response.json assert len(export['roles']) == 2 assert not 'ous' in export Role.objects.filter(ou__in=[ou1, ou2]).delete() resp = app.get('/manage/roles/') resp = resp.click('Import') resp.form['site_json'] = Upload('export.json', json.dumps(export).encode(), 'application/json') resp = resp.form.submit().follow() assert Role.objects.filter(name=role_ou1.name, ou=get_default_ou()).exists() assert Role.objects.filter(name=role_ou2.name, ou=get_default_ou()).exists() response.form.set('search-text', 'role_ou1') search_response = response.form.submit() export_response = response.click('Export') new_export = export_response.json assert len(export['roles']) == 2 assert new_export['roles'][0]['uuid'] == export['roles'][0]['uuid'] assert new_export['roles'][1]['uuid'] == export['roles'][1]['uuid'] resp = app.get('/manage/roles/') resp = resp.click('Import') resp.form['site_json'] = Upload('export.json', json.dumps(export).encode(), 'application/json') resp.form['ou'] = ou1.pk resp = resp.form.submit().follow() assert Role.objects.filter(name=role_ou1.name, ou=get_default_ou()).exists() assert Role.objects.filter(name=role_ou2.name, ou=get_default_ou()).exists() assert Role.objects.filter(ou=ou1).count() == 4 # in case ous are present in export file, they must not be imported export['ous'] = [{ "uuid": "27255f404cb140df9a577da76b59f285", "slug": "should_not_exist", "name": "should_not_exist", }] resp = app.get('/manage/roles/') # unselect ou1 resp = resp.click('Import') resp.form['site_json'] = Upload('export.json', json.dumps(export).encode(), 'application/json') resp = resp.form.submit().follow() assert not OrganizationalUnit.objects.filter(slug="should_not_exist").exists() def test_manager_role_import_single_ou(app, admin, simple_role): assert OrganizationalUnit.objects.count() == 1 response = login(app, admin, 'a2-manager-roles') export_response = response.click('Export') export = export_response.json assert len(export['roles']) == 1 simple_role.delete() resp = app.get('/manage/roles/') resp = resp.click('Import') assert not 'Organizational unit' in resp.text assert resp.form['ou'].attrs['type'] == 'hidden' resp.form['site_json'] = Upload('export.json', json.dumps(export).encode(), 'application/json') resp = resp.form.submit().follow() imported_role = Role.objects.get(slug=simple_role.slug) assert imported_role.ou == simple_role.ou def test_manager_role_import_selected_ou(app, admin, ou1, ou2): response = login(app, admin, 'a2-manager-roles') response.form.set('search-ou', ou2.pk) response = response.form.submit() response = response.click('Import') assert response.pyquery.find('select#id_ou option[selected]')[0].text == 'OU2' def test_manager_role_add_selected_ou(app, admin, ou1, ou2): response = login(app, admin, 'a2-manager-roles') response.form.set('search-ou', ou2.pk) response = response.form.submit() response = response.click('Add role') assert response.pyquery.find('select#id_ou option[selected]')[0].text == 'OU2'