Ejemplo n.º 1
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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
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)
Ejemplo n.º 4
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)
Ejemplo n.º 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)
Ejemplo n.º 6
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)
Ejemplo n.º 7
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)
Ejemplo n.º 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)
Ejemplo n.º 9
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)
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
    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()
Ejemplo n.º 12
0
    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()
Ejemplo n.º 13
0
    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()
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
    def put(self, request, collection, experiment):
        """
        Update a experiment using django rest framework

        Args:
            request: DRF Request object
            collection: Collection name
            experiment : Experiment name for the new experiment

        Returns:
            Experiment
        """
        try:
            # Check if the object exists
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment,
                                                    collection=collection_obj)
            if request.user.has_perm("update", experiment_obj):
                serializer = ExperimentUpdateSerializer(experiment_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'] != experiment:
                        lookup_key = str(collection_obj.pk) + '&' + str(
                            experiment_obj.pk)
                        boss_key = collection_obj.name + '&' + request.data[
                            'name']
                        LookUpKey.update_lookup_experiment(
                            lookup_key, boss_key, collection_obj.name,
                            request.data['name'])

                    # return the object back to the user
                    experiment = serializer.data['name']
                    experiment_obj = Experiment.objects.get(
                        name=experiment, collection=collection_obj)
                    serializer = ExperimentReadSerializer(experiment_obj)
                    return Response(serializer.data)
                else:
                    return BossHTTPError("{}".format(serializer.errors),
                                         ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('update', experiment)

        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except BossError as err:
            return err.to_http()
Ejemplo n.º 16
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()
Ejemplo n.º 17
0
    def put(self, request, collection, experiment, channel_layer):
        """
        Update new Channel or Layer
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel_layer: Channel or Layer name

        Returns :
            ChannelLayer
        """
        channel_layer_data = request.data.copy()
        if 'is_channel' in channel_layer_data:
            channel_layer_data['is_channel'] = self.get_bool(channel_layer_data['is_channel'])

        try:
            # Check if the object exists
            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("update", channel_layer_obj):
                serializer = ChannelLayerSerializer(channel_layer_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'] != channel_layer:
                        lookup_key = str(collection_obj.pk) + '&' + str(experiment_obj.pk) + '&' \
                                     + str(channel_layer_obj.pk)
                        boss_key = collection_obj.name + '&' + experiment_obj.name + '&' + request.data['name']
                        LookUpKey.update_lookup(lookup_key, boss_key, collection_obj.name,  experiment_obj.name,
                                                request.data['name'])

                    return Response(serializer.data)
                else:
                    return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('update', channel_layer)

        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except ChannelLayer.DoesNotExist:
            return BossResourceNotFoundError(channel_layer)
Ejemplo n.º 18
0
    def delete(self, request, collection, experiment, channel):
        """
        Delete a Channel
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel: Channel name

        Returns :
            Http status
        """
        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)

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

                # The channel cannot be deleted if this is the source of any other channels
                derived_channels = channel_obj.get_derived()
                if len(derived_channels) > 0:
                    return BossHTTPError(
                        "Channel {} is the source channel of other channels and cannot be deleted"
                        .format(channel), ErrorCodes.INTEGRITY_ERROR)
                channel_obj.to_be_deleted = timezone.now()
                channel_obj.save()
                return HttpResponse(status=204)
            else:
                return BossPermissionError('delete', channel)

        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except Channel.DoesNotExist:
            return BossResourceNotFoundError(channel)
        except ProtectedError:
            return BossHTTPError(
                "Cannot delete {}. It has channels that reference it.".format(
                    channel), ErrorCodes.INTEGRITY_ERROR)
Ejemplo n.º 19
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):
             coordframe_obj.delete()
             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)
Ejemplo n.º 20
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):
                serializer = CollectionSerializer(collection_obj)
                return Response(serializer.data, status=200)
            else:
                return BossPermissionError('read', collection)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
Ejemplo n.º 21
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):
                serializer = ExperimentSerializer(experiment_obj)
                return Response(serializer.data)
            else:
                return BossPermissionError('read', experiment)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
Ejemplo n.º 22
0
    def put(self, request, collection, experiment, channel):
        """
        Update new Channel
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel: Channel name

        Returns :
            Channel
        """
        if 'name' in request.data:
            channel_name = request.data['name']
        else:
            channel_name = channel
        try:
            # Check if the object exists
            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)

            if request.user.has_perm("update", channel_obj):

                # The source and related channels are names and need to be removed from the dict before serialization
                source_channels = request.data.pop('sources', [])
                related_channels = request.data.pop('related', [])

                # Validate the source and related channels if they are incuded
                channels = self.validate_source_related_channels(experiment_obj, source_channels, related_channels)
                source_channels_objs = channels[0]
                related_channels_objs = channels[1]

                serializer = ChannelUpdateSerializer(channel_obj, data=request.data, partial=True)
                if serializer.is_valid():
                    serializer.save()

                    channel_obj = Channel.objects.get(name=channel_name, experiment=experiment_obj)
                    # Save source and related channels if they are valid
                    channel_obj = self.update_source_related_channels(channel_obj, experiment_obj, source_channels_objs,
                                                                      related_channels_objs)

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

                    # return the object back to the user
                    channel = serializer.data['name']
                    channel_obj = Channel.objects.get(name=channel, experiment=experiment_obj)
                    serializer = ChannelReadSerializer(channel_obj)
                    return Response(serializer.data)
                else:
                    return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('update', channel)

        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except Channel.DoesNotExist:
            return BossResourceNotFoundError(channel)
Ejemplo n.º 23
0
    def post(self, request, collection, experiment, channel):
        """
        Post a new Channel
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel: Channel name

        Returns :
            Channel
        """

        channel_data = request.data.copy()
        channel_data['name'] = channel

        try:
            # Get the collection and experiment
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment, collection=collection_obj)

            # Check for add permissions
            if request.user.has_perm("add", experiment_obj):
                channel_data['experiment'] = experiment_obj.pk

                # The source and related channels are names and need to be removed from the dict before serialization
                source_channels = channel_data.pop('sources', [])
                related_channels = channel_data.pop('related', [])

                # Source channels have to be included for new annotation channels
                if 'type' in channel_data and channel_data['type'] == 'annotation' and len(source_channels) == 0:
                    return BossHTTPError("Annotation channels require the source channel to be set. "
                                         "Specify a valid source channel in the post", ErrorCodes.INVALID_POST_ARGUMENT)

                # Validate the source and related channels if they are incuded
                channels = self.validate_source_related_channels(experiment_obj, source_channels, related_channels)
                source_channels_objs = channels[0]
                related_channels_objs = channels[1]

                # Validate and create the channel
                serializer = ChannelSerializer(data=channel_data)
                if serializer.is_valid():
                    serializer.save(creator=self.request.user)
                    channel_obj = Channel.objects.get(name=channel_data['name'], experiment=experiment_obj)

                    # Save source and related channels if they are valid
                    channel_obj = self.add_source_related_channels(channel_obj, experiment_obj, source_channels_objs,
                                                                   related_channels_objs)

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

                    # Add Lookup key
                    lookup_key = str(collection_obj.pk) + '&' + str(experiment_obj.pk) + '&' + str(channel_obj.pk)
                    boss_key = collection_obj.name + '&' + experiment_obj.name + '&' + channel_obj.name
                    LookUpKey.add_lookup(lookup_key, boss_key, collection_obj.name, experiment_obj.name,
                                         channel_obj.name)

                    serializer = ChannelReadSerializer(channel_obj)
                    return Response(serializer.data, status=status.HTTP_201_CREATED)
                else:
                    return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('add', experiment)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except Channel.DoesNotExist:
            return BossResourceNotFoundError(channel)
        except BossError as err:
            return err.to_http()
        except ValueError:
            return BossHTTPError("Value Error in post data", ErrorCodes.TYPE_ERROR)
Ejemplo n.º 24
0
    def post(self, request, collection, experiment, channel_layer):
        """
        Post a new Channel
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel_layer: Channel or Layer name

        Returns :
            ChannelLayer
        """

        channel_layer_data = request.data.copy()
        channel_layer_data['name'] = channel_layer

        try:
            if 'channels' in channel_layer_data:
                channels = dict(channel_layer_data)['channels']
            else:
                channels = []
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment, collection=collection_obj)
            # Check for add permissions
            if request.user.has_perm("add", experiment_obj):
                channel_layer_data['experiment'] = experiment_obj.pk
                channel_layer_data['is_channel'] = self.get_bool(channel_layer_data['is_channel'])

                # layers require at least 1 channel
                if (channel_layer_data['is_channel'] is False) and (len(channels) == 0):
                    return BossHTTPError("Invalid Request.Please specify a valid channel for the layer",
                                         ErrorCodes.INVALID_POST_ARGUMENT)

                serializer = ChannelLayerSerializer(data=channel_layer_data)
                if serializer.is_valid():
                    serializer.save(creator=self.request.user)
                    channel_layer_obj = ChannelLayer.objects.get(name=channel_layer_data['name'],
                                                                 experiment=experiment_obj)

                    # Layer?
                    if not channel_layer_obj.is_channel:
                        # Layers must map to at least 1 channel
                        for channel_id in channels:
                            # Is this a valid channel?
                            channel_obj = ChannelLayer.objects.get(pk=channel_id)
                            if channel_obj:
                                channel_layer_map = {'channel': channel_id, 'layer': channel_layer_obj.pk}
                                map_serializer = ChannelLayerMapSerializer(data=channel_layer_map)
                                if map_serializer.is_valid():
                                    map_serializer.save()

                    # Assign permissions to the users primary group
                    BossPermissionManager.add_permissions_primary_group(self.request.user, channel_layer_obj)

                    # Add Lookup key
                    lookup_key = str(collection_obj.pk) + '&' + str(experiment_obj.pk) + '&' + str(channel_layer_obj.pk)
                    boss_key = collection_obj.name + '&' + experiment_obj.name + '&' + channel_layer_obj.name
                    LookUpKey.add_lookup(lookup_key, boss_key, collection_obj.name, experiment_obj.name,
                                         channel_layer_obj.name)

                    return Response(serializer.data, status=status.HTTP_201_CREATED)
                else:
                    return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('add', experiment)
        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)
Ejemplo n.º 25
0
    def post(self, request, collection, experiment, channel):
        """
        Post a new Channel
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel: Channel name

        Returns :
            Channel
        """

        channel_data = request.data.copy()
        channel_data['name'] = channel

        try:
            is_admin = BossPermissionManager.is_in_group(
                request.user, ADMIN_GRP)
            if 'bucket' in channel_data and channel_data[
                    'bucket'] and not is_admin:
                return BossHTTPError('Only admins can set bucket name',
                                     ErrorCodes.MISSING_PERMISSION)

            if 'cv_path' in channel_data and channel_data[
                    'cv_path'] and not is_admin:
                return BossHTTPError('Only admins can set cv_path',
                                     ErrorCodes.MISSING_PERMISSION)

            # Get the collection and experiment
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment,
                                                    collection=collection_obj)

            # Check for add permissions
            if request.user.has_perm("add", experiment_obj):
                channel_data['experiment'] = experiment_obj.pk

                use_cloudvol = channel_data.get(
                    'storage_type', None) == Channel.StorageType.CLOUD_VOLUME
                cv_path = channel_data.get('cv_path', None)
                if use_cloudvol and (cv_path is None or cv_path == ''):
                    channel_data[
                        'cv_path'] = f'/{collection}/{experiment}/{channel}'

                if use_cloudvol:
                    # DX NOTE: For now we assume that cloudvolume channels are downsampled. This means
                    # that the num_hierarchy_levels in the experiment should be limited to the available
                    # mip levels in the cloudvolume layer.
                    channel_data['downsample_status'] = 'DOWNSAMPLED'

                # The source and related channels are names and need to be removed from the dict before serialization
                source_channels = channel_data.pop('sources', [])
                related_channels = channel_data.pop('related', [])

                # TODO: Removed source channel requirement for annotation channels. Future update should allow source channel from
                # different collections.

                # Source channels have to be included for new annotation channels
                # if 'type' in channel_data and channel_data['type'] == 'annotation' and len(source_channels) == 0:
                #     return BossHTTPError("Annotation channels require the source channel to be set. "
                #                          "Specify a valid source channel in the post", ErrorCodes.INVALID_POST_ARGUMENT)

                # Validate the source and related channels if they are incuded
                channels = self.validate_source_related_channels(
                    experiment_obj, source_channels, related_channels)
                source_channels_objs = channels[0]
                related_channels_objs = channels[1]

                # Validate and create the channel
                serializer = ChannelSerializer(data=channel_data)
                if serializer.is_valid():
                    serializer.save(creator=self.request.user)
                    channel_obj = Channel.objects.get(
                        name=channel_data['name'], experiment=experiment_obj)

                    # Save source and related channels if they are valid
                    channel_obj = self.add_source_related_channels(
                        channel_obj, experiment_obj, source_channels_objs,
                        related_channels_objs)

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

                    # Add Lookup key
                    lookup_key = str(collection_obj.pk) + '&' + str(
                        experiment_obj.pk) + '&' + str(channel_obj.pk)
                    boss_key = collection_obj.name + '&' + experiment_obj.name + '&' + channel_obj.name
                    LookUpKey.add_lookup(lookup_key, boss_key,
                                         collection_obj.name,
                                         experiment_obj.name, channel_obj.name)

                    serializer = ChannelReadSerializer(channel_obj)
                    return Response(serializer.data,
                                    status=status.HTTP_201_CREATED)
                else:
                    return BossHTTPError("{}".format(serializer.errors),
                                         ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('add', experiment)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except Channel.DoesNotExist:
            return BossResourceNotFoundError(channel)
        except BossError as err:
            return err.to_http()
        except ValueError:
            return BossHTTPError("Value Error in post data",
                                 ErrorCodes.TYPE_ERROR)