api: add list and retrieve role member(s) api (#50889)
This commit is contained in:
parent
852655fb95
commit
ed01a4e8c3
|
@ -22,6 +22,11 @@ urlpatterns = [
|
|||
url(r'^register/$', api_views.register, name='a2-api-register'),
|
||||
url(r'^password-change/$', api_views.password_change, name='a2-api-password-change'),
|
||||
url(r'^user/$', api_views.user, name='a2-api-user'),
|
||||
url(
|
||||
r'^roles/(?P<role_uuid>[\w+]*)/members/$',
|
||||
api_views.roles_members,
|
||||
name='a2-api-role-members-list',
|
||||
),
|
||||
url(
|
||||
r'^roles/(?P<role_uuid>[\w+]*)/members/(?P<member_uuid>[^/]+)/$',
|
||||
api_views.role_membership,
|
||||
|
|
|
@ -878,6 +878,23 @@ class RolesAPI(api_mixins.GetOrCreateMixinView, ExceptionHandlerMixin, ModelView
|
|||
super(RolesAPI, self).perform_destroy(instance)
|
||||
|
||||
|
||||
class RolesMembersAPI(UsersAPI):
|
||||
def initial(self, request, *args, **kwargs):
|
||||
super(RolesMembersAPI, self).initial(request, *args, **kwargs)
|
||||
Role = get_role_model()
|
||||
self.role = get_object_or_404(Role, uuid=kwargs['role_uuid'])
|
||||
|
||||
def get_queryset(self):
|
||||
if self.request.GET.get('nested', 'false').lower() in ('true', '1'):
|
||||
qs = self.role.all_members()
|
||||
else:
|
||||
qs = self.role.members.all()
|
||||
return qs
|
||||
|
||||
|
||||
roles_members = RolesMembersAPI.as_view({'get': 'list'})
|
||||
|
||||
|
||||
class RoleMembershipAPI(ExceptionHandlerMixin, APIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
|
@ -888,18 +905,27 @@ class RoleMembershipAPI(ExceptionHandlerMixin, APIView):
|
|||
self.role = get_object_or_404(Role, uuid=kwargs['role_uuid'])
|
||||
self.member = get_object_or_404(User, uuid=kwargs['member_uuid'])
|
||||
|
||||
perm = 'a2_rbac.manage_members_role'
|
||||
authorized = request.user.has_perm(perm, obj=self.role)
|
||||
if not authorized:
|
||||
raise PermissionDenied(u'User not allowed to manage role members')
|
||||
def get(self, request, *args, **kwargs):
|
||||
if not request.user.has_perm('a2_rbac.view_role', obj=self.role):
|
||||
raise PermissionDenied(u'User not allowed to view role')
|
||||
if self.request.GET.get('nested', 'false').lower() in ('true', '1'):
|
||||
qs = self.role.all_members()
|
||||
else:
|
||||
qs = self.role.members.all()
|
||||
member = get_object_or_404(qs, uuid=kwargs['member_uuid'])
|
||||
return Response(BaseUserSerializer(member).data)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
if not request.user.has_perm('a2_rbac.manage_members_role', obj=self.role):
|
||||
raise PermissionDenied(u'User not allowed to manage role members')
|
||||
self.role.members.add(self.member)
|
||||
return Response(
|
||||
{'result': 1, 'detail': _('User successfully added to role')}, status=status.HTTP_201_CREATED
|
||||
)
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
if not request.user.has_perm('a2_rbac.manage_members_role', obj=self.role):
|
||||
raise PermissionDenied(u'User not allowed to manage role members')
|
||||
self.role.members.remove(self.member)
|
||||
return Response(
|
||||
{'result': 1, 'detail': _('User successfully removed from role')}, status=status.HTTP_200_OK
|
||||
|
|
|
@ -677,6 +677,115 @@ def test_api_users_create_force_password_reset(app, client, settings, superuser)
|
|||
assert 'Password changed' in resp
|
||||
|
||||
|
||||
def test_api_role_get_member(app, api_user, role, member):
|
||||
app.authorization = ('Basic', (api_user.username, api_user.username))
|
||||
|
||||
authorized = api_user.has_perm('a2_rbac.view_role', role)
|
||||
|
||||
if member.username == 'fake' or role.name == 'fake':
|
||||
status = 404
|
||||
elif authorized:
|
||||
status = 404
|
||||
else:
|
||||
status = 403
|
||||
|
||||
resp = app.get('/api/roles/{0}/members/{1}/'.format(role.uuid, member.uuid), status=status)
|
||||
|
||||
if member.username == 'fake' or role.name == 'fake':
|
||||
assert resp.json == {'result': 0, 'errors': {'detail': 'Not found.'}}
|
||||
elif status == 404:
|
||||
assert resp.json == {'result': 0, 'errors': {'detail': 'Not found.'}}
|
||||
member.roles.add(role)
|
||||
resp = app.get('/api/roles/{0}/members/{1}/'.format(role.uuid, member.uuid))
|
||||
assert resp.json['uuid'] == member.uuid
|
||||
assert (
|
||||
set(
|
||||
[
|
||||
'id',
|
||||
'ou',
|
||||
'date_joined',
|
||||
'last_login',
|
||||
'password',
|
||||
'is_superuser',
|
||||
'uuid',
|
||||
'username',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'email_verified',
|
||||
'is_staff',
|
||||
'is_active',
|
||||
'modified',
|
||||
'last_account_deletion_alert',
|
||||
'deactivation',
|
||||
'first_name_verified',
|
||||
'last_name_verified',
|
||||
]
|
||||
)
|
||||
== set(resp.json.keys())
|
||||
)
|
||||
else:
|
||||
assert resp.json['result'] == 0
|
||||
assert resp.json['errors'] == 'User not allowed to view role'
|
||||
|
||||
|
||||
def test_api_role_get_member_nested(app, admin_ou1, user_ou1, role_ou1, role_random):
|
||||
app.authorization = ('Basic', (admin_ou1.username, admin_ou1.username))
|
||||
url = reverse(
|
||||
'a2-api-role-member',
|
||||
kwargs={
|
||||
'role_uuid': role_ou1.uuid,
|
||||
'member_uuid': admin_ou1.uuid,
|
||||
},
|
||||
)
|
||||
|
||||
Attribute.objects.create(kind='birthdate', name='birthdate', label='birthdate', required=True)
|
||||
user_ou1.attributes.birthdate = datetime.date(2019, 2, 2)
|
||||
user_ou1.save()
|
||||
|
||||
# admin.ou1 is an inherited member of role_ou1
|
||||
role_random.members.add(admin_ou1)
|
||||
role_random.add_parent(role_ou1)
|
||||
assert admin_ou1 not in role_ou1.members.all()
|
||||
assert admin_ou1 in role_ou1.all_members()
|
||||
|
||||
# default api call without nested users
|
||||
resp = app.get(url, status=404)
|
||||
assert resp.json == {'result': 0, 'errors': {'detail': 'Not found.'}}
|
||||
|
||||
# api call with nested users
|
||||
resp = app.get(url, params={'nested': 'true'})
|
||||
assert resp.json['username'] == 'admin.ou1'
|
||||
assert (
|
||||
set(
|
||||
[
|
||||
'ou',
|
||||
'id',
|
||||
'uuid',
|
||||
'is_staff',
|
||||
'is_superuser',
|
||||
'first_name',
|
||||
'first_name_verified',
|
||||
'last_name',
|
||||
'last_name_verified',
|
||||
'date_joined',
|
||||
'last_login',
|
||||
'username',
|
||||
'password',
|
||||
'email',
|
||||
'is_active',
|
||||
'modified',
|
||||
'email_verified',
|
||||
'last_account_deletion_alert',
|
||||
'deactivation',
|
||||
'birthdate',
|
||||
'birthdate_verified',
|
||||
]
|
||||
)
|
||||
== set(resp.json)
|
||||
)
|
||||
|
||||
|
||||
def test_api_role_add_member(app, api_user, role, member):
|
||||
app.authorization = ('Basic', (api_user.username, api_user.username))
|
||||
|
||||
|
@ -719,6 +828,8 @@ def test_api_role_remove_member(app, api_user, role, member):
|
|||
elif authorized:
|
||||
assert resp.json['result'] == 1
|
||||
assert resp.json['detail'] == 'User successfully removed from role'
|
||||
resp = app.get('/api/roles/{0}/members/{1}/'.format(role.uuid, member.uuid), status=404)
|
||||
assert resp.json == {'result': 0, 'errors': {'detail': 'Not found.'}}
|
||||
else:
|
||||
assert resp.json['result'] == 0
|
||||
assert resp.json['errors'] == 'User not allowed to manage role members'
|
||||
|
@ -1385,6 +1496,67 @@ def test_api_get_role_list(app, admin_ou1, role_ou1, role_random):
|
|||
assert field in role_dict
|
||||
|
||||
|
||||
def test_api_get_role_member_list(app, admin_ou1, user_ou1, role_ou1, role_random):
|
||||
app.authorization = ('Basic', (admin_ou1.username, admin_ou1.username))
|
||||
url = reverse('a2-api-role-members-list', kwargs={'role_uuid': role_ou1.uuid})
|
||||
|
||||
Attribute.objects.create(kind='birthdate', name='birthdate', label='birthdate', required=True)
|
||||
user_ou1.attributes.birthdate = datetime.date(2019, 2, 2)
|
||||
user_ou1.save()
|
||||
|
||||
# john.doe is a direct member of role_ou1
|
||||
role_ou1.members.add(user_ou1)
|
||||
assert user_ou1 in role_ou1.members.all()
|
||||
|
||||
# admin.ou1 is an inherited member of role_ou1
|
||||
role_random.members.add(admin_ou1)
|
||||
role_random.add_parent(role_ou1)
|
||||
assert admin_ou1 not in role_ou1.members.all()
|
||||
assert admin_ou1 in role_ou1.all_members()
|
||||
|
||||
# default api call without nested users
|
||||
resp = app.get(url)
|
||||
assert len(resp.json['results']) > 0
|
||||
for user_dict in resp.json['results']:
|
||||
assert (
|
||||
set(
|
||||
[
|
||||
'ou',
|
||||
'id',
|
||||
'uuid',
|
||||
'is_staff',
|
||||
'is_superuser',
|
||||
'first_name',
|
||||
'first_name_verified',
|
||||
'last_name',
|
||||
'last_name_verified',
|
||||
'date_joined',
|
||||
'last_login',
|
||||
'username',
|
||||
'password',
|
||||
'email',
|
||||
'is_active',
|
||||
'modified',
|
||||
'email_verified',
|
||||
'last_account_deletion_alert',
|
||||
'deactivation',
|
||||
'birthdate',
|
||||
'birthdate_verified',
|
||||
]
|
||||
)
|
||||
== set(user_dict.keys())
|
||||
)
|
||||
assert [x['username'] for x in resp.json['results']] == ['john.doe']
|
||||
|
||||
# api call with nested users
|
||||
resp = app.get(url, params={'nested': 'true'})
|
||||
assert [x['username'] for x in resp.json['results']] == ['john.doe', 'admin.ou1']
|
||||
|
||||
# get users ordered by usernames
|
||||
resp = app.get(url, params={'nested': 'true', 'ordering': 'username'})
|
||||
assert [x['username'] for x in resp.json['results']] == ['admin.ou1', 'john.doe']
|
||||
|
||||
|
||||
def test_no_opened_session_cookie_on_api(app, user, settings):
|
||||
settings.A2_OPENED_SESSION_COOKIE_DOMAIN = 'testserver.local'
|
||||
app.authorization = ('Basic', (user.username, user.username))
|
||||
|
|
Loading…
Reference in New Issue