2023-11-14 17:54:56 +01:00
|
|
|
from django.conf import settings
|
2023-12-04 13:04:35 +01:00
|
|
|
from ninja import Router as APIRouter, Field as APIField
|
2023-11-14 17:54:56 +01:00
|
|
|
from ninja import Schema
|
|
|
|
|
2023-12-04 13:04:35 +01:00
|
|
|
from c3nav.api.auth import APIKeyType, auth_responses
|
2023-11-19 00:12:10 +01:00
|
|
|
from c3nav.api.utils import NonEmptyStr
|
2023-12-02 01:31:58 +01:00
|
|
|
from c3nav.control.models import UserPermissions
|
2023-11-19 00:12:10 +01:00
|
|
|
|
2023-11-14 17:54:56 +01:00
|
|
|
auth_api_router = APIRouter(tags=["auth"])
|
|
|
|
|
|
|
|
|
2023-12-02 01:31:58 +01:00
|
|
|
class AuthStatusSchema(Schema):
|
|
|
|
"""
|
|
|
|
Current auth state and permissions
|
|
|
|
"""
|
2023-12-04 13:04:35 +01:00
|
|
|
key_type: APIKeyType = APIField(
|
|
|
|
title="api key type",
|
|
|
|
)
|
|
|
|
readonly: bool = APIField(
|
|
|
|
title="read only",
|
|
|
|
description="if true, no API operations that modify data can be called"
|
|
|
|
)
|
2023-12-02 01:31:58 +01:00
|
|
|
scopes: list[str]
|
|
|
|
|
|
|
|
|
2023-12-03 19:04:23 +01:00
|
|
|
@auth_api_router.get('/status/', summary="get status",
|
|
|
|
description="Returns details about the current authentication",
|
2023-12-02 01:31:58 +01:00
|
|
|
response={200: AuthStatusSchema, **auth_responses})
|
|
|
|
def get_status(request):
|
|
|
|
permissions = UserPermissions.get_for_user(request.user)
|
|
|
|
scopes = [
|
|
|
|
*(p for p in ("editor_access", "grant_permissions", "mesh_control") if getattr(permissions, p)),
|
|
|
|
*([] if request.auth.readonly else ["write"]),
|
|
|
|
]
|
|
|
|
return AuthStatusSchema(
|
|
|
|
method=request.auth.method,
|
|
|
|
readonly=request.auth.readonly,
|
|
|
|
scopes=scopes,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-11-14 17:54:56 +01:00
|
|
|
class APITokenSchema(Schema):
|
2023-11-19 00:12:10 +01:00
|
|
|
"""
|
|
|
|
An API token to be used with Bearer authentication
|
|
|
|
"""
|
|
|
|
token: NonEmptyStr
|
2023-11-14 17:54:56 +01:00
|
|
|
|
|
|
|
|
2023-11-14 18:29:21 +01:00
|
|
|
@auth_api_router.get('/session/', response=APITokenSchema, auth=None,
|
2023-12-03 19:04:23 +01:00
|
|
|
summary="get session-bound token")
|
2023-11-14 17:54:56 +01:00
|
|
|
def session_token(request):
|
2023-11-14 18:29:21 +01:00
|
|
|
session_id = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
|
|
|
|
return {"token": "anonymous" if session_id is None else f"session:{session_id}"}
|