authentic2-wallonie-connect/tests/test_acl.py

195 lines
8.3 KiB
Python

# coding: utf-8
#
# authentic2-wallonie-connect - Authentic2 plugin for the Wallonie Connect usecase
# Copyright (C) 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
from authentic2.custom_user.models import User
from authentic2.a2_rbac.models import OrganizationalUnit as OU, Role
from authentic2.models import Service
from utils import login
@pytest.fixture(autouse=True)
def base(db):
class Base(object):
pass
b = Base()
OU.objects.filter(default=True).update(name='IMIO', slug='imio')
b.ou_imio = OU.objects.get(slug='imio')
b.role_global_admin = Role.objects.get(slug='_imio-wc-admin')
b.user_admin = User.objects.create(ou=b.ou_imio, username='admin')
b.user_admin.roles.add(b.role_global_admin)
b.ou_liege = OU.objects.create(name='Liège', slug='liege')
b.role_liege_user_admin = Role.objects.get(slug='_imio-wc-user-admin', ou=b.ou_liege)
b.role_liege_role_admin = Role.objects.get(slug='_imio-wc-role-admin', ou=b.ou_liege)
b.service_liege = Service.objects.create(ou=b.ou_liege, slug='service', name='Service')
b.role_service_liege = Role.objects.create(ou=b.ou_liege, slug='service', name='Accès Service')
b.service_liege.authorized_roles.through.objects.create(service=b.service_liege, role=b.role_service_liege)
b.user_liege = User.objects.create(ou=b.ou_liege, username='user-liege')
b.user_liege_admin = User.objects.create(ou=b.ou_liege, username='admin-liege')
b.user_liege_admin.roles.add(b.role_liege_user_admin)
b.user_liege_admin.roles.add(b.role_liege_role_admin)
b.user_liege_service_admin = User.objects.create(ou=b.ou_liege, username='service-admin-liege')
b.user_liege_service_admin.roles.add(b.role_service_liege.get_admin_role())
b.ou_tournay = OU.objects.create(name='Tournay', slug='tournay')
b.role_tournay_user_admin = Role.objects.get(slug='_imio-wc-user-admin', ou=b.ou_tournay)
b.role_tournay_role_admin = Role.objects.get(slug='_imio-wc-role-admin', ou=b.ou_tournay)
b.user_tournay = User.objects.create(ou=b.ou_tournay, username='user-tournay')
# set all passwords
for user in User.objects.all():
user.set_password(user.username)
user.save()
return b
def test_imio_admin(app, base):
home = login(app, base.user_admin, '/manage/')
assert (set(elt.attrib['href'].strip('/').split('/')[1] for elt in home.pyquery('.apps li a'))
== set(['organizational-units',
'roles',
'users',
'services']))
users = home.click('Users')
assert len(users.pyquery('table tbody tr')) == User.objects.count()
# Can add user in IMIO
users_imio = app.get('/manage/users/?search-ou=%s' % base.ou_imio.pk)
assert len(users_imio.pyquery('table tbody tr')) == 1
users_imio.click('Add user')
# Can add user in Liège
users_liege = app.get('/manage/users/?search-ou=%s' % base.ou_liege.pk)
assert len(users_liege.pyquery('table tbody tr')) == 3
users_liege.click('Add user')
# Can edit user in IMIO
user_imio = app.get('/manage/users/%s/' % base.user_admin.pk)
assert (set(elt.text for elt in user_imio.pyquery('.actions a:not(.disabled)'))
== set(['Delete', 'Edit']))
assert (set(elt.text for elt in user_imio.pyquery('.other_actions button'))
== set(['Suspend',
'Reset password',
'Modify roles',
'Change user password',
'Force password change on next login']))
# or Liège
user_liege = app.get('/manage/users/%s/' % base.user_liege_admin.pk)
assert (set(elt.text for elt in user_liege.pyquery('.actions a:not(.disabled)'))
== set(['Delete', 'Edit']))
assert (set(elt.text for elt in user_liege.pyquery('.other_actions button'))
== set(['Suspend',
'Reset password',
'Modify roles',
'Change user password',
'Force password change on next login']))
def test_liege_admin(app, base):
home = login(app, base.user_liege_admin, '/manage/')
assert (set(elt.attrib['href'].strip('/').split('/')[1] for elt in home.pyquery('.apps li a'))
== set(['roles', 'users']))
users = home.click('Users')
assert len(users.pyquery('table tbody tr')) == User.objects.filter(ou=base.ou_liege).count()
# Can add user directly
users.click('Add user')
# Cannot see user in IMIO or Tournay
app.get('/manage/users/%s/' % base.user_admin.pk, status=403)
app.get('/manage/users/%s/' % base.user_tournay.pk, status=403)
# Cane edit but not delete user in Liège
user_liege = app.get('/manage/users/%s/' % base.user_liege_admin.pk)
assert (set(elt.text for elt in user_liege.pyquery('.actions a:not(.disabled)'))
== set(['Edit']))
assert (set(elt.text for elt in user_liege.pyquery('.other_actions button'))
== set(['Suspend',
'Reset password',
'Modify roles',
'Force password change on next login']))
def test_liege_service_admin(app, base):
home = login(app, base.user_liege_service_admin, '/manage/')
assert (set(elt.attrib['href'].strip('/').split('/')[1] for elt in home.pyquery('.apps li a'))
== set(['roles', 'users']))
users = home.click('Users')
assert len(users.pyquery('table tbody tr')) == User.objects.filter(ou=base.ou_liege).count()
# Cannot add user
assert len(users.pyquery('#add-user-btn.disabled')) == 1
# Can see user in Liège
app.get('/manage/users/%s/edit/' % base.user_liege.pk, status=403)
# Cannot see in IMIO or Tournay
app.get('/manage/users/%s/' % base.user_admin.pk, status=403)
app.get('/manage/users/%s/' % base.user_tournay.pk, status=403)
# Cane edit but not delete user in Liège but modify roles
user_liege = app.get('/manage/users/%s/' % base.user_liege.pk)
# Can't do anthing on a user of Liège
assert (set(elt.text for elt in user_liege.pyquery('.actions a:not(.disabled)'))
== set([]))
assert (set(elt.text for elt in user_liege.pyquery('.other_actions button'))
== set(['Modify roles']))
# but modify members of the service role
modify_roles = app.get('/manage/users/%s/roles/' % base.user_liege.pk)
assert len(modify_roles.pyquery('table tbody tr td.name a')) == 1
assert modify_roles.pyquery('table tbody tr td.name a')[0].text == 'Accès Service'
assert base.user_liege.roles.count() == 0
modify_roles = app.post('/manage/users/%s/roles/' % base.user_liege.pk,
params={
'csrfmiddlewaretoken': app.cookies['csrftoken'],
'action': 'add',
'role': base.role_service_liege.pk
})
assert base.user_liege.roles.count() == 1
assert base.user_liege.roles.get().name == 'Accès Service'
roles = app.get('/manage/roles/')
assert len(roles.pyquery('table tbody tr')) == 1
assert roles.pyquery('table tbody tr td.name a')[0].text == 'Accès Service'
# Select3 only shows users from Liège
service_role = app.get('/manage/roles/%s/' % base.role_service_liege.pk)
select2_url = service_role.pyquery('select#id_user')[0].attrib['data-ajax--url']
select2_field_id = service_role.pyquery('select#id_user')[0].attrib['data-field_id']
select2_response = app.get(select2_url, params={'field_id': select2_field_id, 'term': ''})
assert select2_response.json['more'] is False
assert len(select2_response.json['results']) == 3
ids = set(result['id'] for result in select2_response.json['results'])
assert User.objects.filter(id__in=ids, ou=base.ou_liege).count() == 3