51 lines
1.3 KiB
Python
51 lines
1.3 KiB
Python
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
|