From 3e786da5537cc243097b4bedb8e6b78ad1525f95 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Sat, 22 Jan 2022 01:54:15 +0300 Subject: Add Helper Functions For Managing Roles Signed-off-by: Hassan Abouelela --- backend/models/discord_role.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 backend/models/discord_role.py (limited to 'backend/models/discord_role.py') diff --git a/backend/models/discord_role.py b/backend/models/discord_role.py new file mode 100644 index 0000000..9f0b7dd --- /dev/null +++ b/backend/models/discord_role.py @@ -0,0 +1,40 @@ +import typing + +from pydantic import BaseModel + + +class RoleTags(BaseModel): + """Meta information about a discord role.""" + + bot_id: typing.Optional[str] + integration_id: typing.Optional[str] + premium_subscriber: bool + + def __init__(self, **data: typing.Any): + """ + Handle the terrible discord API. + + Discord only returns the premium_subscriber field if it's true, + meaning the typical validation process wouldn't work. + + We manually parse the raw data to determine if the field exists, and give it a useful + bool value. + """ + data["premium_subscriber"] = "premium_subscriber" in data.keys() + super().__init__(**data) + + +class DiscordRole(BaseModel): + """Schema model of Discord guild roles.""" + + id: str + name: str + color: int + hoist: bool + icon: typing.Optional[str] + unicode_emoji: typing.Optional[str] + position: int + permissions: str + managed: bool + mentionable: bool + tags: typing.Optional[RoleTags] -- cgit v1.2.3 From c4f816c576097d78c5645113115bbcaa29f7a1ee Mon Sep 17 00:00:00 2001 From: Hassan Abouelela Date: Sat, 5 Feb 2022 18:49:45 +0400 Subject: Fix Linting Errors Signed-off-by: Hassan Abouelela --- backend/models/discord_role.py | 2 +- backend/models/form.py | 2 +- backend/routes/discord.py | 10 +++++----- tox.ini | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'backend/models/discord_role.py') diff --git a/backend/models/discord_role.py b/backend/models/discord_role.py index 9f0b7dd..c05c9de 100644 --- a/backend/models/discord_role.py +++ b/backend/models/discord_role.py @@ -10,7 +10,7 @@ class RoleTags(BaseModel): integration_id: typing.Optional[str] premium_subscriber: bool - def __init__(self, **data: typing.Any): + def __init__(self, **data: typing.Any) -> None: """ Handle the terrible discord API. diff --git a/backend/models/form.py b/backend/models/form.py index 4ee2804..f888d6e 100644 --- a/backend/models/form.py +++ b/backend/models/form.py @@ -70,7 +70,7 @@ class Form(BaseModel): return value @validator("response_readers", "editors") - def validate_role_scoping(cls, value: t.Optional[list[str]]): + def validate_role_scoping(cls, value: t.Optional[list[str]]) -> t.Optional[list[str]]: """Ensure special role based permissions aren't granted to the @everyone role.""" if value and str(DISCORD_GUILD) in value: raise ValueError("You can not add the everyone role as an access scope.") diff --git a/backend/routes/discord.py b/backend/routes/discord.py index a980d94..bca1edb 100644 --- a/backend/routes/discord.py +++ b/backend/routes/discord.py @@ -7,7 +7,7 @@ from starlette.responses import JSONResponse from starlette.routing import Request from backend import discord, models, route -from backend.validation import ErrorMessage, OkayResponse, api +from backend.validation import ErrorMessage, api NOT_FOUND_EXCEPTION = JSONResponse( {"error": "Could not find the requested resource in the guild or cache."}, status_code=404 @@ -27,7 +27,7 @@ class RolesRoute(route.Route): @requires(["authenticated", "admin"]) @api.validate( - resp=Response(HTTP_200=OkayResponse), + resp=Response(HTTP_200=RolesResponse), tags=["roles"] ) async def patch(self, request: Request) -> JSONResponse: @@ -35,7 +35,7 @@ class RolesRoute(route.Route): roles = await discord.get_roles(request.state.db, force_refresh=True) return JSONResponse( - {"status": "ok"}, + {"roles": [role.dict() for role in roles]}, ) @@ -56,7 +56,7 @@ class MemberRoute(route.Route): json=MemberRequest, tags=["auth"] ) - async def delete(self, request: Request): + async def delete(self, request: Request) -> JSONResponse: """Force a resync of the cache for the given user.""" body = await request.json() member = await discord.get_member(request.state.db, body["user_id"], force_refresh=True) @@ -72,7 +72,7 @@ class MemberRoute(route.Route): json=MemberRequest, tags=["auth"] ) - async def get(self, request: Request): + async def get(self, request: Request) -> JSONResponse: """Get a user's roles on the configured server.""" body = await request.json() member = await discord.get_member(request.state.db, body["user_id"]) diff --git a/tox.ini b/tox.ini index afb3b34..451c3dd 100644 --- a/tox.ini +++ b/tox.ini @@ -5,6 +5,6 @@ docstring-convention=all import-order-style=pycharm ignore= # Type annotations - ANN101,ANN102 + ANN002,ANN003,ANN101,ANN102 # Line breaks W503 -- cgit v1.2.3