gitdataai/lib/git/http/utils.rs
2026-05-30 01:38:40 +08:00

99 lines
3.1 KiB
Rust

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<RepoModel, Error> {
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()))
}