CSSS / csss-site-backend

CSSS Website Backend (2024 - Present)
4 stars 0 forks source link

interface with CSSS-WEBSITE discord application #31

Closed EarthenSky closed 4 months ago

EarthenSky commented 4 months ago

CSSS discord has several bots (called discord applications): Wall-e, eve, and csss-website. Wall-e is a whole project undergoing renovations, and with different goals than the website.

We'd like to query the csss discord server with things like "which people have which executive roles", or "who has access to which channels". We'll want to display this information to the dashboard so that executives can be notified if someone has permission that they shouldn't (ie. transitioned officer). Historically this was automated, however the execs / mods would prefer to have direct control. In addition, we'll want some api calls to modify permissions as well (a dashboard interface), but we should leave that for a future issue.

It looks like we can use discord's http api to get the info we're looking for.

Requirements:

If you're not sure what we're looking for specifically, please ask so we're all on the same page. If you have any questions please lmk!

EarthenSky commented 4 months ago

We need to stay beneath the rate limit of 50 requests per second (& 10k per 10 minutes), which should (hopefully) be pretty easy https://discord.com/developers/docs/topics/rate-limits#rate-limits

DerpyWasHere commented 4 months ago

Specifically, this is just asking for the api to return data right? Any specific format you want that back in? Otherwise I'll default to JSON.

micahdbak commented 4 months ago

^^^ yo good question, @EarthenSky are you asking for this to be an API or functions to be used internally by the server?

EarthenSky commented 4 months ago

Specifically, this is just asking for the api to return data right? Any specific format you want that back in? Otherwise I'll default to JSON.

^^^ yo good question, @EarthenSky are you asking for this to be an API or functions to be used internally by the server?

Internal use only. I'm seeing this as a module with no endpoints, then we'll eventually write a /admin_dashboard_info endpoint (or something) that will use this module to get info or do stuff. We'll also want to use / extend this module for officer onboarding.

Seeing as this is a module, there should be functions which return python dicts & lists (essentially parsed json). Ex: def all_channels_in_category(category_name: str) -> list[str]

EarthenSky commented 4 months ago

One possible issue I'm seeing is that I'm not 100% sure if we'll need the above functions (listed under requirements), as some other access pattern might work better. If you think that maybe there could be a better set of functions to access the data above (after you read into the discord API), please let us know & do so!

DerpyWasHere commented 4 months ago

After looking into it, I think Oauth2 isn't a good fit. I think token authentication might be better.

DerpyWasHere commented 4 months ago

Before I wrack my brains on getting users w/ access to a specific channel, is there a specific need for this functionality? It's gonna be a lot of weird enumeration I feel like.

Also note that the endpoints I put in will be taken out.

EarthenSky commented 4 months ago

After looking into it, I think Oauth2 isn't a good fit. I think token authentication might be better.

I'm not familiar with Oauth2, what are the pros & cons in our situation? Token auth sounds fine & dandy, but I'm interested in the options we have!

Before I wrack my brains on getting users w/ access to a specific channel, is there a specific need for this functionality? It's gonna be a lot of weird enumeration I feel like.

In the CSSS discord people (like me) have been manually given access to specific exec channels that they weren't supposed to. It's very easy to forget / not care very much. I think Wall-E used to automatically fix permissions like this, but I'm not sure anymore (we want to notify, but not automatically fix them). This is not a very important feature, but it seems nice.

If you think it's going to be a lot of effort, feel free to make an issue for it & leave it for when we actually need to support it. It'll hopefully avoid extra refactoring that way.

micahdbak commented 4 months ago

I'm not familiar with Oauth2, what are the pros & cons in our situation?

I've used OAuth2 with my work, it's a way of validating a user by having them log in with a third-party service (e.g., Discord, Google, ...). I think in practice it requires the user interact with the third party service somehow..? Anyhoo, I think OAuth2 is better for user-experiences, not servers, and token auth is probably smarter for our situation

DerpyWasHere commented 4 months ago

I'm not familiar with Oauth2, what are the pros & cons in our situation?

I've used OAuth2 with my work, it's a way of validating a user by having them log in with a third-party service (e.g., Discord, Google, ...). I think in practice it requires the user interact with the third party service somehow..? Anyhoo, I think OAuth2 is better for user-experiences, not servers, and token auth is probably smarter for our situation

Yeah, I was having issues with the user interaction issue. Token auth is just way simpler and probably better for our use case.

If you think it's going to be a lot of effort, feel free to make an issue for it & leave it for when we actually need to support it. It'll hopefully avoid extra refactoring that way.

The way I was considering going about this involved a few steps which made it a bit complicated.

  1. Grab the given channel object
  2. Grab a list of up to 1000 users iteratively (returns a guild member object)
  3. Compare each role a user has to the channel's permissions (a bunch of bit shifting and comparisons) (This is ignoring overrides as you mentioned above)

It wouldn't be too terrible implementing this, but I was thinking of an alternative. We already expose endpoints for Wall-E, would it be possible for us to hook up an endpoint such that we can use the functionality of the .here command?

The reason for the indirection to Wall-E is that using discord.py for this module seemed a bit ham-fisted, + using effectively a synchronous library in an asynchronous setting broke a bit.

EarthenSky commented 4 months ago

We already expose endpoints for Wall-E

I would prefer to not become dependent as Wall-E since it's a bit of a massive codebase. However, you make a super good idea that we should be looking at how Wall-E already does this! Mostly copying the code is totally okay since we're within the same organization.

I'm not familiar with the discord API, but my guess was that there's a better way to determine this than fetching all users & the channel permissions they have, since discord has a view that lists all users who have access to a channel in the desktop app. This might be expressed via roles + select members who have access to a channel, for which it would make sense that we'd need to fetch all the people who have that role. However in this context, we care less about the individual people & more about the role.

I haven't looked into it deeply, but channel.fetch_members seems to be a function that exists & should have an API call.

EDIT: /channels/{channel.id}/thread-members seems promising, but might be restricted to only threads...

The way I was considering going about this involved a few steps

I'm not sure how many api calls this would require, however we don't want to make more than a few per request. If it seems not reasonably possible, let's make an issue for it & leave it for later. As I mentioned before, this isn't a particularly important function.

The reason for the indirection to Wall-E is that using discord.py for this module seemed a bit ham-fisted

It looks like we’re using the discord http api, so I’m not sure I understand what you’re referring to?

DerpyWasHere commented 4 months ago

The reason for the indirection to Wall-E is that using discord.py for this module seemed a bit ham-fisted

It looks like we’re using the discord http api, so I’m not sure I understand what you’re referring to?

We are using the discord http api, I made an attempt to use discord.py when I was in the early stages of my research.

The way I was considering going about this involved a few steps

I'm not sure how many api calls this would require, however we don't want to make more than a few per request. If it seems not reasonably possible, let's make an issue for it & leave it for later. As I mentioned before, this isn't a particularly important function.

The setup I have going in commit d8314052e9fc14ea0b340de42a4b9d97fb6bf995 requires 3 + n/1000 api calls, where n is the number of members of the server.

DerpyWasHere commented 4 months ago

Closed with #40, #41