mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 11:16:47 +00:00
OTP (OTP_ENABLED) was enforced only by the HTML login form, but two other doors let an enrolled user authenticate with a password and no token, so a leaked password defeated the second factor. Both were reproduced with a confirmed TOTP device: /api-auth/login/ (DRF's browsable-API login) created a site-wide session, and DRF's default BasicAuthentication let every /api/v1/ endpoint accept HTTP Basic credentials. The api-auth/ include is removed, so the only interactive login is the OTP-aware form at /accounts/login/; the browsable API still works with the session that form sets. REST_FRAMEWORK now pins DEFAULT_AUTHENTICATION_CLASSES to SessionAuthentication only, so the API requires a session and no longer accepts a password over HTTP Basic. A session therefore implies the OTP factor was met. Password-based programmatic API access is intentionally dropped. The authorization matrix drops its rest_framework:login/logout allowlist entries (the routes are gone). New tests assert the browsable login route is removed, HTTP Basic is rejected on the API, Basic is not a default auth class, and a session still reaches the API. Verified live with OTP_ENABLED that /api-auth/login/ is 404 and an API Basic request is 403.
50 lines
1.9 KiB
Python
50 lines
1.9 KiB
Python
from django.conf import settings
|
|
from django.urls import include, path, re_path
|
|
from drf_spectacular.views import (
|
|
SpectacularAPIView,
|
|
SpectacularRedocView,
|
|
SpectacularSwaggerView,
|
|
)
|
|
from appsettings.views import appsettings
|
|
from console.views import console
|
|
from instances.views import index
|
|
|
|
# Fallback for existing installations where REST_FRAMEWORK.DEFAULT_SCHEMA_CLASS is not configured in settings.py
|
|
user_rf = getattr(settings, "REST_FRAMEWORK", None)
|
|
if not user_rf or "DEFAULT_SCHEMA_CLASS" not in user_rf:
|
|
try:
|
|
from rest_framework.settings import api_settings
|
|
from drf_spectacular.openapi import AutoSchema
|
|
|
|
api_settings.DEFAULT_SCHEMA_CLASS = AutoSchema
|
|
except (ImportError, AttributeError):
|
|
pass
|
|
|
|
urlpatterns = [
|
|
path("", index, name="index"),
|
|
path("admin/", include(("admin.urls", "admin"), namespace="admin")),
|
|
path("accounts/", include("accounts.urls")),
|
|
path("appsettings/", appsettings, name="appsettings"),
|
|
path("computes/", include("computes.urls")),
|
|
path("console/", console, name="console"),
|
|
path("datasource/", include("datasource.urls")),
|
|
path("instances/", include("instances.urls")),
|
|
path("i18n/", include("django.conf.urls.i18n")),
|
|
path("logs/", include("logs.urls")),
|
|
path('api/v1/', include("webvirtcloud.urls-api")),
|
|
path("api/schema/", SpectacularAPIView.as_view(), name="schema"),
|
|
re_path(r"^swagger\.(?P<format>json|yaml)$", SpectacularAPIView.as_view(), name="schema-json"),
|
|
path("swagger/", SpectacularSwaggerView.as_view(url_name="schema"), name="schema-swagger-ui"),
|
|
path("redoc/", SpectacularRedocView.as_view(url_name="schema"), name="schema-redoc"),
|
|
]
|
|
|
|
if settings.DEBUG:
|
|
try:
|
|
import debug_toolbar
|
|
|
|
urlpatterns += [
|
|
path("__debug__/", include(debug_toolbar.urls)),
|
|
]
|
|
except ImportError:
|
|
pass
|
|
|