From 0e8d9aa45d1950444d12432c8d21ea5c418d4d1e Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sun, 30 May 2021 13:56:43 +0200 Subject: [PATCH] api: add System info API Signed-off-by: Jens Langhammer --- authentik/admin/api/system.py | 90 +++++++++++++++++++++++++++++++ authentik/admin/tests/test_api.py | 5 ++ authentik/api/v2/urls.py | 2 + schema.yml | 65 ++++++++++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 authentik/admin/api/system.py diff --git a/authentik/admin/api/system.py b/authentik/admin/api/system.py new file mode 100644 index 000000000..42cbe7c5e --- /dev/null +++ b/authentik/admin/api/system.py @@ -0,0 +1,90 @@ +"""authentik administration overview""" +import os +import platform +from datetime import datetime +from sys import version as python_version +from typing import TypedDict + +from django.utils.timezone import now +from drf_spectacular.utils import extend_schema +from gunicorn import version_info as gunicorn_version +from rest_framework.fields import SerializerMethodField +from rest_framework.permissions import IsAdminUser +from rest_framework.request import Request +from rest_framework.response import Response +from rest_framework.views import APIView + +from authentik.core.api.utils import PassiveSerializer + + +class RuntimeDict(TypedDict): + """Runtime information""" + + python_version: str + gunicorn_version: str + environment: str + architecture: str + platform: str + uname: str + + +class SystemSerializer(PassiveSerializer): + """Get system information.""" + + http_headers = SerializerMethodField() + http_host = SerializerMethodField() + http_is_secure = SerializerMethodField() + runtime = SerializerMethodField() + tenant = SerializerMethodField() + server_time = SerializerMethodField() + + def get_http_headers(self, request: Request) -> dict[str, str]: + """Get HTTP Request headers""" + headers = {} + for key, value in request.META.items(): + if not isinstance(value, str): + continue + headers[key] = value + return headers + + def get_http_host(self, request: Request) -> str: + """Get HTTP host""" + return request._request.get_host() + + def get_http_is_secure(self, request: Request) -> bool: + """Get HTTP Secure flag""" + return request._request.is_secure() + + def get_runtime(self, request: Request) -> RuntimeDict: + """Get versions""" + return { + "python_version": python_version, + "gunicorn_version": ".".join(str(x) for x in gunicorn_version), + "environment": "kubernetes" + if "KUBERNETES_PORT" in os.environ + else "compose", + "architecture": platform.machine(), + "platform": platform.platform(), + "uname": " ".join(platform.uname()), + } + + def get_tenant(self, request: Request) -> str: + """Currently active tenant""" + return str(request._request.tenant) + + def get_server_time(self, request: Request) -> datetime: + """Current server time""" + return now() + + +class SystemView(APIView): + """Get system information.""" + + permission_classes = [IsAdminUser] + pagination_class = None + filter_backends = [] + + @extend_schema(responses={200: SystemSerializer(many=False)}) + def get(self, request: Request) -> Response: + """Get system information.""" + return Response(SystemSerializer(request).data) diff --git a/authentik/admin/tests/test_api.py b/authentik/admin/tests/test_api.py index 75e1dac2b..dbcbd647b 100644 --- a/authentik/admin/tests/test_api.py +++ b/authentik/admin/tests/test_api.py @@ -95,3 +95,8 @@ class TestAdminAPI(TestCase): """Test apps API""" response = self.client.get(reverse("authentik_api:apps-list")) self.assertEqual(response.status_code, 200) + + def test_system(self): + """Test system API""" + response = self.client.get(reverse("authentik_api:admin_system")) + self.assertEqual(response.status_code, 200) diff --git a/authentik/api/v2/urls.py b/authentik/api/v2/urls.py index dade31d5e..59502c174 100644 --- a/authentik/api/v2/urls.py +++ b/authentik/api/v2/urls.py @@ -5,6 +5,7 @@ from rest_framework import routers from authentik.admin.api.meta import AppsViewSet from authentik.admin.api.metrics import AdministrationMetricsViewSet +from authentik.admin.api.system import SystemView from authentik.admin.api.tasks import TaskViewSet from authentik.admin.api.version import VersionView from authentik.admin.api.workers import WorkerView @@ -225,6 +226,7 @@ urlpatterns = ( ), path("admin/version/", VersionView.as_view(), name="admin_version"), path("admin/workers/", WorkerView.as_view(), name="admin_workers"), + path("admin/system/", SystemView.as_view(), name="admin_system"), path("root/config/", ConfigView.as_view(), name="config"), path( "flows/executor//", diff --git a/schema.yml b/schema.yml index db673fce4..834bf270b 100644 --- a/schema.yml +++ b/schema.yml @@ -51,6 +51,26 @@ paths: $ref: '#/components/schemas/ValidationError' '403': $ref: '#/components/schemas/GenericError' + /api/v2beta/admin/system/: + get: + operationId: admin_system_retrieve + description: Get system information. + tags: + - admin + security: + - authentik: [] + - cookieAuth: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/System' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' /api/v2beta/admin/system_tasks/: get: operationId: admin_system_tasks_list @@ -24808,6 +24828,51 @@ components: - user_email - user_upn type: string + System: + type: object + description: Get system information. + properties: + http_headers: + type: object + additionalProperties: + type: string + readOnly: true + http_host: + type: string + readOnly: true + http_is_secure: + type: boolean + readOnly: true + runtime: + type: object + properties: + python_version: + type: string + gunicorn_version: + type: string + environment: + type: string + architecture: + type: string + platform: + type: string + uname: + type: string + readOnly: true + tenant: + type: string + readOnly: true + server_time: + type: string + format: date-time + readOnly: true + required: + - http_headers + - http_host + - http_is_secure + - runtime + - server_time + - tenant TOTPDevice: type: object description: Serializer for totp authenticator devices