def delete(self, request, group_name, user_name): """ Removes a user from a group Args: request: Django rest framework request group_name:Group name from the request user_name: User name from the request Returns: Http status of the request """ try: if group_name == 'public' or group_name == 'admin': return BossHTTPError( 'Cannot remove a user from the group {}. This is an admin managed group' .format(group_name), ErrorCodes.BAD_REQUEST) group = Group.objects.get(name=group_name) bgroup = BossGroup.objects.get(group=group) # Check the users permissions. if request.user.has_perm("maintain_group", bgroup): usr = User.objects.get(username=user_name) bgroup.group.user_set.remove(usr) return HttpResponse(status=204) else: return BossHTTPError( 'The user {} does not have the {} permission on the group {}' .format(request.user.username, 'maintain_group', group_name), ErrorCodes.MISSING_PERMISSION) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except User.DoesNotExist: return BossUserNotFoundError(user_name)
def delete(self, request, group_name): """ Delete a group. The user has to be an admin or the creator of the group Args: request: Django rest framework request group_name: Group name from the request Returns: Http status of the request """ try: group = Group.objects.get(name=group_name) bgroup = BossGroup.objects.get(group=group) bpm = BossPrivilegeManager(request.user) if request.user == bgroup.creator or bpm.has_role('admin'): group.delete() return Response(status=204) else: return BossHTTPError( 'Groups can only be deleted by the creator or administrator', ErrorCodes.MISSING_ROLE) except Group.DoesNotExist: return BossGroupNotFoundError(group_name)
def get(self, request, group_name, user_name=None): """ Gets the membership status of a user for a group Args: request: Django rest framework request group_name: Group name from the request user_name: User name from the request Returns: bool : True if the user is a member of the group """ try: group = Group.objects.get(name=group_name) if user_name: # Check the membership status for a user usr = User.objects.get(username=user_name) data = group.user_set.filter(id=usr.id).exists() return Response(data, status=200) else: # Return all the users in the group # TODO (pmanava1) - Check if the user has the role to do this users = group.user_set.all() serializer = UserSerializer(users, many=True) return Response(serializer.data, status=200) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except User.DoesNotExist: return BossUserNotFoundError(user_name)
def post(self, request, group_name, user_name): """ Adds a user to a group Args: request: Django rest framework request group_name: Group name from the request user_name: User name from the request Returns: Http status of the request """ try: group = Group.objects.get(name=group_name) bgroup = BossGroup.objects.get(group=group) # Check the users permissions. if request.user.has_perm("maintain_group", bgroup): usr = User.objects.get(username=user_name) bgroup.group.user_set.add(usr) return HttpResponse(status=204) else: return BossHTTPError( 'The user {} does not have the {} permission on the group {}' .format(request.user.username, 'maintain_group', group_name), ErrorCodes.MISSING_PERMISSION) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except User.DoesNotExist: return BossUserNotFoundError(user_name)
def delete(self, request): """ Delete permissions for a resource object Remove specific permissions for a existing group and resource object Args: request: Django rest framework request Returns: Http status code """ if 'group' not in request.query_params: return BossHTTPError("Group are not included in the request", ErrorCodes.INVALID_URL) if 'collection' not in request.query_params: return BossHTTPError( "Invalid resource or missing resource name in request", ErrorCodes.INVALID_URL) group_name = request.query_params.get('group', None) collection = request.query_params.get('collection', None) experiment = request.query_params.get('experiment', None) channel = request.query_params.get('channel', None) try: if not check_is_member_or_maintainer(request.user, group_name): return BossHTTPError( 'The user {} is not a member or maintainer of the group {} ' .format(request.user.username, group_name), ErrorCodes.MISSING_PERMISSION) resource_object = self.get_object(collection, experiment, channel) if resource_object is None: return BossHTTPError("Unable to validate the resource", ErrorCodes.UNABLE_TO_VALIDATE) if request.user.has_perm("remove_group", resource_object[0]): BossPermissionManager.delete_all_permissions_group( group_name, resource_object[0]) return Response(status=status.HTTP_204_NO_CONTENT) else: return BossPermissionError('remove group', resource_object[0].name) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except Permission.DoesNotExist: return BossHTTPError( "Invalid permissions in post".format( request.data['permissions']), ErrorCodes.UNRECOGNIZED_PERMISSION) except Exception as e: return BossHTTPError("{}".format(e), ErrorCodes.UNHANDLED_EXCEPTION) except BossError as err: return err.to_http()
def post(self, request): """ Add permissions to a resource Add new permissions for a existing group and resource object Args: request: Django rest framework request Returns: Http status code """ if 'permissions' not in request.data: return BossHTTPError("Permission are not included in the request", ErrorCodes.INVALID_URL) else: perm_list = dict(request.data)['permissions'] if 'group' not in request.data: return BossHTTPError("Group are not included in the request", ErrorCodes.INVALID_URL) if 'collection' not in request.data: return BossHTTPError("Invalid resource or missing resource name in request", ErrorCodes.INVALID_URL) group_name = request.data.get('group', None) collection = request.data.get('collection', None) experiment = request.data.get('experiment', None) channel = request.data.get('channel', None) try: # public group can only have read permission if group_name == 'public' and not (set(perm_list).issubset({'read', 'read_volumetric_data'})): return BossHTTPError("The public group can only have read permissions", ErrorCodes.INVALID_POST_ARGUMENT) # If the user is not a member or maintainer of the group, they cannot assign permissions if not check_is_member_or_maintainer(request.user, group_name): return BossHTTPError('The user {} is not a member or maintainer of the group {} '. format(request.user.username, group_name), ErrorCodes.MISSING_PERMISSION) resource_object = self.get_object(collection, experiment, channel) if resource_object is None: return BossHTTPError("Unable to validate the resource", ErrorCodes.UNABLE_TO_VALIDATE) resource = resource_object[0] if request.user.has_perm("assign_group", resource): BossPermissionManager.add_permissions_group(group_name, resource, perm_list) return Response(status=status.HTTP_201_CREATED) else: return BossPermissionError('assign group', collection) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except Permission.DoesNotExist: return BossHTTPError("Invalid permissions in post".format(request.data['permissions']), ErrorCodes.UNRECOGNIZED_PERMISSION) except BossError as err: return err.to_http()
def patch(self, request): """ Patch permissions for a resource Remove specific permissions for a existing group and resource object Args: request: Django rest framework request Returns: Http status code """ if 'permissions' not in request.data: return BossHTTPError("Permission are not included in the request", ErrorCodes. UNABLE_TO_VALIDATE) else: perm_list = dict(request.data)['permissions'] if 'group' not in request.data: return BossHTTPError("Group are not included in the request", ErrorCodes. UNABLE_TO_VALIDATE) if 'collection' not in request.data: return BossHTTPError("Invalid resource or missing resource name in request", ErrorCodes. UNABLE_TO_VALIDATE) group_name = request.data.get('group', None) collection = request.data.get('collection', None) experiment = request.data.get('experiment', None) channel = request.data.get('channel', None) try: # public group can only have read permission if group_name == 'public' and (len(perm_list) != 1 or perm_list[0] != 'read'): return BossHTTPError("The public group can only have read permissions", ErrorCodes.INVALID_POST_ARGUMENT) # If the user is not a member or maintainer of the group, they cannot patch permissions if not check_is_member_or_maintainer(request.user, group_name): return BossHTTPError('The user {} is not a member or maintainer of the group {} '. format(request.user.username, group_name), ErrorCodes.MISSING_PERMISSION) resource_object = self.get_object(collection, experiment, channel) if resource_object is None: return BossHTTPError("Unable to validate the resource", ErrorCodes.UNABLE_TO_VALIDATE) resource = resource_object[0] # remove all existing permission for the group if request.user.has_perm("remove_group", resource) and request.user.has_perm("assign_group", resource): BossPermissionManager.delete_all_permissions_group(group_name, resource) BossPermissionManager.add_permissions_group(group_name, resource, perm_list) return Response(status=status.HTTP_200_OK) else: return BossPermissionError('remove group', resource.name) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except Permission.DoesNotExist: return BossHTTPError("Invalid permissions in post".format(request.data['permissions']), ErrorCodes.UNRECOGNIZED_PERMISSION) except BossError as err: return err.to_http()
def delete(self, request, group_name, user_name): """ Removes a maintainer from the group Args: request: Django rest framework request group_name:Group name from the request user_name: User name from the request Returns: Http status of the request """ try: if group_name == PUBLIC_GRP or group_name == ADMIN_GRP: return BossHTTPError( 'Cannot remove a maintainer from the group {}. This is an admin managed group' .format(group_name), ErrorCodes.BAD_REQUEST) if user_name is None: return BossHTTPError('Missing username parameter in post.', ErrorCodes.INVALID_URL) elif user_name == ADMIN_USER: return BossHTTPError( 'Cannot remove {} maintainer from any group'.format( ADMIN_USER), ErrorCodes.BAD_REQUEST) group = Group.objects.get(name=group_name) bgroup = BossGroup.objects.get(group=group) # Check the users permissions. if request.user.has_perm("maintain_group", bgroup): usr = User.objects.get(username=user_name) status = usr.has_perm('maintain_group', bgroup) if status is False: return BossHTTPError( 'The user {} does not have the {} permission on the group {}' .format(usr.username, 'maintain_group', group_name), ErrorCodes.MISSING_PERMISSION) else: remove_perm('maintain_group', usr, bgroup) return HttpResponse(status=204) else: return BossHTTPError( 'The user {} does not have the {} permission on the group {}' .format(request.user.username, 'maintain_group', group_name), ErrorCodes.MISSING_PERMISSION) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except User.DoesNotExist: return BossUserNotFoundError(user_name)
def post(self, request, group_name, user_name): """ Adds a maintainer to a group Args: request: Django rest framework request group_name: Group name from the request user_name: User name from the request Returns: Http status of the request """ try: if group_name == 'public' or group_name == 'admin': return BossHTTPError( 'Cannot add a maintainer to the group {}. This is an admin managed group' .format(group_name), ErrorCodes.BAD_REQUEST) if user_name is None: return BossHTTPError('Missing username in post.', ErrorCodes.INVALID_URL) group = Group.objects.get(name=group_name) bgroup = BossGroup.objects.get(group=group) # Check the users permissions. if request.user.has_perm("maintain_group", bgroup): usr = User.objects.get(username=user_name) # assign permissions to the creator of the group group_perms = [ perm.codename for perm in get_perms_for_model(BossGroup) ] for permission in group_perms: assign_perm(permission, usr, bgroup) return HttpResponse(status=204) else: return BossHTTPError( 'The user {} does not have the {} permission on the group {}' .format(request.user.username, 'maintain_group', group_name), ErrorCodes.MISSING_PERMISSION) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except User.DoesNotExist: return BossUserNotFoundError(user_name)
def post(self, request, group_name, collection, experiment=None, channel_layer=None): """ Add permissions to a resource Add new permissions for a existing group and resource object Args: request: Django rest framework request group_name: Group name of an existing group collection: Collection name from the request experiment: Experiment name from the request channel_layer: Channel or layer name from the request Returns: Http status code """ if 'permissions' not in request.data: return BossHTTPError("Permission are not included in the request", ErrorCodes.INCOMPLETE_REQUEST) else: perm_list = dict(request.data)['permissions'] try: obj = self.get_object(collection, experiment, channel_layer) if request.user.has_perm("assign_group", obj): BossPermissionManager.add_permissions_group( group_name, obj, perm_list) return Response(status=status.HTTP_201_CREATED) else: return BossPermissionError('assign group', collection) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except Permission.DoesNotExist: return BossHTTPError( "Invalid permissions in post".format( request.data['permissions']), ErrorCodes.UNRECOGNIZED_PERMISSION) except BossError as err: return err.to_http()
def delete(self, request, group_name): """ Delete a group Args: request: Django rest framework request group_name: Group name from the request Returns: Http status of the request """ try: Group.objects.get(name=group_name).delete() return Response(status=204) except Group.DoesNotExist: return BossGroupNotFoundError(group_name)
def post(self, request, group_name): """ Create a new group is the group does not exist Args: request: Django rest framework request group_name: Group name from the request Returns: Http status of the request """ try: group, created = Group.objects.get_or_create(name=group_name) if not created: return BossHTTPError( "A group with name {} already exist".format(group_name), ErrorCodes.GROUP_EXISTS) bgroup = BossGroup.objects.create(group=group, creator=request.user) admin_user = User.objects.get(username=ADMIN_USER) # assign permissions to the creator of the group # Get the primary group of the creator group_name = request.user.username + "-primary" user_primary_group = Group.objects.get(name=group_name) admin_group = Group.objects.get(name=ADMIN_GRP) group_perms = [ perm.codename for perm in get_perms_for_model(BossGroup) ] for permission in group_perms: assign_perm(permission, user_primary_group, bgroup) assign_perm(permission, admin_group, bgroup) # add the creator to the group bgroup.group.user_set.add(request.user) return Response(status=201) except User.DoesNotExist: return BossUserNotFoundError(ADMIN_USER) except Group.DoesNotExist: return BossGroupNotFoundError(ADMIN_GRP)
def get(self, request, group_name, collection, experiment=None, channel_layer=None): """Return a list of permissions Get the list of the permissions for a group on a resource. These determine the access for the users in the group on the resource Args: request: Django Rest framework request group_name: Group name of an existing group collection: Collection name from the request experiment: Experiment name from the request channel_layer: Channel or Layer name from the request Returns: List of permissions """ try: obj = self.get_object(collection, experiment, channel_layer) perm = BossPermissionManager.get_permissions_group(group_name, obj) data = {'group': group_name, 'permissions': perm} return Response(data, status=status.HTTP_201_CREATED, content_type='application/json') except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except Permission.DoesNotExist: return BossHTTPError( "Invalid permissions in post".format( request.data['permissions']), ErrorCodes.UNRECOGNIZED_PERMISSION) except BossError as err: return err.to_http()
def delete(self, request, group_name, user_name): """ Removes a user from a group Args: request: Django rest framework request group_name:Group name from the request user_name: User name from the request Returns: Http status of the request """ try: usr = User.objects.get(username=user_name) Group.objects.get(name=group_name).user_set.remove(usr) return HttpResponse(status=204) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except User.DoesNotExist: return BossUserNotFoundError(user_name)
def get(self, request, group_name, user_name=None): """ Gets the maintianer status of a user for a group Args: request: Django rest framework request group_name: Group name from the request user_name: User name from the request Returns: bool : True if the user is a member of the group """ try: group = Group.objects.get(name=group_name) bgroup = BossGroup.objects.get(group=group) # Check for permissions. The logged in user has to be a member or group maintainer if not check_is_member_or_maintainer(request.user, group_name): return BossHTTPError( 'The user {} is not a member or maintainer of the group {} ' .format(request.user.username, group_name), ErrorCodes.MISSING_PERMISSION) if user_name is None: # Return all maintainers for the group list_maintainers = get_users_with_perms(bgroup) maintainers = [user.username for user in list_maintainers] data = {"maintainers": maintainers} else: # Both group name and user name are specified. Return the maintainer status for the user usr = User.objects.get(username=user_name) status = usr.has_perm("maintain_group", bgroup) data = {"result": status} return Response(data, status=200) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except User.DoesNotExist: return BossUserNotFoundError(user_name)
def get(self, request, group_name, user_name=None): """ Gets the membership status of a user for a group Args: request: Django rest framework request group_name: Group name from the request user_name: User name from the request Returns: bool : True if the user is a member of the group """ try: group = Group.objects.get(name=group_name) # Check for permissions. The logged in user has to be a member or group maintainer if not check_is_member_or_maintainer(request.user, group_name): return BossHTTPError( 'The user {} is not a member or maintainer of the group {} ' .format(request.user.username, group_name), ErrorCodes.MISSING_PERMISSION) if user_name is None: # Return all users for the group list_users = group.user_set.all().values_list('username', flat=True) list_users = [name for name in list_users] data = {"members": list_users} else: # Both group name and user name are specified. Return the membership status for the user usr = User.objects.get(username=user_name) status = group.user_set.filter(id=usr.id).exists() data = {"result": status} return Response(data, status=200) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except User.DoesNotExist: return BossUserNotFoundError(user_name)
def get(self, request): """Return a list of permissions Get the list of the permissions for a group on a resource. These determine the access for the users in the group on the resource Args: request: Django Rest framework request Returns: List of permissions """ try: obj_list = [] group = request.query_params.get('group', None) collection = request.query_params.get('collection', None) experiment = request.query_params.get('experiment', None) channel = request.query_params.get('channel', None) # get permission sets for models col_perms = [perm.codename for perm in get_perms_for_model(Collection)] exp_perms = [perm.codename for perm in get_perms_for_model(Experiment)] channel_perms = [perm.codename for perm in get_perms_for_model(Channel)] resource_object = self.get_object(collection, experiment, channel) if group and resource_object: group = Group.objects.get(name=group) resource_type = resource_object[1] # filtering on both group and resource resource = resource_object[0] perms = get_perms(group, resource) if len(perms) == 0: # Nothing to return data = {'permission-sets': []} return Response(data, status=status.HTTP_200_OK) if resource_type == 'collection': obj = {'group': group.name, 'collection': resource.name, 'permissions': perms} obj_list.append(obj) data = {'permission-sets': obj_list} elif resource_type == 'experiment': obj = {'group': group.name, 'collection': resource.collection.name, 'experiment': resource.name, 'permissions': perms} obj_list.append(obj) data = {'permission-sets': obj_list} else: obj = {'group': group.name, 'collection': resource.experiment.collection.name, 'experiment': resource.experiment.name, 'channel': resource.name, 'permissions': perms} obj_list.append(obj) data = {'permission-sets': obj_list} elif resource_object and not group: # filtering on resource resource = resource_object[0] resource_type = resource_object[1] list_member_groups = request.user.groups.all() for group in list_member_groups: perms = get_perms(group, resource) if resource_type == 'collection' and len(perms) > 0: obj = {'group': group.name, 'collection': resource.name, 'permissions': perms} obj_list.append(obj) elif resource_type == 'experiment' and len(perms) > 0: obj = {'group': group.name, 'collection': resource.collection.name, 'experiment': resource.name, 'permissions': perms} obj_list.append(obj) elif resource_type == 'channel' and len(perms) > 0: obj = {'group': group.name, 'collection': resource.experiment.collection.name, 'experiment': resource.experiment.name, 'channel': resource.name, 'permissions': perms} obj_list.append(obj) data = {'permission-sets': obj_list} elif group and not resource_object: # filtering on group group = Group.objects.get(name=group) col_list = get_objects_for_group(group, perms=col_perms, klass=Collection, any_perm=True) for col in col_list: col_perms = get_perms(group, col) obj = {'group': group.name, 'collection': col.name, 'permissions': col_perms} obj_list.append(obj) exp_list = get_objects_for_group(group, perms=exp_perms, klass=Experiment, any_perm=True) for exp in exp_list: exp_perms = get_perms(group, exp) obj_list.append({'group': group.name, 'collection': exp.collection.name, 'experiment': exp.name, 'permissions': exp_perms}) ch_list = get_objects_for_group(group, perms=channel_perms, klass=Channel, any_perm=True) for channel in ch_list: channel_perms = get_perms(group, channel) obj_list.append({'group': group.name, 'collection': channel.experiment.collection.name, 'experiment': channel.experiment.name, 'channel': channel.name, 'permissions': channel_perms}) data = {'permission-sets': obj_list} else: # no filtering list_member_groups = request.user.groups.all() for group in list_member_groups: col_list = get_objects_for_group(group, perms=col_perms, klass=Collection, any_perm=True) for col in col_list: col_perms = get_perms(group, col) obj = {'group': group.name, 'collection': col.name, 'permissions': col_perms} obj_list.append(obj) exp_list = get_objects_for_group(group, perms=exp_perms, klass=Experiment, any_perm=True) for exp in exp_list: exp_perms = get_perms(group, exp) obj_list.append({'group': group.name, 'collection': exp.collection.name, 'experiment': exp.name, 'permissions': col_perms}) ch_list = get_objects_for_group(group, perms=channel_perms, klass=Channel, any_perm=True) for channel in ch_list: channel_perms = get_perms(group, channel) obj_list.append({'group': group.name, 'collection': channel.experiment.collection.name, 'experiment': channel.experiment.name, 'channel': channel.name, 'permissions': col_perms}) data = {'permission-sets': obj_list} return Response(data, status=status.HTTP_200_OK) except Group.DoesNotExist: return BossGroupNotFoundError(group) except Permission.DoesNotExist: return BossHTTPError("Invalid permissions in post".format(request.data['permissions']), ErrorCodes.UNRECOGNIZED_PERMISSION) except BossError as err: return err.to_http()
def get(self, request, group_name=None): """ Get all groups Args: request: Django rest framework request group_name: Group name from the request Returns: Group if the group exists """ if group_name is not None: try: # Check for permissions. The logged in user has to be a member or group maintainer if not check_is_member_or_maintainer(request.user, group_name): return BossHTTPError( 'Unauthorized. The user {} is not a member or maintainer of the group {}' .format(request.user.username, group_name), ErrorCodes.MISSING_PERMISSION) group = Group.objects.get(name=group_name) bgroup = BossGroup.objects.get(group=group) data = {"name": group.name, "owner": bgroup.creator.username} resources = [] # get permission sets for models col_perms = [ perm.codename for perm in get_perms_for_model(Collection) ] exp_perms = [ perm.codename for perm in get_perms_for_model(Experiment) ] channel_perms = [ perm.codename for perm in get_perms_for_model(Channel) ] # get objects for the group col_list = get_objects_for_group(group, perms=col_perms, klass=Collection, any_perm=True) exp_list = get_objects_for_group(group, perms=exp_perms, klass=Experiment, any_perm=True) ch_list = get_objects_for_group(group, perms=channel_perms, klass=Channel, any_perm=True) for col in col_list: obj = {'collection': col.name} resources.append(obj) for exp in exp_list: obj = { 'collection': exp.collection.name, 'experiment': exp.name } resources.append(obj) for ch in ch_list: obj = { 'collection': ch.experiment.collection.name, 'experiment': ch.experiment.name, 'channel': ch.name } resources.append(obj) data['resources'] = resources return Response(data, status=200) except Group.DoesNotExist: return BossGroupNotFoundError(group_name) except BossGroup.DoesNotExist: return BossHTTPError( "The group {} is not configured correctly and does not have a creator. " "Contact an admin to update it".format(group_name), ErrorCodes.UNABLE_TO_VALIDATE) else: # Get all the groups that the logged in user is a member of list_member_groups = request.user.groups.values_list('name', flat=True) member_groups = [name for name in list_member_groups] # Get all groups that the user has maintainer permissions on group_perms = [ perm.codename for perm in get_perms_for_model(BossGroup) ] list_maintainer_groups = get_objects_for_user(request.user, group_perms, klass=BossGroup, any_perm=True) maintainer_groups = [ bgroup.group.name for bgroup in list_maintainer_groups ] if 'filter' in request.query_params and request.query_params[ 'filter'] == 'member': data = {'groups': member_groups} return Response(data, status=200) elif 'filter' in request.query_params and request.query_params[ 'filter'] == 'maintainer': data = {'groups': maintainer_groups} return Response(data, status=200) elif 'filter' not in request.query_params: all_groups = list(set(member_groups).union(maintainer_groups)) data = {'groups': all_groups} else: return BossHTTPError( 'Unrecogizes value {} in filter. Valid parameters are member or maintainer.', ErrorCodes.UNABLE_TO_VALIDATE) return Response(data, status=200)