aboutsummaryrefslogtreecommitdiffstats
path: root/backend/routes/discord.py
blob: 53b8af3192e6bd64431265c69ac034db0790942b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
"""Routes which directly interact with discord related data."""

import pydantic
from spectree import Response
from starlette.authentication import requires
from starlette.responses import JSONResponse
from starlette.routing import Request

from backend import discord, models, route
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,
)


class RolesRoute(route.Route):
    """Refreshes the roles database."""

    name = "roles"
    path = "/roles"

    class RolesResponse(pydantic.BaseModel):
        """A list of all roles on the configured server."""

        roles: list[models.DiscordRole]

    @requires(["authenticated", "admin"])
    @api.validate(
        resp=Response(HTTP_200=RolesResponse),
        tags=["roles"],
    )
    async def patch(self, request: Request) -> JSONResponse:
        """Refresh the roles database."""
        roles = await discord.get_roles(request.state.db, force_refresh=True)

        return JSONResponse(
            {"roles": [role.dict() for role in roles]},
        )


class MemberRoute(route.Route):
    """Retrieve information about a server member."""

    name = "member"
    path = "/member"

    class MemberRequest(pydantic.BaseModel):
        """An ID of the member to update."""

        user_id: str

    @requires(["authenticated", "admin"])
    @api.validate(
        resp=Response(HTTP_200=models.DiscordMember, HTTP_400=ErrorMessage),
        json=MemberRequest,
        tags=["auth"],
    )
    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)

        if member:
            return JSONResponse(member.dict())
        return NOT_FOUND_EXCEPTION

    @requires(["authenticated", "admin"])
    @api.validate(
        resp=Response(HTTP_200=models.DiscordMember, HTTP_400=ErrorMessage),
        json=MemberRequest,
        tags=["auth"],
    )
    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"])

        if not member:
            return NOT_FOUND_EXCEPTION

        return JSONResponse(member.dict())