aboutsummaryrefslogtreecommitdiffstats
path: root/backend/discord.py
diff options
context:
space:
mode:
authorGravatar Hassan Abouelela <[email protected]>2022-02-05 17:39:33 +0400
committerGravatar Hassan Abouelela <[email protected]>2022-02-05 18:27:11 +0400
commit513de6945d40b66368a061dff6a81646e8bda7a0 (patch)
tree64f3ad8670cc9c1fffb6c8c2c0a5e9a8da04582f /backend/discord.py
parentOverhaul Scope System (diff)
Add Role Based Authorized Readers
Adds a new property on forms to declare which roles are authorized to access form responses. Signed-off-by: Hassan Abouelela <[email protected]>
Diffstat (limited to 'backend/discord.py')
-rw-r--r--backend/discord.py38
1 files changed, 38 insertions, 0 deletions
diff --git a/backend/discord.py b/backend/discord.py
index 51de26a..4e35216 100644
--- a/backend/discord.py
+++ b/backend/discord.py
@@ -5,6 +5,7 @@ import json
import typing
import httpx
+import starlette.requests
from pymongo.database import Database
from backend import constants, models
@@ -150,3 +151,40 @@ async def get_member(
"inserted_at": datetime.datetime.now(tz=datetime.timezone.utc),
})
return member
+
+
+class FormNotFoundError(Exception):
+ """The requested form was not found."""
+
+
+async def _verify_access_helper(
+ form_id: str, request: starlette.requests.Request, attribute: str
+) -> bool:
+ """A low level helper to validate access to a form resource based on the user's scopes."""
+ # Short circuit all resources for admins
+ if "admin" in request.auth.scopes:
+ return True
+
+ form = await request.state.db.forms.find_one({"id": form_id})
+
+ if not form:
+ raise FormNotFoundError()
+
+ form = models.Form(**form)
+
+ for role_id in getattr(form, attribute) or []:
+ role = await request.state.db.roles.find_one({"id": role_id})
+ if not role:
+ continue
+
+ role = models.DiscordRole(**json.loads(role["data"]))
+
+ if role.name in request.auth.scopes:
+ return True
+
+ return False
+
+
+async def verify_response_access(form_id: str, request: starlette.requests.Request) -> bool:
+ """Ensure the user can access responses on the requested resource."""
+ return await _verify_access_helper(form_id, request, "response_readers")