From 83294ac7c9ab194a2a221e5b10cee3446be4d4fd Mon Sep 17 00:00:00 2001 From: Kai Vogelgesang Date: Tue, 4 Oct 2022 13:36:35 +0200 Subject: [PATCH] Implement admin methods --- .env | 3 ++- backend/app.py | 64 ++++++++++++++++++++++++++++++++++++++++----- backend/settings.py | 3 ++- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/.env b/.env index edd9a68..db98bd4 100644 --- a/.env +++ b/.env @@ -1 +1,2 @@ -MONGO_URI="mongodb://user:pass@localhost:27017/" \ No newline at end of file +MONGO_URI="mongodb://user:pass@localhost:27017/" +ADMIN_TOKEN="admin" \ No newline at end of file diff --git a/backend/app.py b/backend/app.py index 50c0ad5..43f3c39 100644 --- a/backend/app.py +++ b/backend/app.py @@ -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 diff --git a/backend/settings.py b/backend/settings.py index 7d50352..3ffd322 100644 --- a/backend/settings.py +++ b/backend/settings.py @@ -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"