from django.contrib.auth import authenticate from django.http import HttpRequest from ninja import Router, Schema from ninja.errors import HttpError from accounts.auth import AUTH from accounts.models import ApiToken router = Router() class LoginIn(Schema): username: str password: str device_name: str = "" class TokenOut(Schema): token: str username: str class UserOut(Schema): username: str is_staff: bool @router.post("/login", response=TokenOut, auth=None) def login(request: HttpRequest, payload: LoginIn): """Exchange username/password for a bearer token. There is no registration.""" user = authenticate(request, username=payload.username, password=payload.password) if user is None: raise HttpError(401, "Invalid username or password.") token = ApiToken.objects.create(user=user, name=payload.device_name) return {"token": token.key, "username": user.username} @router.post("/logout", auth=AUTH) def logout(request: HttpRequest): """Revoke the token used for this request. Session logins are unaffected.""" token = request.auth if isinstance(token, ApiToken): token.delete() return {"detail": "Logged out."} @router.get("/me", response=UserOut, auth=AUTH) def me(request: HttpRequest): return request.user