From 13c5219d715bb3c327c3b9f3d19f64647e5b774e Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Thu, 17 May 2018 23:39:34 +0200
Subject: [PATCH] See #206: added API endpoint for managing settings

---
 api/funkwhale_api/instance/urls.py  |  6 ++++--
 api/funkwhale_api/instance/views.py |  5 +++++
 api/funkwhale_api/users/models.py   |  6 +++++-
 api/tests/instance/test_views.py    | 28 ++++++++++++++++++++++++++++
 4 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/api/funkwhale_api/instance/urls.py b/api/funkwhale_api/instance/urls.py
index f506488f..7992842c 100644
--- a/api/funkwhale_api/instance/urls.py
+++ b/api/funkwhale_api/instance/urls.py
@@ -1,9 +1,11 @@
 from django.conf.urls import url
+from rest_framework import routers
 
 from . import views
-
+admin_router = routers.SimpleRouter()
+admin_router.register(r'admin/settings', views.AdminSettings, 'admin-settings')
 
 urlpatterns = [
     url(r'^nodeinfo/2.0/$', views.NodeInfo.as_view(), name='nodeinfo-2.0'),
     url(r'^settings/$', views.InstanceSettings.as_view(), name='settings'),
-]
+] + admin_router.urls
diff --git a/api/funkwhale_api/instance/views.py b/api/funkwhale_api/instance/views.py
index 5953ca55..e6725e24 100644
--- a/api/funkwhale_api/instance/views.py
+++ b/api/funkwhale_api/instance/views.py
@@ -2,6 +2,7 @@ from rest_framework import views
 from rest_framework.response import Response
 
 from dynamic_preferences.api import serializers
+from dynamic_preferences.api import viewsets as preferences_viewsets
 from dynamic_preferences.registries import global_preferences_registry
 
 from funkwhale_api.common import preferences
@@ -15,6 +16,10 @@ NODEINFO_2_CONTENT_TYPE = (
 )
 
 
+class AdminSettings(preferences_viewsets.GlobalPreferencesViewSet):
+    pagination_class = None
+
+
 class InstanceSettings(views.APIView):
     permission_classes = []
     authentication_classes = []
diff --git a/api/funkwhale_api/users/models.py b/api/funkwhale_api/users/models.py
index f067a2a8..8273507c 100644
--- a/api/funkwhale_api/users/models.py
+++ b/api/funkwhale_api/users/models.py
@@ -6,7 +6,7 @@ import os
 import uuid
 
 from django.conf import settings
-from django.contrib.auth.models import AbstractUser
+from django.contrib.auth.models import AbstractUser, Permission
 from django.urls import reverse
 from django.db import models
 from django.utils.encoding import python_2_unicode_compatible
@@ -55,6 +55,10 @@ class User(AbstractUser):
     def __str__(self):
         return self.username
 
+    def add_permission(self, codename):
+        p = Permission.objects.get(codename=codename)
+        self.user_permissions.add(p)
+
     def get_absolute_url(self):
         return reverse('users:detail', kwargs={'username': self.username})
 
diff --git a/api/tests/instance/test_views.py b/api/tests/instance/test_views.py
index 468c0dda..6d8dcac3 100644
--- a/api/tests/instance/test_views.py
+++ b/api/tests/instance/test_views.py
@@ -21,3 +21,31 @@ def test_nodeinfo_endpoint_disabled(db, api_client, preferences):
     response = api_client.get(url)
 
     assert response.status_code == 404
+
+
+def test_settings_only_list_public_settings(db, api_client, preferences):
+    url = reverse('api:v1:instance:settings')
+    response = api_client.get(url)
+
+    for conf in response.data:
+        p = preferences.model.objects.get(
+            section=conf['section'], name=conf['name'])
+        assert p.preference.show_in_api is True
+
+
+def test_admin_settings_restrict_access(db, logged_in_api_client, preferences):
+    url = reverse('api:v1:instance:admin-settings-list')
+    response = logged_in_api_client.get(url)
+
+    assert response.status_code == 403
+
+
+def test_admin_settings_correct_permission(
+        db, logged_in_api_client, preferences):
+    user = logged_in_api_client.user
+    user.add_permission('change_globalpreferencemodel')
+    url = reverse('api:v1:instance:admin-settings-list')
+    response = logged_in_api_client.get(url)
+
+    assert response.status_code == 200
+    assert len(response.data) == len(preferences.all())
-- 
GitLab