diff --git a/src/auth.rs b/src/auth.rs index 49d7ed0..0d7a405 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -34,7 +34,7 @@ pub fn generate_token( let mut access = Vec::new(); - if let Some(scope) = &auth_request.scope { + for scope in &auth_request.scope { let parts: Vec<&str> = scope.split(':').collect(); if parts.len() >= 3 { let resource_type = parts[0]; // "repository" diff --git a/src/handlers.rs b/src/handlers.rs index 286ff80..e9ce7ed 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -154,12 +154,13 @@ pub async fn registry_v2_check( pub async fn auth_handler( State(state): State>, - Query(auth_req): Query, + Query(params): Query>, headers: HeaderMap, ) -> impl IntoResponse { + let auth_req = AuthRequest::from(params); debug!( service = auth_req.service, - scope = auth_req.scope, + scope = ?auth_req.scope, account = auth_req.account, "Auth request" ); @@ -248,8 +249,8 @@ pub async fn auth_handler( // Check scope permissions if specified let mut auth_req = auth_req; - if let Some(scope_str) = &auth_req.scope { - let scope_parts: Vec<&str> = scope_str.split(':').collect(); + for scope in &mut auth_req.scope { + let scope_parts: Vec<&str> = scope.split(':').collect(); if scope_parts.len() >= 2 { let scope_name = scope_parts[1]; @@ -299,12 +300,8 @@ pub async fn auth_handler( let mut scope_parts_clone = scope_parts.clone(); let library_scope = format!("library/{}", scope_parts_clone[1]); scope_parts_clone[1] = &library_scope; - info!( - "Converted scope {} -> {}", - auth_req.scope.clone().unwrap_or_default(), - library_scope - ); - auth_req.scope = Some(scope_parts_clone.join(":")); + info!("Converted scope {} -> {}", scope, library_scope); + *scope = scope_parts_clone.join(":"); } else { // Check if user is admin of the specified game scope match state.database.get_game_by_namespace(namespace).await { @@ -328,12 +325,8 @@ pub async fn auth_handler( let scope_name = scope_image_parts.join("/"); scope_parts[1] = &scope_name; let new_scope = scope_parts.join(":"); - info!( - "Converted scope {} -> {}", - auth_req.scope.unwrap_or_default(), - new_scope - ); - auth_req.scope = Some(new_scope); + info!("Converted scope {} -> {}", scope, new_scope); + *scope = new_scope; } } Ok(None) => { diff --git a/src/models.rs b/src/models.rs index 56df107..11895b8 100644 --- a/src/models.rs +++ b/src/models.rs @@ -184,13 +184,28 @@ pub struct AccessEntry { pub actions: Vec, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Default)] pub struct AuthRequest { pub service: Option, - pub scope: Option, + pub scope: Vec, pub account: Option, } +impl From> for AuthRequest { + fn from(params: Vec<(String, String)>) -> Self { + let mut request = Self::default(); + for (key, value) in params { + match key.as_str() { + "service" => request.service = Some(value), + "scope" => request.scope.push(value), + "account" => request.account = Some(value), + _ => {} + } + } + request + } +} + #[derive(Debug, Serialize)] pub struct AuthResponse { pub token: String,