You've already forked AstralRinth
forked from didirus/AstralRinth
OAuth 2.0 Authorization Server [MOD-559] (#733)
* WIP end-of-day push * Authorize endpoint, accept endpoints, DB stuff for oauth clients, their redirects, and client authorizations * OAuth Client create route * Get user clients * Client delete * Edit oauth client * Include redirects in edit client route * Database stuff for tokens * Reorg oauth stuff out of auth/flows and into its own module * Impl OAuth get access token endpoint * Accept oauth access tokens as auth and update through AuthQueue * User OAuth authorization management routes * Forgot to actually add the routes lol * Bit o cleanup * Happy path test for OAuth and minor fixes for things it found * Add dummy data oauth client (and detect/handle dummy data version changes) * More tests * Another test * More tests and reject endpoint * Test oauth client and authorization management routes * cargo sqlx prepare * dead code warning * Auto clippy fixes * Uri refactoring * minor name improvement * Don't compile-time check the test sqlx queries * Trying to fix db concurrency problem to get tests to pass * Try fix from test PR * Fixes for updated sqlx * Prevent restricted scopes from being requested or issued * Get OAuth client(s) * Remove joined oauth client info from authorization returns * Add default conversion to OAuthError::error so we can use ? * Rework routes * Consolidate scopes into SESSION_ACCESS * Cargo sqlx prepare * Parse to OAuthClientId automatically through serde and actix * Cargo clippy * Remove validation requiring 1 redirect URI on oauth client creation * Use serde(flatten) on OAuthClientCreationResult
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
use super::ids::*;
|
||||
use crate::auth::flows::AuthProvider;
|
||||
use crate::auth::oauth::uris::OAuthRedirectUris;
|
||||
use crate::database::models::DatabaseError;
|
||||
use crate::database::redis::RedisPool;
|
||||
use crate::{auth::flows::AuthProvider, models::pats::Scopes};
|
||||
use chrono::Duration;
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::Rng;
|
||||
@@ -34,6 +35,21 @@ pub enum Flow {
|
||||
confirm_email: String,
|
||||
},
|
||||
MinecraftAuth,
|
||||
InitOAuthAppApproval {
|
||||
user_id: UserId,
|
||||
client_id: OAuthClientId,
|
||||
existing_authorization_id: Option<OAuthClientAuthorizationId>,
|
||||
scopes: Scopes,
|
||||
redirect_uris: OAuthRedirectUris,
|
||||
state: Option<String>,
|
||||
},
|
||||
OAuthAuthorizationCodeSupplied {
|
||||
user_id: UserId,
|
||||
client_id: OAuthClientId,
|
||||
authorization_id: OAuthClientAuthorizationId,
|
||||
scopes: Scopes,
|
||||
original_redirect_uri: Option<String>, // Needed for https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
|
||||
},
|
||||
}
|
||||
|
||||
impl Flow {
|
||||
@@ -58,6 +74,22 @@ impl Flow {
|
||||
redis.get_deserialized_from_json(FLOWS_NAMESPACE, id).await
|
||||
}
|
||||
|
||||
/// Gets the flow and removes it from the cache, but only removes if the flow was present and the predicate returned true
|
||||
/// The predicate should validate that the flow being removed is the correct one, as a security measure
|
||||
pub async fn take_if(
|
||||
id: &str,
|
||||
predicate: impl FnOnce(&Flow) -> bool,
|
||||
redis: &RedisPool,
|
||||
) -> Result<Option<Flow>, DatabaseError> {
|
||||
let flow = Self::get(id, redis).await?;
|
||||
if let Some(flow) = flow.as_ref() {
|
||||
if predicate(flow) {
|
||||
Self::remove(id, redis).await?;
|
||||
}
|
||||
}
|
||||
Ok(flow)
|
||||
}
|
||||
|
||||
pub async fn remove(id: &str, redis: &RedisPool) -> Result<Option<()>, DatabaseError> {
|
||||
redis.delete(FLOWS_NAMESPACE, id).await?;
|
||||
Ok(Some(()))
|
||||
|
||||
Reference in New Issue
Block a user