From 841fa76ec0248f7bebe7c242ff9fa646f08cf35d Mon Sep 17 00:00:00 2001
From: Valentin Rigal <rigal@teklia.com>
Date: Tue, 17 Nov 2020 07:54:04 +0000
Subject: [PATCH] Set PonosAgentsState endpoint permission to verified users

---
 arkindex/project/openapi/patch.yml        | 14 ++++++++++
 arkindex/project/tests/test_ponos_view.py | 33 ++++++++++++++++++++++-
 arkindex/project/urls.py                  | 11 +++++++-
 arkindex/project/views.py                 | 17 +++++++++++-
 4 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/arkindex/project/openapi/patch.yml b/arkindex/project/openapi/patch.yml
index 60a825fc83..902dade7c6 100644
--- a/arkindex/project/openapi/patch.yml
+++ b/arkindex/project/openapi/patch.yml
@@ -433,3 +433,17 @@ paths:
       security: []
       tags:
         - ponos
+  /ponos/v1/agents/:
+    get:
+      description: List the state of all Ponos agents
+      operationId: ListAgentStates
+      security: []
+      tags:
+        - ponos
+  /ponos/v1/agent/{id}/:
+    get:
+      description: Retrieve details of a Ponos agent with a list of its running tasks
+      operationId: RetrieveAgent
+      security: []
+      tags:
+        - ponos
diff --git a/arkindex/project/tests/test_ponos_view.py b/arkindex/project/tests/test_ponos_view.py
index 28e66f133f..f81b0444c6 100644
--- a/arkindex/project/tests/test_ponos_view.py
+++ b/arkindex/project/tests/test_ponos_view.py
@@ -6,7 +6,7 @@ from django.urls import reverse
 from rest_framework import status
 
 from arkindex.users.models import User
-from ponos.models import Secret, encrypt
+from ponos.models import Agent, Farm, Secret, encrypt
 
 
 @override_settings(PONOS_PRIVATE_KEY='staging')
@@ -48,3 +48,34 @@ class TestPonosView(TestCase):
             self.client.force_login(user)
             response = self.client.get(reverse('secret-details', kwargs={"name": "secret/name"}))
             self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+
+    def test_list_agents(self):
+        """
+        Only authenticated users should have the ability to list agents
+        """
+        response = self.client.get(reverse('ponos-agents'))
+        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+
+        self.client.force_login(User.objects.create())
+        response = self.client.get(reverse('ponos-agents'))
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+
+    def test_retrieve_agent(self):
+        """
+        Only authenticated users should have the ability to retrieve details of an agent
+        """
+        agent = Agent.objects.create(
+            cpu_cores=3,
+            cpu_frequency=3e9,
+            gpu_count=0,
+            farm_id=Farm.objects.create().id,
+            ram_total=2e9,
+            last_ping='1999-09-09'
+        )
+
+        response = self.client.get(reverse('ponos-agent-details', kwargs={'pk': str(agent.id)}))
+        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+
+        self.client.force_login(User.objects.create())
+        response = self.client.get(reverse('ponos-agent-details', kwargs={'pk': str(agent.id)}))
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
diff --git a/arkindex/project/urls.py b/arkindex/project/urls.py
index 84b4803a3b..02f199ae58 100644
--- a/arkindex/project/urls.py
+++ b/arkindex/project/urls.py
@@ -4,7 +4,14 @@ from django.contrib.staticfiles.urls import staticfiles_urlpatterns
 from django.urls import include, path, re_path
 
 from arkindex.project.api_v1 import api
-from arkindex.project.views import CdnHome, FrontendView, OpenAPIDocsView, PonosSecretDetails
+from arkindex.project.views import (
+    CdnHome,
+    FrontendView,
+    OpenAPIDocsView,
+    PonosAgentDetails,
+    PonosAgentsState,
+    PonosSecretDetails,
+)
 
 # Fallback to the dummy frontend view when CDN_ASSETS_URL is not set
 frontend_view = FrontendView if settings.CDN_ASSETS_URL is None else CdnHome
@@ -14,6 +21,8 @@ urlpatterns = [
     path('api-docs/', OpenAPIDocsView.as_view(), name='openapi-docs'),
     # Override Ponos endpoints
     path('ponos/v1/secret/<path:name>', PonosSecretDetails.as_view(), name='secret-details'),
+    path('ponos/v1/agents/', PonosAgentsState.as_view(), name='ponos-agents'),
+    path('ponos/v1/agent/<uuid:pk>/', PonosAgentDetails.as_view(), name='ponos-agent-details'),
     path('ponos/', include('ponos.urls')),
     path('admin/', admin.site.urls),
     path('rq/', include('django_rq.urls')),
diff --git a/arkindex/project/views.py b/arkindex/project/views.py
index 384c5596b5..06fc7f2141 100644
--- a/arkindex/project/views.py
+++ b/arkindex/project/views.py
@@ -3,7 +3,8 @@ from django.views.generic import TemplateView, View
 from rest_framework import permissions
 
 from arkindex.project.mixins import CachedViewMixin
-from ponos.api import SecretDetails
+from arkindex.project.permissions import IsVerified
+from ponos.api import AgentDetails, AgentsState, SecretDetails
 
 
 class FrontendView(View):
@@ -51,3 +52,17 @@ class PonosSecretDetails(SecretDetails):
             return request.user.is_authenticated and request.user.is_internal
 
     permission_classes = (IsInternalOnly, )
+
+
+class PonosAgentsState(AgentsState):
+    """
+    Allow any verified user to see the state of Ponos agents on this instance
+    """
+    permission_classes = (IsVerified, )
+
+
+class PonosAgentDetails(AgentDetails):
+    """
+    Allow any verified user to see the details of an agent including all its running tasks
+    """
+    permission_classes = (IsVerified, )
-- 
GitLab