We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Data.create returns bad message when missing ADD permission on collection
If a user tries to run a process inside a collection, but doesn't have `ADD` permission, the api returns `{"detail":"Not found."}`

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `resolwe/flow/views/mixins.py`
Content:
```
1 """Mixins used in Resolwe Viewsets."""
2 from __future__ import absolute_import, division, print_function, unicode_literals
3 
4 from django.db import IntegrityError, transaction
5 
6 from guardian.shortcuts import assign_perm
7 from rest_framework import mixins, status
8 from rest_framework.decorators import list_route
9 from rest_framework.response import Response
10 
11 from resolwe.flow.models import DescriptorSchema
12 from resolwe.permissions.shortcuts import get_objects_for_user
13 
14 
15 class ResolweCreateModelMixin(mixins.CreateModelMixin):
16     """Mixin to support creating new `Resolwe` models.
17 
18     Extends `django_rest_framework`'s class `CreateModelMixin` with:
19 
20       * append user's id from request to posted data as `contributor`
21         key
22       * catch `IntegrityError`s, so we can return HTTP status 409
23         instead of raising error
24 
25     """
26 
27     def create(self, request, *args, **kwargs):
28         """Create a resource."""
29         ds_slug = request.data.get('descriptor_schema', None)
30         if ds_slug:
31             ds_query = DescriptorSchema.objects.filter(slug=ds_slug)
32             ds_query = get_objects_for_user(request.user, 'view_descriptorschema', ds_query)
33             try:
34                 request.data['descriptor_schema'] = ds_query.latest().pk
35             except DescriptorSchema.DoesNotExist:
36                 return Response(
37                     {'descriptor_schema': [
38                         'Invalid descriptor_schema slug "{}" - object does not exist.'.format(ds_slug)]},
39                     status=status.HTTP_400_BAD_REQUEST)
40 
41         request.data['contributor'] = request.user.pk
42         try:
43             return super(ResolweCreateModelMixin, self).create(request, *args, **kwargs)
44 
45         except IntegrityError as ex:
46             return Response({u'error': str(ex)}, status=status.HTTP_409_CONFLICT)
47 
48     def perform_create(self, serializer):
49         """Create a resource."""
50         with transaction.atomic():
51             instance = serializer.save()
52 
53             # Assign all permissions to the object contributor.
54             for permission in list(zip(*instance._meta.permissions))[0]:  # pylint: disable=protected-access
55                 assign_perm(permission, instance.contributor, instance)
56 
57 
58 class ResolweUpdateModelMixin(mixins.UpdateModelMixin):
59     """Mixin to support updating `Resolwe` models.
60 
61     Extends `django_rest_framework`'s class `UpdateModelMixin` with:
62 
63       * translate `descriptor_schema` field from DescriptorSchema's
64         slug to its id and return 400 error Response if it doesn't
65         exists
66 
67     """
68 
69     def update(self, request, *args, **kwargs):
70         """Update a resource."""
71         ds_slug = request.data.get('descriptor_schema', None)
72         if ds_slug:
73             ds_query = DescriptorSchema.objects.filter(slug=ds_slug)
74             ds_query = get_objects_for_user(request.user, 'view_descriptorschema', ds_query)
75             try:
76                 request.data['descriptor_schema'] = ds_query.latest().pk
77             except DescriptorSchema.DoesNotExist:
78                 return Response(
79                     {'descriptor_schema': [
80                         'Invalid descriptor_schema slug "{}" - object does not exist.'.format(ds_slug)]},
81                     status=status.HTTP_400_BAD_REQUEST)
82 
83         return super(ResolweUpdateModelMixin, self).update(request, *args, **kwargs)
84 
85 
86 class ResolweCheckSlugMixin(object):
87     """Slug validation."""
88 
89     @list_route(methods=[u'get'])
90     def slug_exists(self, request):
91         """Check if given url slug exists.
92 
93         Check if slug given in query parameter ``name`` exists. Return
94         ``True`` if slug already exists and ``False`` otherwise.
95 
96         """
97         if not request.user.is_authenticated():
98             return Response(status=status.HTTP_401_UNAUTHORIZED)
99 
100         if 'name' not in request.query_params:
101             return Response({'error': 'Query parameter `name` must be given.'},
102                             status=status.HTTP_400_BAD_REQUEST)
103 
104         queryset = self.get_queryset()
105         slug_name = request.query_params['name']
106         return Response(queryset.filter(slug__iexact=slug_name).exists())
107
```

Path: `resolwe/flow/views/data.py`
Content:
```
1 """Data viewset."""
2 from __future__ import absolute_import, division, print_function, unicode_literals
3 
4 from django.db import transaction
5 
6 from guardian.shortcuts import assign_perm
7 from rest_framework import exceptions, mixins, status, viewsets
8 from rest_framework.decorators import list_route
9 from rest_framework.response import Response
10 
11 from resolwe.flow.filters import DataFilter
12 from resolwe.flow.managers import manager
13 from resolwe.flow.models import Collection, Data, Process
14 from resolwe.flow.serializers import DataSerializer
15 from resolwe.flow.utils import dict_dot, get_data_checksum, iterate_schema
16 from resolwe.permissions.loader import get_permissions_class
17 from resolwe.permissions.mixins import ResolwePermissionsMixin
18 from resolwe.permissions.shortcuts import get_objects_for_user
19 
20 from .mixins import ResolweCheckSlugMixin, ResolweCreateModelMixin, ResolweUpdateModelMixin
21 
22 
23 class DataViewSet(ResolweCreateModelMixin,
24                   mixins.RetrieveModelMixin,
25                   ResolweUpdateModelMixin,
26                   mixins.DestroyModelMixin,
27                   mixins.ListModelMixin,
28                   ResolwePermissionsMixin,
29                   ResolweCheckSlugMixin,
30                   viewsets.GenericViewSet):
31     """API view for :class:`Data` objects."""
32 
33     queryset = Data.objects.all().prefetch_related('process', 'descriptor_schema', 'contributor')
34     serializer_class = DataSerializer
35     permission_classes = (get_permissions_class(),)
36     filter_class = DataFilter
37     ordering_fields = ('id', 'created', 'modified', 'started', 'finished', 'name')
38     ordering = ('id',)
39 
40     def create(self, request, *args, **kwargs):
41         """Create a resource."""
42         collections = request.data.get('collections', [])
43 
44         # check that user has permissions on all collections that Data
45         # object will be added to
46         for collection_id in collections:
47             try:
48                 collection = Collection.objects.get(pk=collection_id)
49             except Collection.DoesNotExist:
50                 return Response({'collections': ['Invalid pk "{}" - object does not exist.'.format(collection_id)]},
51                                 status=status.HTTP_400_BAD_REQUEST)
52 
53             if not request.user.has_perm('add_collection', obj=collection):
54                 if request.user.is_authenticated():
55                     raise exceptions.PermissionDenied
56                 else:
57                     raise exceptions.NotFound
58 
59         # translate processe's slug to id
60         process_slug = request.data.get('process', None)
61         process_query = Process.objects.filter(slug=process_slug)
62         process_query = get_objects_for_user(request.user, 'view_process', process_query)
63         try:
64             process = process_query.latest()
65         except Process.DoesNotExist:
66             return Response({'process': ['Invalid process slug "{}" - object does not exist.'.format(process_slug)]},
67                             status=status.HTTP_400_BAD_REQUEST)
68         request.data['process'] = process.pk
69 
70         # perform "get_or_create" if requested - return existing object
71         # if found
72         if kwargs.pop('get_or_create', False):
73             process_input = request.data.get('input', {})
74 
75             # use default values if they are not given
76             for field_schema, fields, path in iterate_schema(process_input, process.input_schema):
77                 if 'default' in field_schema and field_schema['name'] not in fields:
78                     dict_dot(process_input, path, field_schema['default'])
79 
80             checksum = get_data_checksum(process_input, process.slug, process.version)
81             data_qs = Data.objects.filter(
82                 checksum=checksum,
83                 process__persistence__in=[Process.PERSISTENCE_CACHED, Process.PERSISTENCE_TEMP],
84             )
85             data_qs = get_objects_for_user(request.user, 'view_data', data_qs)
86             if data_qs.exists():
87                 data = data_qs.order_by('created').last()
88                 serializer = self.get_serializer(data)
89                 return Response(serializer.data)
90 
91         # create the objects
92         resp = super(DataViewSet, self).create(request, *args, **kwargs)
93 
94         # run manager
95         manager.communicate()
96 
97         return resp
98 
99     @list_route(methods=[u'post'])
100     def get_or_create(self, request, *args, **kwargs):
101         """Get ``Data`` object if similar already exists, otherwise create it."""
102         kwargs['get_or_create'] = True
103         return self.create(request, *args, **kwargs)
104 
105     def perform_create(self, serializer):
106         """Create a resource."""
107         with transaction.atomic():
108             instance = serializer.save()
109 
110             # Assign all permissions to the object contributor.
111             for permission in list(zip(*instance._meta.permissions))[0]:  # pylint: disable=protected-access
112                 assign_perm(permission, instance.contributor, instance)
113 
114             # Assign data object to all specified collections.
115             collections = self.request.data.get('collections', [])
116             for c in collections:
117                 collection = Collection.objects.get(pk=c)
118                 collection.data.add(instance)
119
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/resolwe/flow/views/data.py b/resolwe/flow/views/data.py
--- a/resolwe/flow/views/data.py
+++ b/resolwe/flow/views/data.py
@@ -51,10 +51,14 @@
                                 status=status.HTTP_400_BAD_REQUEST)
 
             if not request.user.has_perm('add_collection', obj=collection):
-                if request.user.is_authenticated():
-                    raise exceptions.PermissionDenied
+                if request.user.has_perm('view_collection', obj=collection):
+                    raise exceptions.PermissionDenied(
+                        "You don't have `ADD` permission on collection (id: {}).".format(collection_id)
+                    )
                 else:
-                    raise exceptions.NotFound
+                    raise exceptions.NotFound(
+                        "Collection not found (id: {}).".format(collection_id)
+                    )
 
         # translate processe's slug to id
         process_slug = request.data.get('process', None)
diff --git a/resolwe/flow/views/mixins.py b/resolwe/flow/views/mixins.py
--- a/resolwe/flow/views/mixins.py
+++ b/resolwe/flow/views/mixins.py
@@ -4,6 +4,7 @@
 from django.db import IntegrityError, transaction
 
 from guardian.shortcuts import assign_perm
+from guardian.utils import get_anonymous_user
 from rest_framework import mixins, status
 from rest_framework.decorators import list_route
 from rest_framework.response import Response
@@ -38,7 +39,11 @@
                         'Invalid descriptor_schema slug "{}" - object does not exist.'.format(ds_slug)]},
                     status=status.HTTP_400_BAD_REQUEST)
 
-        request.data['contributor'] = request.user.pk
+        if request.user.is_anonymous():
+            request.data['contributor'] = get_anonymous_user().pk
+        else:
+            request.data['contributor'] = request.user.pk
+
         try:
             return super(ResolweCreateModelMixin, self).create(request, *args, **kwargs)

{"golden_diff": "diff --git a/resolwe/flow/views/data.py b/resolwe/flow/views/data.py\n--- a/resolwe/flow/views/data.py\n+++ b/resolwe/flow/views/data.py\n@@ -51,10 +51,14 @@\n                                 status=status.HTTP_400_BAD_REQUEST)\n \n             if not request.user.has_perm('add_collection', obj=collection):\n-                if request.user.is_authenticated():\n-                    raise exceptions.PermissionDenied\n+                if request.user.has_perm('view_collection', obj=collection):\n+                    raise exceptions.PermissionDenied(\n+                        \"You don't have `ADD` permission on collection (id: {}).\".format(collection_id)\n+                    )\n                 else:\n-                    raise exceptions.NotFound\n+                    raise exceptions.NotFound(\n+                        \"Collection not found (id: {}).\".format(collection_id)\n+                    )\n \n         # translate processe's slug to id\n         process_slug = request.data.get('process', None)\ndiff --git a/resolwe/flow/views/mixins.py b/resolwe/flow/views/mixins.py\n--- a/resolwe/flow/views/mixins.py\n+++ b/resolwe/flow/views/mixins.py\n@@ -4,6 +4,7 @@\n from django.db import IntegrityError, transaction\n \n from guardian.shortcuts import assign_perm\n+from guardian.utils import get_anonymous_user\n from rest_framework import mixins, status\n from rest_framework.decorators import list_route\n from rest_framework.response import Response\n@@ -38,7 +39,11 @@\n                         'Invalid descriptor_schema slug \"{}\" - object does not exist.'.format(ds_slug)]},\n                     status=status.HTTP_400_BAD_REQUEST)\n \n-        request.data['contributor'] = request.user.pk\n+        if request.user.is_anonymous():\n+            request.data['contributor'] = get_anonymous_user().pk\n+        else:\n+            request.data['contributor'] = request.user.pk\n+\n         try:\n             return super(ResolweCreateModelMixin, self).create(request, *args, **kwargs)\n", "issue": "Data.create returns bad message when missing ADD permission on collection\nIf a user tries to run a process inside a collection, but doesn't have `ADD` permission, the api returns `{\"detail\":\"Not found.\"}`\n", "before_files": [{"content": "\"\"\"Mixins used in Resolwe Viewsets.\"\"\"\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nfrom django.db import IntegrityError, transaction\n\nfrom guardian.shortcuts import assign_perm\nfrom rest_framework import mixins, status\nfrom rest_framework.decorators import list_route\nfrom rest_framework.response import Response\n\nfrom resolwe.flow.models import DescriptorSchema\nfrom resolwe.permissions.shortcuts import get_objects_for_user\n\n\nclass ResolweCreateModelMixin(mixins.CreateModelMixin):\n    \"\"\"Mixin to support creating new `Resolwe` models.\n\n    Extends `django_rest_framework`'s class `CreateModelMixin` with:\n\n      * append user's id from request to posted data as `contributor`\n        key\n      * catch `IntegrityError`s, so we can return HTTP status 409\n        instead of raising error\n\n    \"\"\"\n\n    def create(self, request, *args, **kwargs):\n        \"\"\"Create a resource.\"\"\"\n        ds_slug = request.data.get('descriptor_schema', None)\n        if ds_slug:\n            ds_query = DescriptorSchema.objects.filter(slug=ds_slug)\n            ds_query = get_objects_for_user(request.user, 'view_descriptorschema', ds_query)\n            try:\n                request.data['descriptor_schema'] = ds_query.latest().pk\n            except DescriptorSchema.DoesNotExist:\n                return Response(\n                    {'descriptor_schema': [\n                        'Invalid descriptor_schema slug \"{}\" - object does not exist.'.format(ds_slug)]},\n                    status=status.HTTP_400_BAD_REQUEST)\n\n        request.data['contributor'] = request.user.pk\n        try:\n            return super(ResolweCreateModelMixin, self).create(request, *args, **kwargs)\n\n        except IntegrityError as ex:\n            return Response({u'error': str(ex)}, status=status.HTTP_409_CONFLICT)\n\n    def perform_create(self, serializer):\n        \"\"\"Create a resource.\"\"\"\n        with transaction.atomic():\n            instance = serializer.save()\n\n            # Assign all permissions to the object contributor.\n            for permission in list(zip(*instance._meta.permissions))[0]:  # pylint: disable=protected-access\n                assign_perm(permission, instance.contributor, instance)\n\n\nclass ResolweUpdateModelMixin(mixins.UpdateModelMixin):\n    \"\"\"Mixin to support updating `Resolwe` models.\n\n    Extends `django_rest_framework`'s class `UpdateModelMixin` with:\n\n      * translate `descriptor_schema` field from DescriptorSchema's\n        slug to its id and return 400 error Response if it doesn't\n        exists\n\n    \"\"\"\n\n    def update(self, request, *args, **kwargs):\n        \"\"\"Update a resource.\"\"\"\n        ds_slug = request.data.get('descriptor_schema', None)\n        if ds_slug:\n            ds_query = DescriptorSchema.objects.filter(slug=ds_slug)\n            ds_query = get_objects_for_user(request.user, 'view_descriptorschema', ds_query)\n            try:\n                request.data['descriptor_schema'] = ds_query.latest().pk\n            except DescriptorSchema.DoesNotExist:\n                return Response(\n                    {'descriptor_schema': [\n                        'Invalid descriptor_schema slug \"{}\" - object does not exist.'.format(ds_slug)]},\n                    status=status.HTTP_400_BAD_REQUEST)\n\n        return super(ResolweUpdateModelMixin, self).update(request, *args, **kwargs)\n\n\nclass ResolweCheckSlugMixin(object):\n    \"\"\"Slug validation.\"\"\"\n\n    @list_route(methods=[u'get'])\n    def slug_exists(self, request):\n        \"\"\"Check if given url slug exists.\n\n        Check if slug given in query parameter ``name`` exists. Return\n        ``True`` if slug already exists and ``False`` otherwise.\n\n        \"\"\"\n        if not request.user.is_authenticated():\n            return Response(status=status.HTTP_401_UNAUTHORIZED)\n\n        if 'name' not in request.query_params:\n            return Response({'error': 'Query parameter `name` must be given.'},\n                            status=status.HTTP_400_BAD_REQUEST)\n\n        queryset = self.get_queryset()\n        slug_name = request.query_params['name']\n        return Response(queryset.filter(slug__iexact=slug_name).exists())\n", "path": "resolwe/flow/views/mixins.py"}, {"content": "\"\"\"Data viewset.\"\"\"\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nfrom django.db import transaction\n\nfrom guardian.shortcuts import assign_perm\nfrom rest_framework import exceptions, mixins, status, viewsets\nfrom rest_framework.decorators import list_route\nfrom rest_framework.response import Response\n\nfrom resolwe.flow.filters import DataFilter\nfrom resolwe.flow.managers import manager\nfrom resolwe.flow.models import Collection, Data, Process\nfrom resolwe.flow.serializers import DataSerializer\nfrom resolwe.flow.utils import dict_dot, get_data_checksum, iterate_schema\nfrom resolwe.permissions.loader import get_permissions_class\nfrom resolwe.permissions.mixins import ResolwePermissionsMixin\nfrom resolwe.permissions.shortcuts import get_objects_for_user\n\nfrom .mixins import ResolweCheckSlugMixin, ResolweCreateModelMixin, ResolweUpdateModelMixin\n\n\nclass DataViewSet(ResolweCreateModelMixin,\n                  mixins.RetrieveModelMixin,\n                  ResolweUpdateModelMixin,\n                  mixins.DestroyModelMixin,\n                  mixins.ListModelMixin,\n                  ResolwePermissionsMixin,\n                  ResolweCheckSlugMixin,\n                  viewsets.GenericViewSet):\n    \"\"\"API view for :class:`Data` objects.\"\"\"\n\n    queryset = Data.objects.all().prefetch_related('process', 'descriptor_schema', 'contributor')\n    serializer_class = DataSerializer\n    permission_classes = (get_permissions_class(),)\n    filter_class = DataFilter\n    ordering_fields = ('id', 'created', 'modified', 'started', 'finished', 'name')\n    ordering = ('id',)\n\n    def create(self, request, *args, **kwargs):\n        \"\"\"Create a resource.\"\"\"\n        collections = request.data.get('collections', [])\n\n        # check that user has permissions on all collections that Data\n        # object will be added to\n        for collection_id in collections:\n            try:\n                collection = Collection.objects.get(pk=collection_id)\n            except Collection.DoesNotExist:\n                return Response({'collections': ['Invalid pk \"{}\" - object does not exist.'.format(collection_id)]},\n                                status=status.HTTP_400_BAD_REQUEST)\n\n            if not request.user.has_perm('add_collection', obj=collection):\n                if request.user.is_authenticated():\n                    raise exceptions.PermissionDenied\n                else:\n                    raise exceptions.NotFound\n\n        # translate processe's slug to id\n        process_slug = request.data.get('process', None)\n        process_query = Process.objects.filter(slug=process_slug)\n        process_query = get_objects_for_user(request.user, 'view_process', process_query)\n        try:\n            process = process_query.latest()\n        except Process.DoesNotExist:\n            return Response({'process': ['Invalid process slug \"{}\" - object does not exist.'.format(process_slug)]},\n                            status=status.HTTP_400_BAD_REQUEST)\n        request.data['process'] = process.pk\n\n        # perform \"get_or_create\" if requested - return existing object\n        # if found\n        if kwargs.pop('get_or_create', False):\n            process_input = request.data.get('input', {})\n\n            # use default values if they are not given\n            for field_schema, fields, path in iterate_schema(process_input, process.input_schema):\n                if 'default' in field_schema and field_schema['name'] not in fields:\n                    dict_dot(process_input, path, field_schema['default'])\n\n            checksum = get_data_checksum(process_input, process.slug, process.version)\n            data_qs = Data.objects.filter(\n                checksum=checksum,\n                process__persistence__in=[Process.PERSISTENCE_CACHED, Process.PERSISTENCE_TEMP],\n            )\n            data_qs = get_objects_for_user(request.user, 'view_data', data_qs)\n            if data_qs.exists():\n                data = data_qs.order_by('created').last()\n                serializer = self.get_serializer(data)\n                return Response(serializer.data)\n\n        # create the objects\n        resp = super(DataViewSet, self).create(request, *args, **kwargs)\n\n        # run manager\n        manager.communicate()\n\n        return resp\n\n    @list_route(methods=[u'post'])\n    def get_or_create(self, request, *args, **kwargs):\n        \"\"\"Get ``Data`` object if similar already exists, otherwise create it.\"\"\"\n        kwargs['get_or_create'] = True\n        return self.create(request, *args, **kwargs)\n\n    def perform_create(self, serializer):\n        \"\"\"Create a resource.\"\"\"\n        with transaction.atomic():\n            instance = serializer.save()\n\n            # Assign all permissions to the object contributor.\n            for permission in list(zip(*instance._meta.permissions))[0]:  # pylint: disable=protected-access\n                assign_perm(permission, instance.contributor, instance)\n\n            # Assign data object to all specified collections.\n            collections = self.request.data.get('collections', [])\n            for c in collections:\n                collection = Collection.objects.get(pk=c)\n                collection.data.add(instance)\n", "path": "resolwe/flow/views/data.py"}], "after_files": [{"content": "\"\"\"Mixins used in Resolwe Viewsets.\"\"\"\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nfrom django.db import IntegrityError, transaction\n\nfrom guardian.shortcuts import assign_perm\nfrom guardian.utils import get_anonymous_user\nfrom rest_framework import mixins, status\nfrom rest_framework.decorators import list_route\nfrom rest_framework.response import Response\n\nfrom resolwe.flow.models import DescriptorSchema\nfrom resolwe.permissions.shortcuts import get_objects_for_user\n\n\nclass ResolweCreateModelMixin(mixins.CreateModelMixin):\n    \"\"\"Mixin to support creating new `Resolwe` models.\n\n    Extends `django_rest_framework`'s class `CreateModelMixin` with:\n\n      * append user's id from request to posted data as `contributor`\n        key\n      * catch `IntegrityError`s, so we can return HTTP status 409\n        instead of raising error\n\n    \"\"\"\n\n    def create(self, request, *args, **kwargs):\n        \"\"\"Create a resource.\"\"\"\n        ds_slug = request.data.get('descriptor_schema', None)\n        if ds_slug:\n            ds_query = DescriptorSchema.objects.filter(slug=ds_slug)\n            ds_query = get_objects_for_user(request.user, 'view_descriptorschema', ds_query)\n            try:\n                request.data['descriptor_schema'] = ds_query.latest().pk\n            except DescriptorSchema.DoesNotExist:\n                return Response(\n                    {'descriptor_schema': [\n                        'Invalid descriptor_schema slug \"{}\" - object does not exist.'.format(ds_slug)]},\n                    status=status.HTTP_400_BAD_REQUEST)\n\n        if request.user.is_anonymous():\n            request.data['contributor'] = get_anonymous_user().pk\n        else:\n            request.data['contributor'] = request.user.pk\n\n        try:\n            return super(ResolweCreateModelMixin, self).create(request, *args, **kwargs)\n\n        except IntegrityError as ex:\n            return Response({u'error': str(ex)}, status=status.HTTP_409_CONFLICT)\n\n    def perform_create(self, serializer):\n        \"\"\"Create a resource.\"\"\"\n        with transaction.atomic():\n            instance = serializer.save()\n\n            # Assign all permissions to the object contributor.\n            for permission in list(zip(*instance._meta.permissions))[0]:  # pylint: disable=protected-access\n                assign_perm(permission, instance.contributor, instance)\n\n\nclass ResolweUpdateModelMixin(mixins.UpdateModelMixin):\n    \"\"\"Mixin to support updating `Resolwe` models.\n\n    Extends `django_rest_framework`'s class `UpdateModelMixin` with:\n\n      * translate `descriptor_schema` field from DescriptorSchema's\n        slug to its id and return 400 error Response if it doesn't\n        exists\n\n    \"\"\"\n\n    def update(self, request, *args, **kwargs):\n        \"\"\"Update a resource.\"\"\"\n        ds_slug = request.data.get('descriptor_schema', None)\n        if ds_slug:\n            ds_query = DescriptorSchema.objects.filter(slug=ds_slug)\n            ds_query = get_objects_for_user(request.user, 'view_descriptorschema', ds_query)\n            try:\n                request.data['descriptor_schema'] = ds_query.latest().pk\n            except DescriptorSchema.DoesNotExist:\n                return Response(\n                    {'descriptor_schema': [\n                        'Invalid descriptor_schema slug \"{}\" - object does not exist.'.format(ds_slug)]},\n                    status=status.HTTP_400_BAD_REQUEST)\n\n        return super(ResolweUpdateModelMixin, self).update(request, *args, **kwargs)\n\n\nclass ResolweCheckSlugMixin(object):\n    \"\"\"Slug validation.\"\"\"\n\n    @list_route(methods=[u'get'])\n    def slug_exists(self, request):\n        \"\"\"Check if given url slug exists.\n\n        Check if slug given in query parameter ``name`` exists. Return\n        ``True`` if slug already exists and ``False`` otherwise.\n\n        \"\"\"\n        if not request.user.is_authenticated():\n            return Response(status=status.HTTP_401_UNAUTHORIZED)\n\n        if 'name' not in request.query_params:\n            return Response({'error': 'Query parameter `name` must be given.'},\n                            status=status.HTTP_400_BAD_REQUEST)\n\n        queryset = self.get_queryset()\n        slug_name = request.query_params['name']\n        return Response(queryset.filter(slug__iexact=slug_name).exists())\n", "path": "resolwe/flow/views/mixins.py"}, {"content": "\"\"\"Data viewset.\"\"\"\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nfrom django.db import transaction\n\nfrom guardian.shortcuts import assign_perm\nfrom rest_framework import exceptions, mixins, status, viewsets\nfrom rest_framework.decorators import list_route\nfrom rest_framework.response import Response\n\nfrom resolwe.flow.filters import DataFilter\nfrom resolwe.flow.managers import manager\nfrom resolwe.flow.models import Collection, Data, Process\nfrom resolwe.flow.serializers import DataSerializer\nfrom resolwe.flow.utils import dict_dot, get_data_checksum, iterate_schema\nfrom resolwe.permissions.loader import get_permissions_class\nfrom resolwe.permissions.mixins import ResolwePermissionsMixin\nfrom resolwe.permissions.shortcuts import get_objects_for_user\n\nfrom .mixins import ResolweCheckSlugMixin, ResolweCreateModelMixin, ResolweUpdateModelMixin\n\n\nclass DataViewSet(ResolweCreateModelMixin,\n                  mixins.RetrieveModelMixin,\n                  ResolweUpdateModelMixin,\n                  mixins.DestroyModelMixin,\n                  mixins.ListModelMixin,\n                  ResolwePermissionsMixin,\n                  ResolweCheckSlugMixin,\n                  viewsets.GenericViewSet):\n    \"\"\"API view for :class:`Data` objects.\"\"\"\n\n    queryset = Data.objects.all().prefetch_related('process', 'descriptor_schema', 'contributor')\n    serializer_class = DataSerializer\n    permission_classes = (get_permissions_class(),)\n    filter_class = DataFilter\n    ordering_fields = ('id', 'created', 'modified', 'started', 'finished', 'name')\n    ordering = ('id',)\n\n    def create(self, request, *args, **kwargs):\n        \"\"\"Create a resource.\"\"\"\n        collections = request.data.get('collections', [])\n\n        # check that user has permissions on all collections that Data\n        # object will be added to\n        for collection_id in collections:\n            try:\n                collection = Collection.objects.get(pk=collection_id)\n            except Collection.DoesNotExist:\n                return Response({'collections': ['Invalid pk \"{}\" - object does not exist.'.format(collection_id)]},\n                                status=status.HTTP_400_BAD_REQUEST)\n\n            if not request.user.has_perm('add_collection', obj=collection):\n                if request.user.has_perm('view_collection', obj=collection):\n                    raise exceptions.PermissionDenied(\n                        \"You don't have `ADD` permission on collection (id: {}).\".format(collection_id)\n                    )\n                else:\n                    raise exceptions.NotFound(\n                        \"Collection not found (id: {}).\".format(collection_id)\n                    )\n\n        # translate processe's slug to id\n        process_slug = request.data.get('process', None)\n        process_query = Process.objects.filter(slug=process_slug)\n        process_query = get_objects_for_user(request.user, 'view_process', process_query)\n        try:\n            process = process_query.latest()\n        except Process.DoesNotExist:\n            return Response({'process': ['Invalid process slug \"{}\" - object does not exist.'.format(process_slug)]},\n                            status=status.HTTP_400_BAD_REQUEST)\n        request.data['process'] = process.pk\n\n        # perform \"get_or_create\" if requested - return existing object\n        # if found\n        if kwargs.pop('get_or_create', False):\n            process_input = request.data.get('input', {})\n\n            # use default values if they are not given\n            for field_schema, fields, path in iterate_schema(process_input, process.input_schema):\n                if 'default' in field_schema and field_schema['name'] not in fields:\n                    dict_dot(process_input, path, field_schema['default'])\n\n            checksum = get_data_checksum(process_input, process.slug, process.version)\n            data_qs = Data.objects.filter(\n                checksum=checksum,\n                process__persistence__in=[Process.PERSISTENCE_CACHED, Process.PERSISTENCE_TEMP],\n            )\n            data_qs = get_objects_for_user(request.user, 'view_data', data_qs)\n            if data_qs.exists():\n                data = data_qs.order_by('created').last()\n                serializer = self.get_serializer(data)\n                return Response(serializer.data)\n\n        # create the objects\n        resp = super(DataViewSet, self).create(request, *args, **kwargs)\n\n        # run manager\n        manager.communicate()\n\n        return resp\n\n    @list_route(methods=[u'post'])\n    def get_or_create(self, request, *args, **kwargs):\n        \"\"\"Get ``Data`` object if similar already exists, otherwise create it.\"\"\"\n        kwargs['get_or_create'] = True\n        return self.create(request, *args, **kwargs)\n\n    def perform_create(self, serializer):\n        \"\"\"Create a resource.\"\"\"\n        with transaction.atomic():\n            instance = serializer.save()\n\n            # Assign all permissions to the object contributor.\n            for permission in list(zip(*instance._meta.permissions))[0]:  # pylint: disable=protected-access\n                assign_perm(permission, instance.contributor, instance)\n\n            # Assign data object to all specified collections.\n            collections = self.request.data.get('collections', [])\n            for c in collections:\n                collection = Collection.objects.get(pk=c)\n                collection.data.add(instance)\n", "path": "resolwe/flow/views/data.py"}]}