Exemplo n.º 1
0
def set_instance_settings(settings, force=False):
    """Set instance settings if they are not yet set. If <force> is True, the
    values will be set regardless. The <settings> parameter is expected to be a
    list of dictionaries where each has a key and a value field. The key is the
    settings familiy, e.g. "neuron-name-service" and the value is the respective
    settings data.
    """
    if type(settings) != dict:
        raise ValueError("Settings needs to be a dictionry")

    data_store = ClientDatastore.objects.get(name='settings')
    client_data_map = dict((cd.key, cd) for cd in ClientData.objects.filter(
        datastore=data_store, project=None, user=None))

    to_save = []
    for key, value in settings.items():
        if key in client_data_map:
            client_data = client_data_map.get(key)
            settings_context = client_data.value
            to_save.append(client_data)
        else:
            settings_context = {"entries": {}, "version": 0}
            client_data = ClientData(datastore=data_store,
                                     project=None,
                                     user=None,
                                     key=key,
                                     value=settings_context)
            to_save.append(client_data)

        for context_setting_key, context_setting_value in value.items():
            if context_setting_key in settings_context["entries"]:
                if not force:
                    continue
                context_setting = settings_context.get("entries").get(
                    context_setting_key)
                context_setting["value"] = context_setting_value
            else:
                context_setting = {
                    "value": context_setting_value,
                    "overridable": True
                }
                settings_context["entries"][
                    context_setting_key] = context_setting

    for o in to_save:
        o.save()
Exemplo n.º 2
0
    def put(self,
            request: Request,
            name: Optional[int] = None,
            format=None) -> Response:
        """Create or replace a key-value data entry for the client.

        Each entry is associated with a datastore, an optional project, an
        optional user, and a key. Creating a request that duplicates this
        quadruple will replace rather than create the value in the key-value
        pair.

        Entries associated with neither a project nor user are considered
        global; those associated with a project but no user are project-
        default; those associated with a user but no project are user-default;
        and those associated with both a project and a user are user-project
        specific. When listing key-value data, all four of these values, if
        existing, will be returned.
        ---
        parameters:
        - name: name
          description: |
            String key for the **datastore** with which this key-value entry is
            associated.
          required: true
          type: string
          paramType: path
        - name: project_id
          description: |
            ID of a project to associate this data with, if any.
          required: false
          type: integer
          paramType: form
        - name: ignore_user
          description: |
            Whether to associate this key-value entry with the instance rather
            than the request user. Only project administrators can do this
            for project-associated instance data, and only super users can do
            this for global data (instance data not associated with any
            project).
          required: false
          type: boolean
          default: false
          paramType: form
        - name: key
          description: A key for this entry.
          required: true
          type: string
          paramType: form
        - name: value
          description: A value for this entry. Must be valid JSON.
          required: true
          type: string
          paramType: form
        - name: format
          description: This function parameter is ignored
          required: false
          type: Any
          default: None
        response_serializer: ClientDataSerializer
        """
        if request.user == get_anonymous_user(
        ) or not request.user.is_authenticated:
            raise PermissionDenied('Unauthenticated or anonymous users ' \
                                   'can not create data.')
        datastore = get_object_or_404(ClientDatastore, name=name)

        key = request.data.get('key', None)
        if not key:
            raise ValidationError('A key for the data must be provided.')

        value = request.data.get('value', None)
        if not value:
            raise ValidationError('A value for the data must be provided.')
        # Validate JSON by reserializing.
        try:
            value = json.loads(value)
        except ValueError as exc:
            raise ValidationError('Data value is invalid JSON: ' + str(exc))

        project_id = request.data.get('project_id', None)
        project = None
        if project_id:
            project_id = int(project_id)
            project = get_object_or_404(Project, pk=project_id)
            if not check_user_role(request.user, project,
                                   [UserRole.Browse, UserRole.Annotate]):
                raise PermissionDenied('User lacks the appropriate ' \
                                       'permissions for this project.')

        ignore_user = get_request_bool(request.data, 'ignore_user', False)
        if ignore_user and not project_id:
            if not request.user.is_superuser:
                raise PermissionDenied('Only super users can create instance ' \
                                       'data.')
        if ignore_user:
            if not check_user_role(request.user, project, [UserRole.Admin]):
                raise PermissionDenied('Only administrators can create ' \
                                       'project default data.')
        user = None if ignore_user else request.user

        try:
            data = ClientData.objects.get(datastore=datastore,
                                          key=key,
                                          project=project,
                                          user=user)
            data.value = value
            data.full_clean()
            data.save()
            return Response(status=status.HTTP_204_NO_CONTENT)
        except ClientData.DoesNotExist:
            data = ClientData(datastore=datastore,
                              key=key,
                              value=value,
                              project=project,
                              user=user)
            data.full_clean()
            data.save()
            serializer = ClientDataSerializer(data)
            return Response(serializer.data)
Exemplo n.º 3
0
    def put(self, request, name=None, format=None):
        """Create or replace a key-value data entry for the client.

        Each entry is associated with a datastore, an optional project, an
        optional user, and a key. Creating a request that duplicates this
        quadruple will replace rather than create the value in the key-value
        pair.

        Entries associated with neither a project nor user are considered
        global; those associated with a project but no user are project-
        default; those associated with a user but no project are user-default;
        and those associated with both a project and a user are user-project
        specific. When listing key-value data, all four of these values, if
        existing, will be returned.
        ---
        parameters:
        - name: name
          description: |
            String key for the **datastore** with which this key-value entry is
            associated.
          required: true
          type: string
          paramType: path
        - name: project_id
          description: |
            ID of a project to associate this data with, if any.
          required: false
          type: integer
          paramType: form
        - name: ignore_user
          description: |
            Whether to associate this key-value entry with the instance rather
            than the request user. Only project administrators can do this
            for project-associated instance data, and only super users can do
            this for global data (instance data not associated with any
            project).
          required: false
          type: boolean
          default: false
          paramType: form
        - name: key
          description: A key for this entry.
          required: true
          type: string
          paramType: form
        - name: value
          description: A value for this entry. Must be valid JSON.
          required: true
          type: string
          paramType: form
        response_serializer: ClientDataSerializer
        """
        if request.user == get_anonymous_user() or not request.user.is_authenticated:
            raise PermissionDenied('Unauthenticated or anonymous users ' \
                                   'can not create data.')
        datastore = get_object_or_404(ClientDatastore, name=name)

        key = request.data.get('key', None)
        if not key:
            raise ValidationError('A key for the data must be provided.')

        value = request.data.get('value', None)
        if not value:
            raise ValidationError('A value for the data must be provided.')
        # Validate JSON by reserializing.
        try:
            value = json.loads(value)
        except ValueError as exc:
            raise ValidationError('Data value is invalid JSON: ' + str(exc))

        project_id = request.data.get('project_id', None)
        project = None
        if project_id:
            project_id = int(project_id)
            project = get_object_or_404(Project, pk=project_id)
            if not check_user_role(request.user,
                                   project,
                                   [UserRole.Browse, UserRole.Annotate]):
                raise PermissionDenied('User lacks the appropriate ' \
                                       'permissions for this project.')

        ignore_user = get_request_bool(request.data, 'ignore_user', False)
        if ignore_user and not project_id:
            if not request.user.is_superuser:
                raise PermissionDenied('Only super users can create instance ' \
                                       'data.')
        if ignore_user:
            if not check_user_role(request.user,
                                   project,
                                   [UserRole.Admin]):
                raise PermissionDenied('Only administrators can create ' \
                                       'project default data.')
        user = None if ignore_user else request.user

        try:
            data = ClientData.objects.get(datastore=datastore,
                                          key=key,
                                          project=project,
                                          user=user)
            data.value = value
            data.full_clean()
            data.save()
            return Response(status=status.HTTP_204_NO_CONTENT)
        except ClientData.DoesNotExist:
            data = ClientData(datastore=datastore,
                              key=key,
                              value=value,
                              project=project,
                              user=user)
            data.full_clean()
            data.save()
            serializer = ClientDataSerializer(data)
            return Response(serializer.data)