diff --git a/crates/core/database/src/models/bots/model.rs b/crates/core/database/src/models/bots/model.rs index 2a2ad0b5..85335590 100644 --- a/crates/core/database/src/models/bots/model.rs +++ b/crates/core/database/src/models/bots/model.rs @@ -49,6 +49,7 @@ auto_derived_partial!( auto_derived!( #[derive(Copy, Hash)] + #[serde(rename = "lowercase")] pub enum OAuth2Scope { Identify, Full, diff --git a/crates/core/database/src/util/oauth2.rs b/crates/core/database/src/util/oauth2.rs index ef09be01..79854116 100644 --- a/crates/core/database/src/util/oauth2.rs +++ b/crates/core/database/src/util/oauth2.rs @@ -123,4 +123,14 @@ pub async fn add_code_challange(token: &str, code_challenge: &str) -> Result<()> .map_err(|_| create_error!(InternalError))?; Ok(()) +} + +pub async fn get_code_challange(token: &str) -> Result> { + let mut conn = redis_kiss::get_connection() + .await + .map_err(|_| create_error!(InternalError))?; + + conn.get(format!("oauth2:{token}:code_challenge")) + .await + .map_err(|_| create_error!(InternalError)) } \ No newline at end of file diff --git a/crates/core/models/src/v0/oauth2.rs b/crates/core/models/src/v0/oauth2.rs index c82715d4..0048a558 100644 --- a/crates/core/models/src/v0/oauth2.rs +++ b/crates/core/models/src/v0/oauth2.rs @@ -77,6 +77,7 @@ auto_derived!( } #[derive(Copy, Hash)] + #[cfg_attr(feature = "serde", serde(rename = "lowercase"))] pub enum OAuth2Scope { Identify, Full, diff --git a/crates/delta/src/routes/bots/edit.rs b/crates/delta/src/routes/bots/edit.rs index 845c7819..b606b6c2 100644 --- a/crates/delta/src/routes/bots/edit.rs +++ b/crates/delta/src/routes/bots/edit.rs @@ -1,4 +1,3 @@ -use revolt_database::BotOauth2; use revolt_database::{util::reference::Reference, Database, PartialBot, User}; use revolt_models::v0::{self, DataEditBot}; use revolt_result::{create_error, Result}; diff --git a/crates/delta/src/routes/oauth2/authorize_auth.rs b/crates/delta/src/routes/oauth2/authorize_auth.rs index 682d6e35..e086f693 100644 --- a/crates/delta/src/routes/oauth2/authorize_auth.rs +++ b/crates/delta/src/routes/oauth2/authorize_auth.rs @@ -17,6 +17,10 @@ pub async fn auth( user: User, info: v0::OAuth2AuthorizationForm, ) -> Result> { + if user.bot.is_some() { + return Err(create_error!(IsBot)); + }; + let bot = Reference::from_unchecked(info.client_id.clone()) .as_bot(db) .await?; diff --git a/crates/delta/src/routes/oauth2/authorize_info.rs b/crates/delta/src/routes/oauth2/authorize_info.rs index f1d7a91b..ccd5a55a 100644 --- a/crates/delta/src/routes/oauth2/authorize_info.rs +++ b/crates/delta/src/routes/oauth2/authorize_info.rs @@ -13,6 +13,10 @@ pub async fn info( user: User, info: v0::OAuth2AuthorizationForm, ) -> Result> { + if user.bot.is_some() { + return Err(create_error!(IsBot)); + }; + let bot = Reference::from_unchecked(info.client_id.to_string()).as_bot(db).await?; let bot_user = Reference::from_unchecked(bot.id.clone()).as_user(db).await?; let public_bot = bot.clone().into_public_bot(bot_user); diff --git a/crates/delta/src/routes/oauth2/token.rs b/crates/delta/src/routes/oauth2/token.rs index 84456ff0..14c93d6b 100644 --- a/crates/delta/src/routes/oauth2/token.rs +++ b/crates/delta/src/routes/oauth2/token.rs @@ -35,13 +35,9 @@ pub async fn token( return Err(create_error!(NotAuthenticated)) } } else if let Some((code_verifier, method)) = info.code_verifier.as_ref().zip(claims.code_challange_method) { - let mut conn = redis_kiss::get_connection() - .await - .map_err(|_| create_error!(InternalError))?; - - let server_code_challenge = conn.get::<_, String>(format!("oauth2:{}:code_challenge", &info.code)) - .await - .map_err(|_| create_error!(InternalError))?; + let Some(server_code_challenge) = oauth2::get_code_challange(&info.code).await? else { + return Err(create_error!(NotAuthenticated)) + }; let is_valid = match method { v0::OAuth2CodeChallangeMethod::Plain => &server_code_challenge == code_verifier, @@ -51,6 +47,8 @@ pub async fn token( if !is_valid { return Err(create_error!(NotAuthenticated)) } + } else { + return Err(create_error!(NotAuthenticated)) } if claims.client_id != info.client_id || claims.exp < Utc::now().timestamp() { @@ -81,6 +79,7 @@ pub async fn token( })) }, v0::OAuth2GrantType::Implicit => { + // token is already an access token so this endpoint does not need to be called - in theory this should be unreachable Err(create_error!(InvalidOperation)) } }