use axum::extract::{FromRequestParts, Path}; use axum::http::request::Parts; use jwt::Session; use serde::Deserialize; use utoipa::IntoParams; use crate::errors::ApiError; use crate::service::GitService; use crate::share::access; #[derive(Debug, Clone, Deserialize, IntoParams)] pub struct RepoPath { pub space_name: String, pub repo_name: String, } #[derive(Debug, Clone, Deserialize, IntoParams)] pub struct RepoPathRev { pub space_name: String, pub repo_name: String, pub revision: String, } impl FromRequestParts for RepoPath where S: Send + Sync, { type Rejection = ApiError; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { Path::::from_request_parts(parts, state) .await .map(|Path(p)| p) .map_err(|_| ApiError::bad_request()) } } pub fn ensure_caller(session: &Session) -> Result { session.uid().ok_or(ApiError::unauthorized()) } pub async fn resolve_reader( service: &GitService, session: &Session, space_name: String, repo_name: String, ) -> Result<(crate::context::facade::GitContext, Option), ApiError> { let ctx = service .context(space_name, repo_name) .await .map_err(super::super::errors::GitApiError::from)?; if ctx.model.is_private { let uid = session.uid().ok_or(ApiError::unauthorized())?; access::authorize_repo_access(service, uid, &ctx, false, false) .await .map_err(super::super::errors::GitApiError::from)?; Ok((ctx, Some(uid))) } else { Ok((ctx, session.uid())) } } pub async fn ensure_read_access( service: &GitService, session: &Session, ctx: &crate::context::facade::GitContext, ) -> Result, ApiError> { if ctx.model.is_private { let uid = session.uid().ok_or(ApiError::unauthorized())?; access::authorize_repo_access(service, uid, ctx, false, false) .await .map_err(super::super::errors::GitApiError::from)?; Ok(Some(uid)) } else { Ok(session.uid()) } } pub async fn require_writer( service: &GitService, session: &Session, space_name: String, repo_name: String, ) -> Result<(crate::context::facade::GitContext, i64), ApiError> { let ctx = service .context(space_name, repo_name) .await .map_err(super::super::errors::GitApiError::from)?; let uid = session.uid().ok_or(ApiError::unauthorized())?; access::authorize_repo_access(service, uid, &ctx, true, false) .await .map_err(super::super::errors::GitApiError::from)?; Ok((ctx, uid)) } pub async fn require_repo_admin( service: &GitService, session: &Session, space_name: String, repo_name: String, ) -> Result<(crate::context::facade::GitContext, i64), ApiError> { let ctx = service .context(space_name, repo_name) .await .map_err(super::super::errors::GitApiError::from)?; let uid = session.uid().ok_or(ApiError::unauthorized())?; access::authorize_repo_access(service, uid, &ctx, true, true) .await .map_err(super::super::errors::GitApiError::from)?; Ok((ctx, uid)) }