Compare commits

..

2 Commits

Author SHA1 Message Date
3bb77d29a5
Make allowed extra length configurable
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-09 17:54:53 +02:00
0512449140
Implement user-modifialble extra props 2022-10-09 17:35:25 +02:00

View File

@ -74,6 +74,26 @@ async def find_guest(party: str, token: str) -> DBGuest:
return DBGuest.parse_obj(guest)
class Party(MongoModel):
name: str
created: datetime
allowed_extra: dict[str, int]
async def find_party(name: str) -> Party:
party = await meta["parties"].find_one({"name": name})
if not party:
raise HTTPException(status.HTTP_404_NOT_FOUND)
return Party.parse_obj(party)
def validate_extra(extra: dict[str, str], party: Party):
return all(
k in party.allowed_extra and len(v) <= party.allowed_extra[k]
for (k, v) in extra.items()
)
# Guest methods
@ -88,7 +108,8 @@ async def get_self(guest: DBGuest = Depends(find_guest)):
class GuestUpdate(BaseModel):
coming: Coming
coming: Coming | None
extra: dict[str, str] | None
@app.patch(
@ -100,8 +121,31 @@ class GuestUpdate(BaseModel):
async def update_self(
party: str, update: GuestUpdate, guest: DBGuest = Depends(find_guest)
):
try:
party_obj = await find_party(party)
except HTTPException:
# should not happen since find_guest in Depends already
# implies that the party/token combo is correct
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
guest_dict = guest.dict(exclude={"id"})
guest_dict.update(update.dict())
update_dict = update.dict(exclude_unset=True)
if "extra" in update_dict:
if not validate_extra(update_dict["extra"], party_obj):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
# overwrite allowed extra, but keep those that are not allowed/user-modifiable
update_dict["extra"].update(
{
k: v
for (k, v) in guest_dict["extra"].items()
if k not in party_obj.allowed_extra
}
)
guest_dict.update(update_dict)
await db[party].replace_one({"_id": guest.id}, guest_dict)
return await db[party].find_one({"_id": guest.id})
@ -135,11 +179,6 @@ async def auth_admin(admin_token: str):
raise HTTPException(status.HTTP_401_UNAUTHORIZED)
class Party(MongoModel):
name: str
created: datetime
@app.get(
"/{admin_token}",
response_model=list[Party],
@ -152,6 +191,7 @@ async def list_parties(_=Depends(auth_admin)):
class PartyCreate(BaseModel):
name: str
allowed_extra: dict[str, int] = dict()
@app.post(
@ -168,12 +208,11 @@ async def create_party(party: PartyCreate, _=Depends(auth_admin)):
raise HTTPException(
status.HTTP_400_BAD_REQUEST, f"Party {party.name!r} already exists"
)
inserted = await meta["parties"].insert_one(
{
"name": party.name,
"created": datetime.now(),
}
)
party_dict = party.dict()
party_dict.update({"created": datetime.now()})
inserted = await meta["parties"].insert_one(party_dict)
return await meta["parties"].find_one({"_id": inserted.inserted_id})
@ -218,8 +257,7 @@ class GuestCreate(BaseModel):
tags=["admin"],
)
async def create_new_guest(party: str, new_guest: GuestCreate, _=Depends(auth_admin)):
if not await meta["parties"].find_one({"name": party}):
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
await find_party(party)
existing = await db[party].find_one({"token": new_guest.token})
if existing:
@ -232,6 +270,33 @@ async def create_new_guest(party: str, new_guest: GuestCreate, _=Depends(auth_ad
return inserted
@app.get(
"/{admin_token}/{party}/userAllowedExtra",
response_model=dict[str, int],
responses=error_responses(401, 404),
tags=["admin"],
)
async def get_allowed_extra_keys(party: str, _=Depends(auth_admin)):
party_obj = await find_party(party)
return party_obj.allowed_extra
@app.patch(
"/{admin_token}/{party}/userAllowedExtra",
response_model=Party,
responses=error_responses(401, 404),
tags=["admin"],
)
async def modify_allowed_extra_keys(
party: str, keys: dict[str, int], _=Depends(auth_admin)
):
party_obj = await find_party(party)
party_dict = party_obj.dict(exclude={"id"})
party_dict["allowed_extra"] = keys
await meta["parties"].replace_one({"_id": party_obj.id}, party_dict)
return await meta["parties"].find_one({"_id": party_obj.id})
class GuestModify(BaseModel):
token: str | None
name: str | None
@ -249,8 +314,7 @@ class GuestModify(BaseModel):
async def modify_guest(
party: str, id: PyObjectId, modified_guest: GuestModify, _=Depends(auth_admin)
):
if not await meta["parties"].find_one({"name": party}):
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
await find_party(party)
existing = await db[party].find_one({"_id": id})
if not existing: