Implement admin methods

This commit is contained in:
Kai Vogelgesang 2022-10-04 13:36:35 +02:00
parent 359c02e6da
commit 83294ac7c9
Signed by: kai
GPG Key ID: 0A95D3B6E62C0879
3 changed files with 61 additions and 9 deletions

3
.env
View File

@ -1 +1,2 @@
MONGO_URI="mongodb://user:pass@localhost:27017/"
MONGO_URI="mongodb://user:pass@localhost:27017/"
ADMIN_TOKEN="admin"

View File

@ -1,37 +1,87 @@
from typing import Literal
from fastapi import FastAPI, HTTPException, status, Depends
from pydantic import BaseModel
from .db import MongoModel, client
from .settings import settings
db = client["party"]
app = FastAPI()
Coming = Literal["yes", "no", "maybe"]
GrammaticalGender = Literal["m", "f", "d"]
class Guest(MongoModel):
token: str
coming: Literal["yes", "no", "maybe"] | None
grammatical_gender: Literal["m", "f", "d"]
name: str
coming: Coming | None
grammatical_gender: GrammaticalGender
async def find_guest(party: str, token: str) -> Guest:
guest = await client["party"][party].find_one({"token": token})
guest = await db[party].find_one({"token": token})
if not guest:
raise HTTPException(status.HTTP_401_UNAUTHORIZED)
return Guest.parse_obj(guest)
@app.get("/api/{party}/{token}/me", response_model=Guest)
# Guest methods
@app.get("/{party}/{token}/me", response_model=Guest)
async def get_self(guest: Guest = Depends(find_guest)):
return guest
class GuestUpdate(BaseModel):
coming: Literal["yes", "no", "maybe"]
coming: Coming
@app.patch("/api/{party}/{token}/update")
@app.patch("/{party}/{token}/update")
async def update_self(
party: str, update: GuestUpdate, guest: Guest = Depends(find_guest)
):
guest_dict = guest.dict()
guest_dict.update(update.dict())
await client["party"][party].replace_one({"_id": guest.id}, guest_dict)
await db[party].replace_one({"_id": guest.id}, guest_dict)
# Admin methods
async def auth_admin(admin_token: str):
if admin_token != settings.admin_token.get_secret_value():
raise HTTPException(status.HTTP_401_UNAUTHORIZED)
@app.get("/{party}/{admin_token}/list", response_model=list[Guest])
async def list_guests(party: str, _=Depends(auth_admin)):
return await db[party].find().to_list(None)
class GuestSet(BaseModel):
token: str
name: str
coming: Coming | None
grammatical_gender: GrammaticalGender
@app.put("/{party}/{admin_token}/set", response_model=Guest)
async def edit_or_create_new_guest(
party: str, guest_set: GuestSet, _=Depends(auth_admin)
):
existing = await db[party].find_one({"token": guest_set.token})
if existing:
# update the existing guest
existing.update(guest_set.dict())
await db[party].replace_one({"_id": existing["_id"]}, existing)
return await db[party].find_one({"_id": existing["_id"]})
else:
# create a new guest
insert_result = await db[party].insert_one(guest_set.dict())
inserted = await db[party].find_one({"_id": insert_result.inserted_id})
return inserted

View File

@ -1,8 +1,9 @@
from pydantic import BaseSettings
from pydantic import BaseSettings, SecretStr
class Settings(BaseSettings):
mongo_uri: str
admin_token: SecretStr
class Config:
env_file = ".env"