Skip to content

Commit

Permalink
Use ckey instead of discord id in patreon route
Browse files Browse the repository at this point in the history
  • Loading branch information
Seefaaa committed Jul 10, 2024
1 parent 7ba9b34 commit 75273b6
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 27 deletions.
32 changes: 19 additions & 13 deletions src/http/discord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ use serde::{Deserialize, Serialize};

use super::{Error, REQWEST_CLIENT};

#[derive(Debug, Deserialize)]
struct ErrorMessage {
code: u32,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct User {
pub id: String,
Expand All @@ -28,28 +33,29 @@ pub async fn get_user(id: i64, token: &str) -> Result<User, Error> {
}

#[derive(Debug, Deserialize)]
struct GuildMember {
roles: HashSet<String>, // other fields are not required for now (https://discord.com/developers/docs/resources/guild#guild-member-object)
pub struct GuildMember {
pub roles: HashSet<String>, // other fields are not required for now (https://discord.com/developers/docs/resources/guild#guild-member-object)
}

pub async fn is_patron(guild_id: i64, user_id: i64, role_id: i64, token: &str) -> Result<bool, Error> {
pub async fn get_guild_member(
guild_id: i64,
user_id: i64,
token: &str,
) -> Result<GuildMember, Error> {
let url = format!("https://discord.com/api/v10/guilds/{guild_id}/members/{user_id}");

let response = REQWEST_CLIENT
.get(url)
.header("Authorization", format!("Bot {token}"))
.send()
.await?
.text()
.await?;

if !response.status().is_success() {
return Ok(false);
}

let member: GuildMember = response.json().await?;

if member.roles.contains(&role_id.to_string()) {
return Ok(true);
}
let Ok(member) = serde_json::from_str(&response) else {
let error: ErrorMessage = serde_json::from_str(&response)?;
return Err(Error::Discord(error.code));
};

Ok(false)
Ok(member)
}
3 changes: 3 additions & 0 deletions src/http/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ use thiserror::Error;
#[error(transparent)]
pub enum Error {
Reqwest(#[from] reqwest::Error),
SerdeJson(#[from] serde_json::Error),
#[error("discord api error")]
Discord(u32),
}
3 changes: 2 additions & 1 deletion src/routes/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use rocket::{routes, Build, Rocket};

mod autocomplete;
mod common;
mod patreon;
mod player;
mod server;
mod verify;
Expand All @@ -12,13 +13,13 @@ pub fn mount(rocket: Rocket<Build>) -> Rocket<Build> {
rocket.mount(
"/v2",
routes![
patreon::index,
player::index,
player::ban,
player::characters,
player::roletime,
player::top,
player::discord,
player::patreon,
server::index,
verify::index,
verify::unverify,
Expand Down
46 changes: 46 additions & 0 deletions src/routes/v2/patreon.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use rocket::{get, http::Status, State};
use serde_json::{json, Value};
use sqlx::MySqlPool;

use crate::{
config::{self, Config},
database::{error::Error, *},
http::{self, discord::get_guild_member},
Database,
};

use super::Json;

#[get("/patreon?<ckey>")]
pub async fn index(
ckey: &str,
database: &State<Database>,
config: &State<Config>,
) -> Result<Json<Value>, Status> {
let Ok(patron) = is_patron(ckey, &database.pool, &config.discord).await else {
return Err(Status::InternalServerError);
};

Ok(Json::Ok(json!({ "patron": patron })))
}

async fn is_patron(ckey: &str, pool: &MySqlPool, discord: &config::Discord) -> Result<bool, Error> {
let mut connection = pool.acquire().await?;

let Ok(discord_id) = discord_id_by_ckey(ckey, &mut connection).await else {
return Ok(false);
};

connection.close().await?;

let member = match get_guild_member(discord.guild, discord_id, &discord.token).await {
Ok(member) => member,
Err(http::Error::Discord(code)) => match code {
10007 | 10013 => return Ok(false),
_ => return Err(http::Error::Discord(code))?,
},
Err(e) => return Err(e)?,
};

Ok(member.roles.contains(&discord.patreon_role.to_string()))
}
13 changes: 0 additions & 13 deletions src/routes/v2/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use crate::{
config::Config,
database::{error::Error, *},
Database,
http::discord::is_patron,
};

use super::{common::ApiKey, Json};
Expand Down Expand Up @@ -104,15 +103,3 @@ pub async fn discord(

unreachable!()
}

#[get("/player/patreon?<discord_id>")]
pub async fn patreon(
discord_id: i64,
config: &State<Config>,
) -> Result<Json<Value>, Status> {
let Ok(patron) = is_patron(config.discord.guild, discord_id, config.discord.patreon_role, &config.discord.token).await else {
return Err(Status::InternalServerError);
};

Ok(Json::Ok(json!({ "patron": patron })))
}

0 comments on commit 75273b6

Please sign in to comment.