From 03bfef6061c4b5dd2e69c245e5d5f98f1b3c07a9 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 20 Aug 2024 10:20:32 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(backend)=20add=20public=20endpoint=20?= =?UTF-8?q?/api/v1.0/config/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add public endpoint /api/v1.0/config/ to share some public configuration values with the frontend. --- src/backend/core/api/viewsets.py | 21 ++++++++++++ src/backend/core/tests/test_api_config.py | 39 +++++++++++++++++++++++ src/backend/people/api_urls.py | 1 + src/backend/people/settings.py | 6 ++++ 4 files changed, 67 insertions(+) create mode 100644 src/backend/core/tests/test_api_config.py diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index 75f10be..4603309 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -1,5 +1,6 @@ """API endpoints""" +from django.conf import settings from django.contrib.postgres.search import TrigramSimilarity from django.db.models import Func, Max, OuterRef, Q, Subquery, Value from django.db.models.functions import Coalesce @@ -12,8 +13,10 @@ from rest_framework import ( pagination, response, throttling, + views, viewsets, ) +from rest_framework.permissions import AllowAny from core import models @@ -491,3 +494,21 @@ class InvitationViewset( .distinct() ) return queryset + + +class ConfigView(views.APIView): + """API ViewSet for sharing some public settings.""" + + permission_classes = [AllowAny] + + def get(self, request): + """ + GET /api/v1.0/config/ + Return a dictionary of public settings. + """ + array_settings = ["LANGUAGES", "FEATURES"] + dict_settings = {} + for setting in array_settings: + dict_settings[setting] = getattr(settings, setting) + + return response.Response(dict_settings) diff --git a/src/backend/core/tests/test_api_config.py b/src/backend/core/tests/test_api_config.py new file mode 100644 index 0000000..16df9a4 --- /dev/null +++ b/src/backend/core/tests/test_api_config.py @@ -0,0 +1,39 @@ +""" +Test users API endpoints in the People core app. +""" + +import pytest +from rest_framework.status import ( + HTTP_200_OK, +) +from rest_framework.test import APIClient + +from core import factories + +pytestmark = pytest.mark.django_db + + +def test_api_config_anonymous(): + """Anonymous users should be allowed to get the configuration.""" + client = APIClient() + response = client.get("/api/v1.0/config/") + assert response.status_code == HTTP_200_OK + assert response.json() == { + "LANGUAGES": [["en-us", "English"], ["fr-fr", "French"]], + "FEATURES": {"TEAMS": True}, + } + + +def test_api_config_authenticated(): + """Authenticated users should be allowed to get the configuration.""" + user = factories.UserFactory() + + client = APIClient() + client.force_login(user) + + response = client.get("/api/v1.0/config/") + assert response.status_code == HTTP_200_OK + assert response.json() == { + "LANGUAGES": [["en-us", "English"], ["fr-fr", "French"]], + "FEATURES": {"TEAMS": True}, + } diff --git a/src/backend/people/api_urls.py b/src/backend/people/api_urls.py index 5d62fc7..4d0e7e1 100644 --- a/src/backend/people/api_urls.py +++ b/src/backend/people/api_urls.py @@ -44,4 +44,5 @@ urlpatterns = [ ), ), path(f"api/{settings.API_VERSION}/", include("mailbox_manager.urls")), + path(f"api/{settings.API_VERSION}/config/", viewsets.ConfigView.as_view()), ] diff --git a/src/backend/people/settings.py b/src/backend/people/settings.py index 1cb44e5..4e80bea 100755 --- a/src/backend/people/settings.py +++ b/src/backend/people/settings.py @@ -371,6 +371,12 @@ class Base(Configuration): environ_prefix=None, ) + FEATURES = { + "TEAMS": values.BooleanValue( + default=True, environ_name="FEATURE_TEAMS", environ_prefix=None + ), + } + # pylint: disable=invalid-name @property def ENVIRONMENT(self):