2022-03-15 16:19:37 +00:00
|
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
2022-03-19 04:07:19 +00:00
|
|
|
from fastapi.security import OAuth2PasswordRequestForm
|
2022-03-15 16:19:37 +00:00
|
|
|
from pydantic import BaseModel
|
2022-03-18 23:04:28 +00:00
|
|
|
from sqlalchemy.orm import Session
|
2022-03-15 16:19:37 +00:00
|
|
|
|
2022-03-19 02:22:49 +00:00
|
|
|
from ..config import Config
|
2022-03-20 02:32:40 +00:00
|
|
|
from ..db import Connection
|
|
|
|
from ..db.schemas import User, UserCapability, UserCreate
|
2022-03-19 04:07:19 +00:00
|
|
|
from . import _deps
|
2022-03-15 16:25:07 +00:00
|
|
|
|
2022-03-18 23:04:28 +00:00
|
|
|
router = APIRouter(prefix="/user")
|
2022-03-15 16:19:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Token(BaseModel):
|
|
|
|
access_token: str
|
|
|
|
token_type: str
|
|
|
|
|
|
|
|
|
2022-03-18 23:04:28 +00:00
|
|
|
@router.post("/auth", response_model=Token)
|
2022-03-18 23:45:09 +00:00
|
|
|
async def login(
|
2022-03-18 23:04:28 +00:00
|
|
|
form_data: OAuth2PasswordRequestForm = Depends(),
|
2022-03-19 04:07:19 +00:00
|
|
|
current_config: Config | None = Depends(Config.load),
|
|
|
|
db: Session | None = Depends(Connection.get),
|
2022-03-19 00:38:57 +00:00
|
|
|
):
|
2022-03-19 04:07:19 +00:00
|
|
|
if current_config is None:
|
|
|
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)
|
|
|
|
|
2022-03-20 02:32:40 +00:00
|
|
|
user = User.login(
|
2022-03-19 00:38:57 +00:00
|
|
|
db=db,
|
|
|
|
name=form_data.username,
|
|
|
|
password=form_data.password,
|
2022-03-19 04:07:19 +00:00
|
|
|
crypt_context=await current_config.crypto.crypt_context,
|
2022-03-19 00:38:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
if user is None:
|
|
|
|
raise HTTPException(
|
|
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
|
|
detail="Could not validate credentials",
|
|
|
|
headers={"WWW-Authenticate": "Bearer"},
|
|
|
|
)
|
|
|
|
|
2022-03-19 04:07:19 +00:00
|
|
|
access_token = await current_config.jwt.create_token(user.name)
|
2022-03-19 00:38:57 +00:00
|
|
|
return {"access_token": access_token, "token_type": "bearer"}
|
|
|
|
|
|
|
|
|
2022-03-20 02:32:40 +00:00
|
|
|
@router.get("/current", response_model=User)
|
2022-03-19 00:38:57 +00:00
|
|
|
async def get_current_user(
|
2022-03-20 02:32:40 +00:00
|
|
|
current_user: User | None = Depends(_deps.get_current_user),
|
2022-03-19 00:38:57 +00:00
|
|
|
):
|
|
|
|
return current_user
|
2022-03-19 18:06:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
@router.post(
|
|
|
|
"/new",
|
|
|
|
responses={
|
|
|
|
status.HTTP_200_OK: _deps.Responses.ok,
|
|
|
|
status.HTTP_400_BAD_REQUEST: _deps.Responses.not_installed,
|
|
|
|
status.HTTP_401_UNAUTHORIZED: _deps.Responses.needs_user,
|
|
|
|
status.HTTP_403_FORBIDDEN: _deps.Responses.needs_admin,
|
|
|
|
status.HTTP_409_CONFLICT: _deps.Responses.entry_exists,
|
|
|
|
},
|
2022-03-20 02:32:40 +00:00
|
|
|
response_model=User,
|
2022-03-19 18:06:28 +00:00
|
|
|
)
|
|
|
|
async def add_user(
|
2022-03-20 02:32:40 +00:00
|
|
|
user: UserCreate,
|
2022-03-19 18:06:28 +00:00
|
|
|
current_config: Config | None = Depends(Config.load),
|
2022-03-20 02:32:40 +00:00
|
|
|
current_user: User | None = Depends(_deps.get_current_user),
|
2022-03-19 18:06:28 +00:00
|
|
|
db: Session | None = Depends(Connection.get),
|
|
|
|
):
|
|
|
|
if current_config is None:
|
|
|
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)
|
|
|
|
|
2022-03-19 18:31:03 +00:00
|
|
|
if (current_user is None
|
2022-03-20 02:32:40 +00:00
|
|
|
or UserCapability.admin not in current_user.capabilities):
|
2022-03-19 18:06:28 +00:00
|
|
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
|
|
|
|
2022-03-20 02:32:40 +00:00
|
|
|
new_user = User.create(
|
2022-03-19 18:06:28 +00:00
|
|
|
db=db,
|
|
|
|
user=user,
|
|
|
|
crypt_context=await current_config.crypto.crypt_context,
|
|
|
|
)
|
|
|
|
|
|
|
|
if new_user is None:
|
|
|
|
raise HTTPException(status_code=status.HTTP_409_CONFLICT)
|
|
|
|
|
|
|
|
return new_user
|