use actix_web::{Error, HttpRequest}; use base64::{Engine, engine::general_purpose::STANDARD}; use db::database::AppDatabase; use model::{ repos::RepoModel, workspace::{ wk_history_name::WkHistoryNameModel, workspace::WorkspaceModel, }, }; pub async fn get_repo_model( namespace: &str, repo_name: &str, db: &AppDatabase, ) -> Result { let wk_id = if let Some(wk) = sqlx::query_as::<_, WorkspaceModel>( "SELECT id, name, description, avatar_url, created_at FROM workspace WHERE name = $1", ) .bind(namespace) .fetch_optional(db.reader()) .await .map_err(|_| actix_web::error::ErrorInternalServerError("Database error"))? { wk.id } else if let Some(history) = sqlx::query_as::<_, WkHistoryNameModel>( "SELECT id, wk, name, changed_by, created_at FROM wk_history_name WHERE name = $1", ) .bind(namespace) .fetch_optional(db.reader()) .await .map_err(|_| actix_web::error::ErrorInternalServerError("Database error"))? { history.wk } else { return Err(actix_web::error::ErrorNotFound("Project not found").into()); }; let repo = sqlx::query_as::<_, RepoModel>( "SELECT id, wk, name, description, default_branch, visibility, size_bytes, \ is_archived, is_template, is_mirror, created_by, storage_path, \ created_at, updated_at, deleted_at \ FROM repo \ WHERE name = $1 AND wk = $2 AND deleted_at IS NULL", ) .bind(repo_name) .bind(wk_id) .fetch_optional(db.reader()) .await .map_err(|_| actix_web::error::ErrorInternalServerError("Database error"))? .ok_or_else(|| actix_web::error::ErrorNotFound("Repository not found"))?; Ok(repo) } pub fn extract_basic_credentials( req: &HttpRequest, ) -> Result<(String, String), Error> { let auth_header = req .headers() .get("authorization") .ok_or_else(|| { actix_web::error::ErrorUnauthorized("Missing authorization header") })? .to_str() .map_err(|_| { actix_web::error::ErrorUnauthorized("Invalid authorization header") })?; let encoded = auth_header.strip_prefix("Basic ").ok_or_else(|| { actix_web::error::ErrorUnauthorized("Invalid authorization scheme") })?; let decoded = STANDARD.decode(encoded).map_err(|_| { actix_web::error::ErrorUnauthorized( "Invalid basic authorization encoding", ) })?; let decoded = String::from_utf8(decoded).map_err(|_| { actix_web::error::ErrorUnauthorized( "Invalid basic authorization payload", ) })?; let (username, access_key) = decoded.split_once(':').ok_or_else(|| { actix_web::error::ErrorUnauthorized( "Invalid basic authorization format", ) })?; if username.is_empty() || access_key.is_empty() { return Err(actix_web::error::ErrorUnauthorized( "Username or access key is empty", )); } Ok((username.to_string(), access_key.to_string())) }