Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
25 changes: 9 additions & 16 deletions src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,13 @@ pub async fn registry_v2_check(

pub async fn auth_handler(
State(state): State<Arc<AppState>>,
Query(auth_req): Query<AuthRequest>,
Query(params): Query<Vec<(String, String)>>,
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"
);
Expand Down Expand Up @@ -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];

Expand Down Expand Up @@ -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 {
Expand All @@ -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) => {
Expand Down
19 changes: 17 additions & 2 deletions src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,28 @@ pub struct AccessEntry {
pub actions: Vec<String>,
}

#[derive(Debug, Deserialize)]
#[derive(Debug, Default)]
pub struct AuthRequest {
pub service: Option<String>,
pub scope: Option<String>,
pub scope: Vec<String>,
pub account: Option<String>,
}

impl From<Vec<(String, String)>> 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,
Expand Down