You've already forked AstralRinth
forked from didirus/AstralRinth
@@ -2,8 +2,9 @@ use crate::auth::flows::AuthProvider;
|
||||
use crate::auth::session::get_session_metadata;
|
||||
use crate::auth::AuthenticationError;
|
||||
use crate::database::models::user_item;
|
||||
use crate::models::pats::Scopes;
|
||||
use crate::models::users::{Role, User, UserId, UserPayoutData};
|
||||
use crate::queue::session::SessionQueue;
|
||||
use crate::queue::session::AuthQueue;
|
||||
use actix_web::HttpRequest;
|
||||
use chrono::Utc;
|
||||
use reqwest::header::{HeaderValue, AUTHORIZATION};
|
||||
@@ -12,8 +13,9 @@ pub async fn get_user_from_headers<'a, E>(
|
||||
req: &HttpRequest,
|
||||
executor: E,
|
||||
redis: &deadpool_redis::Pool,
|
||||
session_queue: &SessionQueue,
|
||||
) -> Result<User, AuthenticationError>
|
||||
session_queue: &AuthQueue,
|
||||
required_scopes: Option<&[Scopes]>,
|
||||
) -> Result<(Scopes, User), AuthenticationError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
|
||||
{
|
||||
@@ -21,7 +23,7 @@ where
|
||||
let token: Option<&HeaderValue> = headers.get(AUTHORIZATION);
|
||||
|
||||
// Fetch DB user record and minos user from headers
|
||||
let db_user = get_user_record_from_bearer_token(
|
||||
let (scopes, db_user) = get_user_record_from_bearer_token(
|
||||
req,
|
||||
token
|
||||
.ok_or_else(|| AuthenticationError::InvalidAuthMethod)?
|
||||
@@ -57,7 +59,16 @@ where
|
||||
payout_address: db_user.payout_address,
|
||||
}),
|
||||
};
|
||||
Ok(user)
|
||||
|
||||
if let Some(required_scopes) = required_scopes {
|
||||
for scope in required_scopes {
|
||||
if !scopes.contains(*scope) {
|
||||
return Err(AuthenticationError::InvalidCredentials);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok((scopes, user))
|
||||
}
|
||||
|
||||
pub async fn get_user_record_from_bearer_token<'a, 'b, E>(
|
||||
@@ -65,13 +76,28 @@ pub async fn get_user_record_from_bearer_token<'a, 'b, E>(
|
||||
token: &str,
|
||||
executor: E,
|
||||
redis: &deadpool_redis::Pool,
|
||||
session_queue: &SessionQueue,
|
||||
) -> Result<Option<user_item::User>, AuthenticationError>
|
||||
session_queue: &AuthQueue,
|
||||
) -> Result<Option<(Scopes, user_item::User)>, AuthenticationError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
|
||||
{
|
||||
let possible_user = match token.split_once('_') {
|
||||
//Some(("modrinth", _)) => get_user_from_pat(token, executor).await?,
|
||||
Some(("mrp", _)) => {
|
||||
let pat =
|
||||
crate::database::models::pat_item::PersonalAccessToken::get(token, executor, redis)
|
||||
.await?
|
||||
.ok_or_else(|| AuthenticationError::InvalidCredentials)?;
|
||||
|
||||
if pat.expires < Utc::now() {
|
||||
return Err(AuthenticationError::InvalidCredentials);
|
||||
}
|
||||
|
||||
let user = user_item::User::get_id(pat.user_id, executor, redis).await?;
|
||||
|
||||
session_queue.add_pat(pat.id).await;
|
||||
|
||||
user.map(|x| (pat.scopes, x))
|
||||
}
|
||||
Some(("mra", _)) => {
|
||||
let session =
|
||||
crate::database::models::session_item::Session::get(token, executor, redis)
|
||||
@@ -85,23 +111,31 @@ where
|
||||
let user = user_item::User::get_id(session.user_id, executor, redis).await?;
|
||||
|
||||
let rate_limit_ignore = dotenvy::var("RATE_LIMIT_IGNORE_KEY")?;
|
||||
if !req.headers().get("x-ratelimit-key").and_then(|x| x.to_str().ok()).map(|x| x == rate_limit_ignore).unwrap_or(false) {
|
||||
if !req
|
||||
.headers()
|
||||
.get("x-ratelimit-key")
|
||||
.and_then(|x| x.to_str().ok())
|
||||
.map(|x| x == rate_limit_ignore)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
let metadata = get_session_metadata(req).await?;
|
||||
session_queue.add(session.id, metadata).await;
|
||||
session_queue.add_session(session.id, metadata).await;
|
||||
}
|
||||
|
||||
user
|
||||
user.map(|x| (Scopes::ALL, x))
|
||||
}
|
||||
Some(("github", _)) | Some(("gho", _)) | Some(("ghp", _)) => {
|
||||
let user = AuthProvider::GitHub.get_user(token).await?;
|
||||
let id = AuthProvider::GitHub.get_user_id(&user.id, executor).await?;
|
||||
|
||||
user_item::User::get_id(
|
||||
let user = user_item::User::get_id(
|
||||
id.ok_or_else(|| AuthenticationError::InvalidCredentials)?,
|
||||
executor,
|
||||
redis,
|
||||
)
|
||||
.await?
|
||||
.await?;
|
||||
|
||||
user.map(|x| (Scopes::ALL, x))
|
||||
}
|
||||
_ => return Err(AuthenticationError::InvalidAuthMethod),
|
||||
};
|
||||
@@ -112,12 +146,14 @@ pub async fn check_is_moderator_from_headers<'a, 'b, E>(
|
||||
req: &HttpRequest,
|
||||
executor: E,
|
||||
redis: &deadpool_redis::Pool,
|
||||
session_queue: &SessionQueue,
|
||||
session_queue: &AuthQueue,
|
||||
) -> Result<User, AuthenticationError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
|
||||
{
|
||||
let user = get_user_from_headers(req, executor, redis, session_queue).await?;
|
||||
let user = get_user_from_headers(req, executor, redis, session_queue, None)
|
||||
.await?
|
||||
.1;
|
||||
|
||||
if user.role.is_mod() {
|
||||
Ok(user)
|
||||
|
||||
Reference in New Issue
Block a user