diff --git a/modoboa/admin/api.py b/modoboa/admin/api.py index 2c7ee274c..e9a334758 100644 --- a/modoboa/admin/api.py +++ b/modoboa/admin/api.py @@ -18,14 +18,13 @@ from . import lib, models, serializers class DomainViewSet(viewsets.ModelViewSet): """ - retrieve: - Return the given domain. + Domain viewset. - list: - Return a list of all existing domains. + retrieve: Return the given domain. - create: - Create a new domain instance. + list: Return a list of all existing domains. + + create: Create a new domain instance. """ permission_classes = [IsAuthenticated, DjangoModelPermissions, ] diff --git a/modoboa/admin/serializers.py b/modoboa/admin/serializers.py index 8a68d184e..2a66a020e 100644 --- a/modoboa/admin/serializers.py +++ b/modoboa/admin/serializers.py @@ -7,6 +7,8 @@ from django.shortcuts import get_object_or_404 from django.utils.encoding import force_text from django.utils.translation import ugettext as _, ugettext_lazy +from drf_spectacular.types import OpenApiTypes +from drf_spectacular.utils import extend_schema_field from rest_framework import serializers from modoboa.admin import models as admin_models @@ -186,6 +188,7 @@ class AccountSerializer(serializers.ModelSerializer): if not user.is_superuser: del self.fields["master_user"] + @extend_schema_field(OpenApiTypes.STR) def get_role(self, account): """Return role.""" return account.role diff --git a/modoboa/core/commands/templates/settings.py.tpl b/modoboa/core/commands/templates/settings.py.tpl index c604ca92b..243658309 100644 --- a/modoboa/core/commands/templates/settings.py.tpl +++ b/modoboa/core/commands/templates/settings.py.tpl @@ -64,6 +64,7 @@ INSTALLED_APPS = ( 'ckeditor_uploader', 'rest_framework', 'rest_framework.authtoken', + 'drf_spectacular', 'phonenumber_field', 'django_otp', 'django_otp.plugins.otp_totp', @@ -192,6 +193,12 @@ REST_FRAMEWORK = { ), } +SPECTACULAR_SETTINGS = { + 'SCHEMA_PATH_PREFIX': r'/api/v1', + 'TITLE': 'Modoboa API', + 'VERSION': '1.0.0' +} + # Modoboa settings # MODOBOA_CUSTOM_LOGO = os.path.join(MEDIA_URL, "custom_logo.png") diff --git a/modoboa/core/viewsets.py b/modoboa/core/viewsets.py index 177160688..1014c2e4d 100644 --- a/modoboa/core/viewsets.py +++ b/modoboa/core/viewsets.py @@ -7,6 +7,7 @@ from django_otp.plugins.otp_static.models import StaticDevice, StaticToken from django_otp.plugins.otp_totp.models import TOTPDevice from rest_framework import permissions, response, viewsets from rest_framework.decorators import action +from drf_spectacular.utils import extend_schema from . import serializers @@ -28,6 +29,9 @@ class AccountViewSet(viewsets.ViewSet): ) return response.Response() + @extend_schema( + request=serializers.CheckTFASetupSerializer + ) @action(methods=["post"], detail=False, url_path="tfa/setup/check") def tfa_setup_check(self, request): """Check TFA setup.""" @@ -57,6 +61,7 @@ class AccountViewSet(viewsets.ViewSet): request.user.save() return response.Response() + @extend_schema(tags=['account']) @action(methods=["post"], detail=False, url_path="tfa/reset_codes") def tfa_reset_codes(self, request, *args, **kwargs): """Reset recovery codes.""" diff --git a/modoboa/templates/swagger-ui.html b/modoboa/templates/swagger-ui.html deleted file mode 100644 index efbd02f35..000000000 --- a/modoboa/templates/swagger-ui.html +++ /dev/null @@ -1,57 +0,0 @@ - -{% load static %} - - - - - Modoboa API - - - - -
- - - - diff --git a/modoboa/urls.py b/modoboa/urls.py index d5a5390de..5e9e1deda 100644 --- a/modoboa/urls.py +++ b/modoboa/urls.py @@ -6,11 +6,9 @@ from django.conf import settings from django.contrib.auth import views as auth_views from django.contrib.auth.decorators import login_required from django.urls import include, path -from django.views.generic import TemplateView from django.views.i18n import JavaScriptCatalog -from rest_framework.renderers import JSONOpenAPIRenderer -from rest_framework.schemas import get_schema_view +from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView from modoboa.admin.views import user as user_views from modoboa.core import signals as core_signals, views as core_views @@ -59,17 +57,11 @@ if extra_routes: urlpatterns += extra_routes # API urls -schema_view = get_schema_view( - title="Modoboa API", - version="1.0.0", - public=False, - renderer_classes=[JSONOpenAPIRenderer], -) urlpatterns += [ - path('docs/openapi.json', schema_view, name="openapi_schema"), - path('docs/api/', login_required( - TemplateView.as_view(template_name="swagger-ui.html")), - name="docs-index"), + path('docs/openapi.json', SpectacularAPIView.as_view(), name='schema'), + path('docs/api/', + SpectacularSwaggerView.as_view(url_name='schema'), + name='docs-index'), path('api/v1/', include("modoboa.urls_api")), ] diff --git a/requirements.txt b/requirements.txt index 8242a5aea..485d9cf23 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,7 @@ django-otp==1.0.2 dj-database-url djangorestframework>=3.11,<3.12 +drf-spectacular uritemplate passlib~=1.7.4