mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-13 21:17:05 +00:00
fix: add more oauth2 checks
This commit is contained in:
@@ -49,6 +49,7 @@ auto_derived_partial!(
|
||||
|
||||
auto_derived!(
|
||||
#[derive(Copy, Hash)]
|
||||
#[serde(rename = "lowercase")]
|
||||
pub enum OAuth2Scope {
|
||||
Identify,
|
||||
Full,
|
||||
|
||||
@@ -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<Option<String>> {
|
||||
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))
|
||||
}
|
||||
@@ -77,6 +77,7 @@ auto_derived!(
|
||||
}
|
||||
|
||||
#[derive(Copy, Hash)]
|
||||
#[cfg_attr(feature = "serde", serde(rename = "lowercase"))]
|
||||
pub enum OAuth2Scope {
|
||||
Identify,
|
||||
Full,
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -17,6 +17,10 @@ pub async fn auth(
|
||||
user: User,
|
||||
info: v0::OAuth2AuthorizationForm,
|
||||
) -> Result<Json<v0::OAuth2AuthorizeAuthResponse>> {
|
||||
if user.bot.is_some() {
|
||||
return Err(create_error!(IsBot));
|
||||
};
|
||||
|
||||
let bot = Reference::from_unchecked(info.client_id.clone())
|
||||
.as_bot(db)
|
||||
.await?;
|
||||
|
||||
@@ -13,6 +13,10 @@ pub async fn info(
|
||||
user: User,
|
||||
info: v0::OAuth2AuthorizationForm,
|
||||
) -> Result<Json<v0::OAuth2AuthorizeInfoResponse>> {
|
||||
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);
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user