From f081f2d228e54e7787cd74a58942eb79bfdafb73 Mon Sep 17 00:00:00 2001
From: James Graham <J.Graham@software.ac.uk>
Date: Fri, 26 Apr 2019 12:27:54 +0100
Subject: [PATCH] Add necessary permission checks to metadata item API
 endpoints

---
 api/permissions.py       | 14 ++++++++++++++
 api/views/datasources.py | 11 ++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/api/permissions.py b/api/permissions.py
index 2153980..fe1fbd3 100644
--- a/api/permissions.py
+++ b/api/permissions.py
@@ -87,3 +87,17 @@ class IsAdminOrReadOnly(permissions.BasePermission):
             request.method in permissions.SAFE_METHODS or
             request.user.is_superuser
         )
+
+
+class IsOwnerOrReadOnly(permissions.BasePermission):
+    """
+    Grant owner and admins write access - all others get read-only.
+    """
+    message = 'You do not have permission to access this resource.'
+
+    def has_permission(self, request, view):
+        return bool(
+            request.method in permissions.SAFE_METHODS or
+            view.get_datasource().owner == request.user or
+            request.user.is_superuser
+        )
diff --git a/api/views/datasources.py b/api/views/datasources.py
index a5d2f9c..713d1f1 100644
--- a/api/views/datasources.py
+++ b/api/views/datasources.py
@@ -21,15 +21,20 @@ from provenance import models as prov_models
 
 
 class MetadataItemApiViewset(viewsets.ModelViewSet):
+    """
+    API ViewSet for viewing and managing dynamic metadata items on a data sources.
+    """
     serializer_class = serializers.MetadataItemSerializer
-    permission_classes = [permissions.IsAdminOrReadOnly]
+    permission_classes = [permissions.IsOwnerOrReadOnly]
+
+    def get_datasource(self):
+        return get_object_or_404(models.DataSource, pk=self.kwargs['datasource_pk'])
 
     def get_queryset(self):
         return models.MetadataItem.objects.filter(datasource=self.kwargs['datasource_pk'])
 
     def perform_create(self, serializer):
-        datasource = get_object_or_404(models.DataSource, pk=self.kwargs['datasource_pk'])
-        serializer.save(datasource=datasource)
+        serializer.save(datasource=self.get_datasource())
 
 
 class DataSourceApiViewset(viewsets.ReadOnlyModelViewSet):
-- 
GitLab