[Patchew-devel] [PATCH 13/17] rest: allow accessing the configuration via the REST API

Paolo Bonzini posted 17 patches 2 years, 6 months ago

[Patchew-devel] [PATCH 13/17] rest: allow accessing the configuration via the REST API

Posted by Paolo Bonzini 2 years, 6 months ago
Add a new endpoint /projects/ID/config/ that allows retrieving and setting the
project's module configuration.  The endpoint is only accessible to maintainers,
because it could contain secrets.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 api/rest.py        | 18 +++++++++++++++++-
 tests/test_rest.py | 30 ++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/api/rest.py b/api/rest.py
index 041e82d..982cb6e 100644
--- a/api/rest.py
+++ b/api/rest.py
@@ -46,6 +46,9 @@ class PatchewPermission(permissions.BasePermission):
     def is_superuser(self, request):
         return request.user and request.user.is_superuser
 
+    def is_safe_method(self, request):
+        return request.method in permissions.SAFE_METHODS
+
     def has_project_permission(self, request, view, obj):
         return obj.maintained_by(request.user)
 
@@ -56,7 +59,7 @@ class PatchewPermission(permissions.BasePermission):
         return False
 
     def has_generic_permission(self, request, view):
-        return (request.method in permissions.SAFE_METHODS) or \
+        return self.is_safe_method(request) or \
             self.is_superuser(request) or \
             self.has_group_permission(request, view, self.allowed_groups)
 
@@ -93,6 +96,11 @@ class PatchewPermission(permissions.BasePermission):
             self.has_project_permission(request, view, obj)
 
 
+class MaintainerPermission(PatchewPermission):
+    def is_safe_method(self, request):
+        return False
+
+
 class ImportPermission(PatchewPermission):
     allowed_groups = ('importers',)
 
@@ -198,6 +206,14 @@ class ProjectsViewSet(viewsets.ModelViewSet):
     serializer_class = ProjectSerializer
     permission_classes = (PatchewPermission,)
 
+    @action(methods=['get', 'put'], detail=True, permission_classes=[MaintainerPermission])
+    def config(self, request, pk=None):
+        project = self.get_object()
+        if request.method == 'PUT':
+            project.config = request.data
+            project.save()
+        return Response(project.config)
+
     @action(methods=['post'], detail=True, permission_classes=[ImportPermission])
     def update_project_head(self, request, pk=None):
         """
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 4ed9c07..906f651 100755
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -92,6 +92,36 @@ class RestTest(PatchewTestCase):
         self.assertEquals(resp.data['name'], "QEMU")
         self.assertEquals(resp.data['mailing_list'], "qemu-devel@nongnu.org")
 
+    def test_project_config_get(self):
+        self.p.config = {
+            "git": {
+                "push_to": "/tmp/aaa"
+            }
+        }
+        self.p.save()
+        resp = self.api_client.get(self.PROJECT_BASE + 'config/')
+        self.assertEquals(resp.status_code, 403)
+        self.api_client.login(username=self.user, password=self.password)
+        resp = self.api_client.get(self.PROJECT_BASE + 'config/')
+        self.assertEquals(resp.status_code, 200)
+        self.assertEquals(resp.data['git']['push_to'], '/tmp/aaa')
+
+    def test_project_config_put(self):
+        new_config = {
+            "git": {
+                "push_to": "/tmp/bbb"
+            }
+        }
+        resp = self.api_client.put(self.PROJECT_BASE + 'config/', new_config, format='json')
+        self.assertEquals(resp.status_code, 403)
+        self.api_client.login(username=self.user, password=self.password)
+        resp = self.api_client.put(self.PROJECT_BASE + 'config/', new_config, format='json')
+        self.assertEquals(resp.status_code, 200)
+        self.assertEquals(resp.data['git']['push_to'], '/tmp/bbb')
+        resp = self.api_client.get(self.PROJECT_BASE + 'config/')
+        self.assertEquals(resp.status_code, 200)
+        self.assertEquals(resp.data['git']['push_to'], '/tmp/bbb')
+
     def test_update_project_head(self):
         resp = self.apply_and_retrieve('0001-simple-patch.mbox.gz',
                                        self.p.id, '20160628014747.20971-1-famz@redhat.com')
-- 
2.21.0


_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel