示例#1
0
    def post(self, request, user_name, role_name):
        """
        Assign a role to a user
        Args:
            request: Django rest framework request
            user_name: User name
            role_name : Role name

        Returns:
            Http status of the request

        """
        try:
            if role_name not in ['admin', 'user-manager', 'resource-manager']:
                return BossHTTPError(404,
                                     "Invalid role name {}".format(role_name),
                                     30000)

            with KeyCloakClient('BOSS') as kc:
                response = kc.map_role_to_user(user_name, role_name)
                return Response(serializer.data, status=201)

        except Exception as e:
            return BossHTTPError(
                404, "Unable to map role {} to user {} in keycloak. {}".format(
                    role_name, user_name, e), 30000)
示例#2
0
    def delete(self, request, user_name, role_name):
        """
        Delete a user
        Args:
            request: Django rest framework request
            user_name: User name from the request
            role_name: Role name from the request

        Returns:
            Http status of the request

        """
        try:

            if role_name not in ['admin', 'user-manager', 'resource-manager']:
                return BossHTTPError(404,
                                     "Invalid role name {}".format(role_name),
                                     30000)
            with KeyCloakClient('BOSS') as kc:
                response = kc.remove_role_from_user(user_name, role_name)
                return Response(status=204)

        except Exception as e:
            return BossHTTPError(
                404,
                "Unable to remove role {} from user {} in keycloak. {}".format(
                    role_name, user_name, e), 30000)
示例#3
0
    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)
示例#4
0
    def get(self, request, user_name, role_name=None):
        """
        Check if the user has a specific role
        Args:
           request: Django rest framework request
           user_name: User name
           role_name:

        Returns:
            True if the user has the role
        """
        try:
            with KeyCloakClient('BOSS') as kc:
                resp = kc.get_realm_roles(user_name)
                roles = [r['name'] for r in resp]
                # DP TODO: filter roles array to limit to valid roles??

                if role_name is None:
                    return Response(roles, status=200)
                else:
                    valid = ['admin', 'user-manager', 'resource-manager']
                    if role_name not in valid:
                        return BossHTTPError(
                            404, "Invalid role name {}".format(role_name),
                            30000)

                    exists = role_name in roles
                    return Response(exists, status=200)

        except Exception as e:
            return BossHTTPError(
                404, "Error getting user's {} roles from keycloak. {}".format(
                    user_name, e), 30000)
示例#5
0
    def delete(self, request, collection, experiment):
        """
        Delete a experiment
        Args:
            request: DRF Request object
            collection:  Name of collection
            experiment: Experiment name to delete
        Returns:
            Http status
        """
        try:
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment, collection=collection_obj)
            if request.user.has_perm("delete", experiment_obj):
                # Are there channels that reference it
                serializer = ExperimentReadSerializer(experiment_obj)
                if len(serializer.get_valid_channels(experiment_obj)) > 0:
                    # This experiment has channels that reference it and cannot be deleted
                    return BossHTTPError(" Experiment {} has channels that reference it and cannot be deleted."
                                         "Please delete the channels first.".format(experiment),
                                         ErrorCodes.INTEGRITY_ERROR)

                experiment_obj.to_be_deleted = datetime.now()
                experiment_obj.save()

                return HttpResponse(status=204)
            else:
                return BossPermissionError('delete', experiment)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except ProtectedError:
            return BossHTTPError("Cannot delete {}. It has channels that reference it."
                                 .format(experiment), ErrorCodes.INTEGRITY_ERROR)
示例#6
0
文件: views.py 项目: jingpengw/boss
    def get(self, request, collection, experiment, dataset, resolution,
            x_range, y_range, z_range):
        """
        View to handle GET requests for a cuboid of data while providing all params

        :param request: DRF Request object
        :type request: rest_framework.request.Request
        :param collection: Unique Collection identifier, indicating which collection you want to access
        :param experiment: Experiment identifier, indicating which experiment you want to access
        :param dataset: Dataset identifier, indicating which channel or layer you want to access
        :param resolution: Integer indicating the level in the resolution hierarchy (0 = native)
        :param x_range: Python style range indicating the X coordinates of where to post the cuboid (eg. 100:200)
        :param y_range: Python style range indicating the Y coordinates of where to post the cuboid (eg. 100:200)
        :param z_range: Python style range indicating the Z coordinates of where to post the cuboid (eg. 100:200)
        :return:
        """
        # Check if parsing completed without error. If an error did occur, return to user.
        if isinstance(request.data, BossParserError):
            return request.data.to_http()

        # Process request and validate
        try:
            req = BossRequest(request)
        except BossError as err:
            return BossHTTPError(err.args[0], err.args[1], err.args[2])

        # Convert to Resource
        resource = project.BossResourceDjango(req)

        # Get bit depth
        try:
            self.bit_depth = resource.get_bit_depth()
        except ValueError:
            return BossHTTPError(
                "Unsupported data type: {}".format(resource.get_data_type()),
                ErrorCodes.TYPE_ERROR)

        # Make sure cutout request is under 1GB UNCOMPRESSED
        total_bytes = req.get_x_span() * req.get_y_span() * req.get_z_span(
        ) * len(req.get_time()) * (self.bit_depth / 8)
        if total_bytes > settings.CUTOUT_MAX_SIZE:
            return BossHTTPError(
                "Cutout request is over 1GB when uncompressed. Reduce cutout dimensions.",
                ErrorCodes.REQUEST_TOO_LARGE)

        # Get interface to SPDB cache
        cache = SpatialDB(settings.KVIO_SETTINGS, settings.STATEIO_CONFIG,
                          settings.OBJECTIO_CONFIG)

        # Get the params to pull data out of the cache
        corner = (req.get_x_start(), req.get_y_start(), req.get_z_start())
        extent = (req.get_x_span(), req.get_y_span(), req.get_z_span())

        # Get a Cube instance with all time samples
        data = cache.cutout(
            resource, corner, extent, req.get_resolution(),
            [req.get_time().start, req.get_time().stop])

        # Send data to renderer
        return Response(data)
示例#7
0
    def delete(self, request, coordframe):
        """
        Delete a coordinate frame
        Args:
            request: DRF Request object
            coordframe:  Name of coordinateframe to delete
        Returns:
            Http status
        """
        try:
            coordframe_obj = CoordinateFrame.objects.get(name=coordframe)

            if request.user.has_perm("delete", coordframe_obj):
                # Are there experiments that reference it
                serializer = CoordinateFrameDeleteSerializer(coordframe_obj)
                if len(serializer.get_valid_exps(coordframe_obj)) > 0:
                    # This collection has experiments that reference it and cannot be deleted
                    return BossHTTPError(" Coordinate frame {} has experiments that reference it and cannot be deleted."
                                         "Please delete the experiments first.".format(coordframe),
                                         ErrorCodes.INTEGRITY_ERROR)

                coordframe_obj.to_be_deleted = datetime.now()
                coordframe_obj.save()
                return HttpResponse(status=204)
            else:
                return BossPermissionError('delete', coordframe)
        except CoordinateFrame.DoesNotExist:
            return BossResourceNotFoundError(coordframe)
        except ProtectedError:
            return BossHTTPError("Cannot delete {}. It has experiments that reference it.".format(coordframe),
                                 ErrorCodes.INTEGRITY_ERROR)
示例#8
0
    def get(self, request, collection, experiment, channel):
        """
        Retrieve information about a channel.
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel: Channel name

        Returns :
            Channel
        """
        try:
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment, collection=collection_obj)
            channel_obj = Channel.objects.get(name=channel, experiment=experiment_obj)

            # Check for permissions
            if request.user.has_perm("read", channel_obj):
                if channel_obj.to_be_deleted is not None:
                    return BossHTTPError("Invalid Request. This Resource has been marked for deletion",
                                         ErrorCodes.RESOURCE_MARKED_FOR_DELETION)
                serializer = ChannelReadSerializer(channel_obj)
                return Response(serializer.data)
            else:
                return BossPermissionError('read', channel)

        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except Channel.DoesNotExist:
            return BossResourceNotFoundError(channel)
        except ValueError:
            return BossHTTPError("Value Error in post data", ErrorCodes.TYPE_ERROR)
示例#9
0
    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'):
                if group_name == ADMIN_GRP or group_name == PUBLIC_GRP:
                    return BossHTTPError(
                        'Admin and public groups cannot be deleted.',
                        ErrorCodes.BAD_REQUEST)
                else:
                    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)
示例#10
0
    def post(self, request, collection, experiment):
        """Create a new experiment

        View to create a new experiment and an associated bosskey for that experiment
        Args:
            request: DRF Request object
            collection : Collection name
            experiment : Experiment name
        Returns:
            Experiment

        """
        experiment_data = request.data.copy()
        experiment_data['name'] = experiment
        try:
            # Get the collection information
            collection_obj = Collection.objects.get(name=collection)

            if request.user.has_perm("add", collection_obj):
                experiment_data['collection'] = collection_obj.pk

                # Update the coordinate frame
                if 'coord_frame' not in experiment_data:
                    return BossHTTPError("This request requires a valid coordinate frame",
                                         ErrorCodes.INVALID_POST_ARGUMENT)

                coord_frame_obj = CoordinateFrame.objects.get(name=experiment_data['coord_frame'])
                experiment_data['coord_frame'] = coord_frame_obj.pk

                serializer = ExperimentSerializer(data=experiment_data)
                if serializer.is_valid():
                    serializer.save(creator=self.request.user)
                    experiment_obj = Experiment.objects.get(name=experiment_data['name'], collection=collection_obj)

                    # Assign permissions to the users primary group and admin group
                    BossPermissionManager.add_permissions_primary_group(self.request.user, experiment_obj)
                    BossPermissionManager.add_permissions_admin_group(experiment_obj)

                    lookup_key = str(collection_obj.pk) + '&' + str(experiment_obj.pk)
                    boss_key = collection_obj.name + '&' + experiment_obj.name
                    LookUpKey.add_lookup(lookup_key, boss_key, collection_obj.name, experiment_obj.name)

                    serializer = ExperimentReadSerializer(experiment_obj)
                    return Response(serializer.data, status=status.HTTP_201_CREATED)
                else:
                    return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('add', collection)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except CoordinateFrame.DoesNotExist:
            return BossResourceNotFoundError(experiment_data['coord_frame'])
        except ValueError:
            return BossHTTPError("Value Error.Collection id {} in post data needs to be an integer"
                                 .format(experiment_data['collection']), ErrorCodes.TYPE_ERROR)
示例#11
0
    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)
示例#12
0
    def post(self, request, collection, experiment=None, channel=None):
        """
        View to handle POST requests for metadata

        Args:
            request: DRF Request object
            collection: Collection Name specifying the collection you want to get the meta data for
            experiment: Experiment name. default = None
            channel: Channel name. Default = None

        Returns:

        """

        if 'key' not in request.query_params or 'value' not in request.query_params:
            return BossHTTPError(
                "Missing optional argument key/value in the request",
                ErrorCodes.INVALID_POST_ARGUMENT)

        try:
            # Create the request dict
            request_args = {
                "service": "meta",
                "collection_name": collection,
                "experiment_name": experiment,
                "channel_name": channel,
                "key": request.query_params['key'],
                "value": request.query_params['value']
            }
            req = BossRequest(request, request_args)
            lookup_key = req.get_lookup_key()
        except BossError as err:
            return err.to_http()

        if not lookup_key:
            return BossHTTPError(
                "Invalid request. Unable to parse the datamodel arguments",
                ErrorCodes.INVALID_POST_ARGUMENT)

        mkey = request.query_params['key']
        value = request.query_params['value']

        # Post Metadata the dynamodb database
        mdb = metadb.MetaDB()
        if mdb.get_meta(lookup_key, mkey):
            return BossHTTPError(
                "Invalid request. The key {} already exists".format(mkey),
                ErrorCodes.INVALID_POST_ARGUMENT)
        mdb.write_meta(lookup_key, mkey, value)
        return HttpResponse(status=201)
示例#13
0
    def get(self, request, collection, experiment=None, channel_layer=None):
        """
        View to handle GET requests for metadata

        Args:
            request: DRF Request object
            collection: Collection Name
            experiment: Experiment name. default = None
            channel_layer: Channel or Layer name

        Returns:

        """
        try:
            # Validate the request and get the lookup Key
            req = BossRequest(request)
            lookup_key = req.get_lookup_key()

        except BossError as err:
            return err.to_http()

        if not lookup_key or lookup_key == "":
            return BossHTTPError(
                "Invalid request. Unable to parse the datamodel arguments", )

        if 'key' not in request.query_params:
            # List all keys that are valid for the query
            mdb = metadb.MetaDB()
            mdata = mdb.get_meta_list(lookup_key)
            keys = []
            if mdata:
                for meta in mdata:
                    keys.append(meta['key'])
            data = {'keys': keys}
            return Response(data)

        else:

            mkey = request.query_params['key']
            mdb = metadb.MetaDB()
            mdata = mdb.get_meta(lookup_key, mkey)
            if mdata:
                data = {'key': mdata['key'], 'value': mdata['metavalue']}
                return Response(data)
            else:
                return BossHTTPError(
                    "Invalid request. Key {} Not found in the database".format(
                        mkey), ErrorCodes.INVALID_POST_ARGUMENT)
示例#14
0
    def get(self, request, collection, experiment):
        """
        GET requests for a single instance of a experiment

        Args:
            request: DRF Request object
            collection: Collection name specifying the collection you want
            experiment: Experiment name specifying the experiment instance
        Returns :
            Experiment
        """
        try:
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment, collection=collection_obj)
            # Check for permissions
            if request.user.has_perm("read", experiment_obj):
                if experiment_obj.to_be_deleted is not None:
                    return BossHTTPError("Invalid Request. This Resource has been marked for deletion",
                                         ErrorCodes.RESOURCE_MARKED_FOR_DELETION)
                serializer = ExperimentReadSerializer(experiment_obj)
                return Response(serializer.data)
            else:
                return BossPermissionError('read', experiment)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
示例#15
0
    def delete(self, request, collection, experiment):
        """
        Delete a experiment
        Args:
            request: DRF Request object
            collection:  Name of collection
            experiment: Experiment name to delete
        Returns:
            Http status
        """
        try:
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment, collection=collection_obj)
            if request.user.has_perm("delete", experiment_obj):
                experiment_obj.delete()
                # # get the lookup key and delete all the meta data for this object
                # bosskey = collection + '&' + experiment
                # lkey = LookUpKey.get_lookup_key(bosskey)
                # mdb = MetaDB()
                # mdb.delete_meta_keys(lkey)

                # delete the lookup key for this object
                LookUpKey.delete_lookup_key(collection, experiment, None)
                return HttpResponse(status=204)
            else:
                return BossPermissionError('delete', experiment)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except ProtectedError:
            return BossHTTPError("Cannot delete {}. It has channels or layers that reference "
                                      "it.".format(experiment), ErrorCodes.INTEGRITY_ERROR)
示例#16
0
    def put(self, request, coordframe):
        """
        Update a coordinate frame using django rest framework

        Args:
            request: DRF Request object
            coordframe: Coordinate frame name
        Returns:
            CoordinateFrame
        """
        try:
            # Check if the object exists
            coordframe_obj = CoordinateFrame.objects.get(name=coordframe)

            if request.user.has_perm("update", coordframe_obj):
                serializer = CoordinateFrameUpdateSerializer(coordframe_obj, data=request.data, partial=True)
                if serializer.is_valid():
                    serializer.save()

                    # return the object back to the user
                    coordframe = serializer.data['name']
                    coordframe_obj = CoordinateFrame.objects.get(name=coordframe)
                    serializer = CoordinateFrameSerializer(coordframe_obj)
                    return Response(serializer.data)
                else:
                    return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('update', coordframe)
        except CoordinateFrame.DoesNotExist:
            return BossResourceNotFoundError(coordframe)
示例#17
0
    def post(self, request, coordframe):
        """Create a new coordinate frame

        View to create a new coordinate frame
        Args:
            request: DRF Request object
            coordframe : Coordinate frame name
        Returns:
            CoordinateFrame

        """
        coordframe_data = request.data.copy()
        coordframe_data['name'] = coordframe

        serializer = CoordinateFrameSerializer(data=coordframe_data)
        if serializer.is_valid():
            serializer.save(creator=self.request.user)
            coordframe_obj = CoordinateFrame.objects.get(name=coordframe_data['name'])

            # Assign permissions to the users primary group and admin group
            BossPermissionManager.add_permissions_primary_group(self.request.user, coordframe_obj)
            BossPermissionManager.add_permissions_admin_group(coordframe_obj)

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
示例#18
0
    def put(self, request, collection):
        """
        Update a collection using django rest framework
        Args:
            request: DRF Request object
            collection: Collection name
        Returns:
            Collection
        """
        try:
            # Check if the object exists
            collection_obj = Collection.objects.get(name=collection)

            # Check for permissions
            if request.user.has_perm("update", collection_obj):
                serializer = CollectionSerializer(collection_obj, data=request.data, partial=True)
                if serializer.is_valid():
                    serializer.save()

                    # update the lookup key if you update the name
                    if 'name' in request.data and request.data['name'] != collection:
                        lookup_key = str(collection_obj.pk)
                        boss_key = request.data['name']
                        LookUpKey.update_lookup(lookup_key, boss_key, request.data['name'])

                    return Response(serializer.data)
                else:
                    return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('update', collection)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
示例#19
0
    def get(self, request, collection, experiment, channel_layer):
        """
        Retrieve information about a channel.
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel_layer: Channel or Layer name

        Returns :
            ChannelLayer
        """
        try:
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment, collection=collection_obj)
            channel_layer_obj = ChannelLayer.objects.get(name=channel_layer, experiment=experiment_obj)

            # Check for permissions
            if request.user.has_perm("read", channel_layer_obj):
                serializer = ChannelLayerSerializer(channel_layer_obj)
                return Response(serializer.data)
            else:
                return BossPermissionError('read', channel_layer)

        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except ChannelLayer.DoesNotExist:
            return BossResourceNotFoundError(channel_layer)
        except ValueError:
            return BossHTTPError("Value Error in post data", ErrorCodes.TYPE_ERROR)
示例#20
0
    def post(self, request, user_name, role_name):
        """
        Assign a role to a user

        Args:
            request: Django rest framework request
            user_name: User name of user to assign role to
            role_name : Role name of role to assign to user

        Returns:
            None
        """
        # DP NOTE: admin role has to be assigned manually in Keycloak
        if role_name == 'admin':
            return BossHTTPError("Cannot assign 'admin' role",
                                 ErrorCodes.INVALID_ROLE)

        # DP NOTE: user-manager role can only be modified by an admin
        if role_name == 'user-manager':
            resp = check_for_admin(request.user)
            if resp is not None:
                return resp

        try:
            with KeyCloakClient('BOSS') as kc:
                response = kc.map_role_to_user(user_name, role_name)
                return Response(status=201)

        except KeyCloakError:
            msg = "Unable to map role '{}' to user '{}' in Keycloak".format(
                role_name, user_name)
            return BossKeycloakError(msg)
示例#21
0
    def delete(self, request, collection, experiment, channel_layer):
        """
        Delete a Channel  or a Layer
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel_layer: Channel or Layer name

        Returns :
            Http status
        """
        try:
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment, collection=collection_obj)
            channel_layer_obj = ChannelLayer.objects.get(name=channel_layer, experiment=experiment_obj)

            if request.user.has_perm("delete", channel_layer_obj):
                channel_layer_obj.delete()

                # delete the lookup key for this object
                LookUpKey.delete_lookup_key(collection, experiment, channel_layer)
                return HttpResponse(status=204)
            else:
                return BossPermissionError('delete', channel_layer)

        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except ChannelLayer.DoesNotExist:
            return BossResourceNotFoundError(channel_layer)
        except ProtectedError:
            return BossHTTPError("Cannot delete {}. It has layers that reference it.".format(channel_layer),
                                 ErrorCodes.INTEGRITY_ERROR)
示例#22
0
    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)
示例#23
0
    def get(self, request, collection):
        """
        Get a single instance of a collection

        Args:
            request: DRF Request object
            collection: Collection name specifying the collection you want
        Returns:
            Collection
        """
        try:
            collection_obj = Collection.objects.get(name=collection)

            # Check for permissions
            if request.user.has_perm("read", collection_obj):
                if collection_obj.to_be_deleted is not None:
                    return BossHTTPError("Invalid Request. This Resource has been marked for deletion",
                                         ErrorCodes.RESOURCE_MARKED_FOR_DELETION)

                serializer = CollectionSerializer(collection_obj)
                return Response(serializer.data, status=200)
            else:
                return BossPermissionError('read', collection)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
示例#24
0
    def delete(self, request, ingest_job_id):
        """

        Args:
            request:
            ingest_job_id:

        Returns:

        """
        try:
            ingest_mgmr = IngestManager()
            ingest_job = ingest_mgmr.get_ingest_job(ingest_job_id)

            # Check permissions
            if not self.is_user_or_admin(request, ingest_job):
                return BossHTTPError(
                    "Only the creator or admin can cancel an ingest job",
                    ErrorCodes.INGEST_NOT_CREATOR)

            # "DELETED" status is 3
            ingest_mgmr.cleanup_ingest_job(ingest_job, 3)
            blog = BossLogger().logger
            blog.info("Deleted Ingest Job {}".format(ingest_job_id))
            return Response(status=status.HTTP_204_NO_CONTENT)

        except BossError as err:
            return err.to_http()
示例#25
0
    def delete(self, request, user_name, role_name):
        """
        Unasign a role from a user

        Args:
            request: Django rest framework request
            user_name: User name of user to unassign role from
            role_name : Role name of role to unassign from user

        Returns:
            None
        """
        # DP NOTE: admin role has to be removed manually in Keycloak
        if role_name == 'admin':
            return BossHTTPError("Cannot remove 'admin' role",
                                 ErrorCodes.INVALID_ROLE)

        # DP NOTE: user-manager role can only be modified by an admin
        if role_name == 'user-manager':
            resp = check_for_admin(request.user)
            if resp is not None:
                return resp

        try:
            with self.get_keycloak_client() as kc:
                response = kc.remove_role_from_user(user_name, role_name)
                return Response(status=204)

        except KeyCloakError:
            msg = "Unable to remove role '{}' from user '{}' in Keycloak".format(
                role_name, user_name)
            return BossKeycloakError(msg)
示例#26
0
    def post(self, request, collection):
        """Create a new collection

        View to create a new collection and an associated bosskey for that collection
        Args:
            request: DRF Request object
            collection : Collection name
        Returns:
            Collection

        """
        col_data = request.data.copy()
        col_data['name'] = collection

        # Save the object
        serializer = CollectionSerializer(data=col_data)
        if serializer.is_valid():
            serializer.save(creator=self.request.user)
            collection_obj = Collection.objects.get(name=col_data['name'])

            # Assign permissions to the users primary group and admin group
            BossPermissionManager.add_permissions_primary_group(self.request.user, collection_obj)
            BossPermissionManager.add_permissions_admin_group(collection_obj)

            lookup_key = str(collection_obj.pk)
            boss_key = collection_obj.name
            LookUpKey.add_lookup(lookup_key, boss_key, collection_obj.name)

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
示例#27
0
    def delete(self, request, collection, experiment=None, channel=None):
        """
        View to handle the delete requests for metadata
        Args:
            request: DRF Request object
            collection: Collection name. Default = None
            experiment: Experiment name. Default = None
            channel: Channel name . Default = None

        Returns:

        """
        if 'key' not in request.query_params:
            return BossHTTPError(
                "Missing optional argument key in the request",
                ErrorCodes.INVALID_POST_ARGUMENT)

        try:
            # Create the request dict
            request_args = {
                "service": "meta",
                "collection_name": collection,
                "experiment_name": experiment,
                "channel_name": channel,
                "key": request.query_params['key'],
            }
            req = BossRequest(request, request_args)
            lookup_key = req.get_lookup_key()
        except BossError as err:
            return err.to_http()

        if not lookup_key:
            return BossHTTPError(
                "Invalid request. Unable to parse the datamodel arguments",
                ErrorCodes.INVALID_POST_ARGUMENT)

        mkey = request.query_params['key']

        # Delete metadata from the dynamodb database
        mdb = metadb.MetaDB()
        response = mdb.delete_meta(lookup_key, mkey)

        if 'Attributes' in response:
            return HttpResponse(status=204)
        else:
            return BossHTTPError("[ERROR]- Key {} not found ".format(mkey),
                                 ErrorCodes.INVALID_POST_ARGUMENT)
示例#28
0
    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)
示例#29
0
def check_for_admin(user):
    bpm = BossPrivilegeManager(user)
    if not bpm.has_role('admin'):
        return BossHTTPError(
            str(user) + " does not have the required role 'admin'",
            ErrorCodes.MISSING_ROLE)
    else:
        return None
示例#30
0
    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()