diff --git a/web/src/lib.rs b/web/src/lib.rs index 0442fa5..07510aa 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -25,7 +25,7 @@ type Database = MySql; #[derive(Debug)] enum Error { SQLx(sqlx::Error), - serenity(serenity::Error), + Serenity(serenity::Error), } #[catch(401)] diff --git a/web/src/macros.rs b/web/src/macros.rs index 8da595a..e14d3a4 100644 --- a/web/src/macros.rs +++ b/web/src/macros.rs @@ -45,3 +45,37 @@ macro_rules! check_url_opt { check_url_opt!($($fields),+); }; } + +macro_rules! check_authorization { + ($cookies:expr, $ctx:expr, $guild:expr) => { + use serenity::model::id::UserId; + + let user_id = $cookies.get_private("userid").map(|c| c.value().parse::().ok()).flatten(); + + match user_id { + Some(user_id) => { + match GuildId($guild).to_guild_cached($ctx) { + Some(guild) => { + let member = guild.member($ctx, UserId(user_id)).await; + + match member { + Err(_) => { + return json!({"error": "User not in guild"}) + } + + Ok(_) => {} + } + } + + None => { + return json!({"error": "Bot not in guild"}) + } + } + } + + None => { + return json!({"error": "User not authorized"}); + } + } + } +} diff --git a/web/src/routes/dashboard/guild.rs b/web/src/routes/dashboard/guild.rs index 50214d5..22b2a10 100644 --- a/web/src/routes/dashboard/guild.rs +++ b/web/src/routes/dashboard/guild.rs @@ -31,13 +31,15 @@ struct ChannelInfo { webhook_name: Option, } -// todo check the user can access this guild #[get("/api/guild//channels")] pub async fn get_guild_channels( id: u64, + cookies: &CookieJar<'_>, ctx: &State, pool: &State>, ) -> JsonValue { + check_authorization!(cookies, ctx.inner(), id); + let channels_res = GuildId(id).channels(ctx.inner()).await; match channels_res { @@ -96,9 +98,10 @@ struct RoleInfo { name: String, } -// todo check the user can access this guild #[get("/api/guild//roles")] -pub async fn get_guild_roles(id: u64, ctx: &State) -> JsonValue { +pub async fn get_guild_roles(id: u64, cookies: &CookieJar<'_>, ctx: &State) -> JsonValue { + check_authorization!(cookies, ctx.inner(), id); + let roles_res = ctx.cache.guild_roles(id); match roles_res { @@ -126,14 +129,10 @@ pub async fn create_reminder( serenity_context: &State, pool: &State>, ) -> JsonValue { - // get userid from cookies - let user_id = cookies.get_private("userid").map(|c| c.value().parse::().ok()).flatten(); + check_authorization!(cookies, serenity_context.inner(), id); - if user_id.is_none() { - return json!({"error": "User not authorized"}); - } - - let user_id = user_id.unwrap(); + let user_id = + cookies.get_private("userid").map(|c| c.value().parse::().ok()).flatten().unwrap(); // validate channel let channel = ChannelId(reminder.channel).to_channel_cached(&serenity_context.inner()); diff --git a/web/src/routes/dashboard/mod.rs b/web/src/routes/dashboard/mod.rs index d8e1403..431a9f6 100644 --- a/web/src/routes/dashboard/mod.rs +++ b/web/src/routes/dashboard/mod.rs @@ -106,7 +106,7 @@ async fn create_database_channel( let webhook = channel .create_webhook_with_avatar(&ctx, "Reminder", DEFAULT_AVATAR.clone()) .await - .map_err(|e| Error::serenity(e))?; + .map_err(|e| Error::Serenity(e))?; sqlx::query!( "UPDATE channels SET webhook_id = ?, webhook_token = ? WHERE channel = ?", @@ -127,7 +127,7 @@ async fn create_database_channel( let webhook = channel .create_webhook_with_avatar(&ctx, "Reminder", DEFAULT_AVATAR.clone()) .await - .map_err(|e| Error::serenity(e))?; + .map_err(|e| Error::Serenity(e))?; // create database entry sqlx::query!( diff --git a/web/templates/dashboard.html.tera b/web/templates/dashboard.html.tera index 51fda97..3bef65f 100644 --- a/web/templates/dashboard.html.tera +++ b/web/templates/dashboard.html.tera @@ -54,6 +54,19 @@ + + @@ -158,7 +171,7 @@ - - -