diff --git a/requirements.txt b/requirements.txt index dcd823d0..440ea59e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -28,3 +28,5 @@ drf-spectacular==0.27.2 drf-spectacular-sidecar==2024.7.1 django-cors-headers==4.4.0 base91==1.0.1 +django-otp==1.5.0 +qrcode==7.4.2 diff --git a/robosats/settings.py b/robosats/settings.py index 555061f0..00f240cf 100644 --- a/robosats/settings.py +++ b/robosats/settings.py @@ -103,6 +103,8 @@ INSTALLED_APPS = [ "frontend", "drf_spectacular", "drf_spectacular_sidecar", # required for Django collectstatic discovery + "django_otp", + "django_otp.plugins.otp_totp", ] REST_FRAMEWORK = { @@ -154,6 +156,7 @@ MIDDLEWARE = [ "robosats.middleware.DisableCSRFMiddleware", "robosats.middleware.SplitAuthorizationHeaderMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", + "django_otp.middleware.OTPMiddleware", "robosats.middleware.RobotTokenSHA256AuthenticationMiddleWare", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", diff --git a/robosats/urls.py b/robosats/urls.py index 2a988cd4..c49b7ac5 100644 --- a/robosats/urls.py +++ b/robosats/urls.py @@ -15,19 +15,30 @@ Including another URLconf """ from decouple import config +from django.apps import apps from django.conf import settings -from django.contrib import admin from django.urls import include, path +from django_otp.admin import OTPAdminSite + + +class OTPAdmin(OTPAdminSite): + pass + + +admin_site = OTPAdmin(name="OTPAdmin") +for model in apps.get_models(): + admin_site.register(model) + VERSION = settings.VERSION urlpatterns = [ - path("coordinator/", admin.site.urls), + path("coordinator/", admin_site.urls), path("api/", include("api.urls")), # path('chat/', include('chat.urls')), path("", include("frontend.urls")), ] -admin.site.site_header = f"RoboSats Coordinator: {config('COORDINATOR_ALIAS', cast=str, default='NoAlias')} {config('NETWORK', cast=str, default='')} (v{VERSION['major']}.{VERSION['minor']}.{VERSION['patch']})".title() -admin.site.index_title = "Coordinator administration" -admin.site.site_title = "RoboSats Coordinator Admin" +admin_site.site_header = f"RoboSats Coordinator: {config('COORDINATOR_ALIAS', cast=str, default='NoAlias')} {config('NETWORK', cast=str, default='')} (v{VERSION['major']}.{VERSION['minor']}.{VERSION['patch']})".title() +admin_site.index_title = "Coordinator administration" +admin_site.site_title = "RoboSats Coordinator Admin"