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 typing import Literal
from fastapi import FastAPI, HTTPException, status, Depends from fastapi import FastAPI, HTTPException, status, Depends
from pydantic import BaseModel from pydantic import BaseModel
from .db import MongoModel, client from .db import MongoModel, client
from .settings import settings
db = client["party"]
app = FastAPI() app = FastAPI()
Coming = Literal["yes", "no", "maybe"]
GrammaticalGender = Literal["m", "f", "d"]
class Guest(MongoModel): class Guest(MongoModel):
token: str token: str
coming: Literal["yes", "no", "maybe"] | None name: str
grammatical_gender: Literal["m", "f", "d"] coming: Coming | None
grammatical_gender: GrammaticalGender
async def find_guest(party: str, token: str) -> Guest: 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: if not guest:
raise HTTPException(status.HTTP_401_UNAUTHORIZED) raise HTTPException(status.HTTP_401_UNAUTHORIZED)
return Guest.parse_obj(guest) 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)): async def get_self(guest: Guest = Depends(find_guest)):
return guest return guest
class GuestUpdate(BaseModel): 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( async def update_self(
party: str, update: GuestUpdate, guest: Guest = Depends(find_guest) party: str, update: GuestUpdate, guest: Guest = Depends(find_guest)
): ):
guest_dict = guest.dict() guest_dict = guest.dict()
guest_dict.update(update.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): class Settings(BaseSettings):
mongo_uri: str mongo_uri: str
admin_token: SecretStr
class Config: class Config:
env_file = ".env" env_file = ".env"