0004-manager-use-new-manage_members-permission-20513.patch
src/authentic2/manager/role_views.py | ||
---|---|---|
155 | 155 |
def form_valid(self, form): |
156 | 156 |
user = form.cleaned_data['user'] |
157 | 157 |
action = form.cleaned_data['action'] |
158 |
if self.can_change:
|
|
158 |
if self.can_manage_members:
|
|
159 | 159 |
if action == 'add': |
160 | 160 |
if self.object.members.filter(pk=user.pk).exists(): |
161 | 161 |
messages.warning(self.request, _('User already in this role.')) |
... | ... | |
277 | 277 |
form_class = forms.RolesForm |
278 | 278 |
success_url = '..' |
279 | 279 |
template_name = 'authentic2/manager/form.html' |
280 |
permissions = ['a2_rbac.change_role']
|
|
280 |
permissions = ['a2_rbac.manage_members_role']
|
|
281 | 281 | |
282 | 282 |
def dispatch(self, request, *args, **kwargs): |
283 | 283 |
self.object = self.get_object() |
... | ... | |
325 | 325 |
model = get_role_model() |
326 | 326 |
success_url = '../..' |
327 | 327 |
template_name = 'authentic2/manager/role_remove_child.html' |
328 |
permissions = ['a2_rbac.change_role']
|
|
328 |
permissions = ['a2_rbac.manage_members_role']
|
|
329 | 329 | |
330 | 330 |
def dispatch(self, request, *args, **kwargs): |
331 | 331 |
self.object = self.get_object() |
... | ... | |
366 | 366 |
return ctx |
367 | 367 | |
368 | 368 |
def post(self, request, *args, **kwargs): |
369 |
if not self.request.user.has_perm('a2_rbac.change_role', self.parent):
|
|
369 |
if not self.request.user.has_perm('a2_rbac.manage_members_role', self.parent):
|
|
370 | 370 |
raise PermissionDenied |
371 | 371 |
self.object.remove_parent(self.parent) |
372 | 372 |
hooks.call_hooks('event', name='manager-remove-child-role', user=self.request.user, |
src/authentic2/manager/templates/authentic2/manager/role_members.html | ||
---|---|---|
52 | 52 | |
53 | 53 |
{% include "authentic2/manager/export_include.html" with export_view_name="a2-manager-role-members-export" %} |
54 | 54 | |
55 |
{% if view.can_change %}
|
|
56 |
<form method="post" class="manager-m2m-add-form"> |
|
55 |
{% if view.can_manage_members %}
|
|
56 |
<form method="post" class="manager-m2m-add-form" id="add-user">
|
|
57 | 57 |
{% csrf_token %} |
58 | 58 |
{{ form }} |
59 | 59 |
<button>{% trans "Add" %}</button> |
... | ... | |
103 | 103 |
<a title="{% trans "Indirect child role" %}" class="disabled role-remove icon-minus-sign"></a> |
104 | 104 |
{% endif %} |
105 | 105 |
{% endfor %} |
106 |
{% if view.can_change %}
|
|
106 |
{% if view.can_manage_members %}
|
|
107 | 107 |
<a rel="popup" href="{% url "a2-manager-role-add-child" pk=object.pk %}" class="role-add icon-add-sign"></a> |
108 | 108 |
{% else %} |
109 | 109 |
<a title="{% trans "Permission denied" %}" class="disabled role-add icon-add-sign"></a> |
src/authentic2/manager/templates/authentic2/manager/role_members_table.html | ||
---|---|---|
7 | 7 |
<th></th> |
8 | 8 |
{% endblock %} |
9 | 9 |
{% block table.tbody.last.column %} |
10 |
<td>{% if table.context.view.can_change and row.record.direct %}<a class="icon-remove-sign js-remove-object" data-confirm="{% blocktrans with username=row.record.get_full_name role=table.context.object %}Do you really want to remove user "{{ username }}" from role "{{ role }}" ?{% endblocktrans %}" href="#" data-pk-arg="user"></a>{% endif %}</td>
|
|
10 |
<td>{% if table.context.view.can_manage_members and row.record.direct %}<a class="icon-remove-sign js-remove-object" data-confirm="{% blocktrans with username=row.record.get_full_name role=table.context.object %}Do you really want to remove user "{{ username }}" from role "{{ role }}" ?{% endblocktrans %}" href="#" data-pk-arg="user"></a>{% endif %}</td>
|
|
11 | 11 |
{% endblock %} |
12 | 12 |
{% endif %} |
src/authentic2/manager/user_views.py | ||
---|---|---|
553 | 553 |
qs = qs.prefetch_related(models.Prefetch( |
554 | 554 |
'members', queryset=User.objects.filter(pk=self.object.pk), |
555 | 555 |
to_attr='member')) |
556 |
qs2 = self.request.user.filter_by_perm('a2_rbac.change_role', qs)
|
|
556 |
qs2 = self.request.user.filter_by_perm('a2_rbac.manage_members_role', qs)
|
|
557 | 557 |
managable_ids = map(str, qs2.values_list('pk', flat=True)) |
558 | 558 |
qs = qs.extra(select={'has_perm': 'a2_rbac_role.id in (%s)' % ', '.join(managable_ids)}) |
559 | 559 |
qs = qs.exclude(slug__startswith='_a2-managers-of-role') |
... | ... | |
578 | 578 |
user = self.object |
579 | 579 |
role = form.cleaned_data['role'] |
580 | 580 |
action = form.cleaned_data['action'] |
581 |
if self.request.user.has_perm('a2_rbac.change_role', role):
|
|
581 |
if self.request.user.has_perm('a2_rbac.manage_members_role', role):
|
|
582 | 582 |
if action == 'add': |
583 | 583 |
if user.roles.filter(pk=role.pk): |
584 | 584 |
messages.warning( |
src/authentic2/manager/views.py | ||
---|---|---|
115 | 115 |
or (hasattr(self, 'slug_url_kwarg') |
116 | 116 |
and self.slug_url_kwarg in self.kwargs)): |
117 | 117 |
self.object = self.get_object() |
118 |
view_perm = '%s.view_%s' % (app_label, model_name) |
|
119 |
change_perm = '%s.change_%s' % (app_label, model_name) |
|
120 |
delete_perm = '%s.delete_%s' % (app_label, model_name) |
|
121 |
self.can_view = request.user.has_perm(view_perm, self.object) |
|
122 |
self.can_change = request.user.has_perm(change_perm, |
|
123 |
self.object) |
|
124 |
self.can_delete = request.user.has_perm(delete_perm, |
|
125 |
self.object) |
|
118 |
permissions = ('view', 'change', 'delete', 'manage_members') |
|
119 |
for permission in permissions: |
|
120 |
perm = '%s.%s_%s' % (app_label, permission, model_name) |
|
121 |
setattr(self, 'can_' + permission, |
|
122 |
request.user.has_perm(perm, self.object)) |
|
126 | 123 |
if self.permissions \ |
127 | 124 |
and not request.user.has_perms( |
128 | 125 |
self.permissions, self.object): |
tests/test_manager.py | ||
---|---|---|
25 | 25 | |
26 | 26 |
from authentic2.a2_rbac.utils import get_default_ou |
27 | 27 | |
28 |
from django_rbac.utils import get_ou_model, get_role_model |
|
28 |
from django_rbac.utils import (get_ou_model, get_role_model, |
|
29 |
get_permission_model, get_operation) |
|
30 |
from django_rbac.models import VIEW_OP |
|
29 | 31 |
from django.contrib.auth import get_user_model |
32 |
from django.contrib.contenttypes.models import ContentType |
|
30 | 33 |
from django.utils.six.moves.urllib.parse import urlparse |
31 | 34 |
from utils import login, get_link_from_mail |
32 | 35 | |
... | ... | |
896 | 899 | |
897 | 900 |
user = User.objects.get(id=simple_user.id) |
898 | 901 |
assert not user.email_verified |
902 | ||
903 | ||
904 |
def test_manager_role_admin_permissions(app, simple_user, admin, simple_role): |
|
905 |
admin_role = simple_role.get_admin_role() |
|
906 |
simple_user.roles.add(admin_role) |
|
907 |
login(app, simple_user, '/manage/') |
|
908 | ||
909 |
# user can view users |
|
910 |
response = app.get('/manage/users/') |
|
911 |
q = response.pyquery.remove_namespaces() |
|
912 |
assert len(q('table tbody tr')) == 2 |
|
913 |
assert set([e.text for e in q('table tbody td.username')]) == {'admin', 'user'} |
|
914 | ||
915 |
# user can view administered roles |
|
916 |
response = app.get('/manage/roles/') |
|
917 |
q = response.pyquery.remove_namespaces() |
|
918 |
assert len(q('table tbody tr')) == 1 |
|
919 |
assert q('table tbody td.name').text() == 'simple role' |
|
920 | ||
921 |
# user can add members |
|
922 |
response = app.get('/manage/roles/%s/' % simple_role.pk) |
|
923 |
form = response.forms['add-user'] |
|
924 |
form['user'].force_value(admin.pk) |
|
925 |
response = form.submit().follow() |
|
926 |
assert simple_role in admin.roles.all() |
|
927 | ||
928 |
# user can delete members |
|
929 |
q = response.pyquery.remove_namespaces() |
|
930 |
assert q('table tbody tr td .icon-remove-sign') |
|
931 |
token = str(response.context['csrf_token']) |
|
932 |
params = {'action': 'remove', 'user': admin.pk, 'csrfmiddlewaretoken': token} |
|
933 |
app.post('/manage/roles/%s/' % simple_role.pk, params=params) |
|
934 |
assert simple_role not in admin.roles.all() |
|
935 | ||
936 |
# user can act on role inheritance |
|
937 |
role = Role.objects.create(name='test_role') |
|
938 |
view_role_perm = get_permission_model().objects.create( |
|
939 |
operation=get_operation(VIEW_OP), ou=role.ou, |
|
940 |
target_ct=ContentType.objects.get_for_model(Role), |
|
941 |
target_id=role.pk) |
|
942 |
simple_role.permissions.add(view_role_perm) |
|
943 |
simple_user.roles.add(simple_role) |
|
944 |
admin.roles.add(role) |
|
945 |
response = app.get('/manage/roles/%s/add-child/' % simple_role.pk) |
|
946 |
form = response.form |
|
947 |
form['roles'].force_value(role.pk) |
|
948 |
form.submit().follow() |
|
949 |
assert role in simple_role.children() |
|
950 | ||
951 |
url = '/manage/roles/%s/remove-child/%s/' % (simple_role.pk, role.pk) |
|
952 |
token = str(response.context['csrf_token']) |
|
953 |
app.post(url, params={'csrfmiddlewaretoken': token}) |
|
954 |
assert not role in simple_role.children() |
|
955 | ||
956 |
response = app.get('/manage/roles/%s/add-parent/' % role.pk) |
|
957 |
form = response.form |
|
958 |
form['roles'].force_value(simple_role.pk) |
|
959 |
form.submit().follow() |
|
960 |
assert simple_role in role.parents() |
|
961 | ||
962 |
url = '/manage/roles/%s/remove-parent/%s/' % (role.pk, simple_role.pk) |
|
963 |
token = str(response.context['csrf_token']) |
|
964 |
app.post(url, params={'csrfmiddlewaretoken': token}) |
|
965 |
assert not simple_role in role.parents() |
|
966 | ||
967 |
# user roles view works |
|
968 |
response = app.get('/manage/users/%s/roles/' % admin.pk) |
|
969 |
q = response.pyquery.remove_namespaces() |
|
970 |
assert len(q('table tbody tr')) == 1 |
|
971 |
assert q('table tbody td.name').text() == 'simple role' |
|
972 | ||
973 |
token = str(response.context['csrf_token']) |
|
974 |
params = {'action': 'add', 'role': simple_role.pk, 'csrfmiddlewaretoken': token} |
|
975 |
response = app.post('/manage/users/%s/roles/' % admin.pk, params=params) |
|
976 |
assert simple_role in admin.roles.all() |
|
977 | ||
978 |
app.get('/manage/roles/add/', status=403) |
|
979 |
app.get('/manage/roles/%s/edit/' % simple_role.pk, status=403) |
|
980 |
app.get('/manage/roles/%s/delete/' % simple_role.pk, status=403) |
|
899 |
- |