1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 11:16:47 +00:00
webvirtcloud/webvirtcloud/urls.py
catborise 401c648944 fix(webvirtcloud): the API and browsable login cannot bypass OTP with a password
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.
2026-10-07 09:57:40 +03:00

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