f934c68
use std::future::Future;
use std::pin::Pin;
use actix_web::dev::Payload;
use actix_web::{FromRequest, HttpRequest};
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 FromRequest for RepoPath {
type Error = ApiError;
type Future = Pin<Box<dyn Future<Output = Result<Self, Self::Error>>>>;
fn from_request(request: &HttpRequest, _payload: &mut Payload) -> Self::Future {
let request = request.clone();
Box::pin(async move {
actix_web::web::Path::<RepoPath>::from_request(&request, &mut Payload::None)
.await
.map(|value| value.into_inner())
.map_err(|_| ApiError::bad_request())
})
}
}
pub async fn resolve_reader(
service: &GitService,
viewer: Option<i64>,
space_name: String,
repo_name: String,
) -> Result<(crate::context::facade::GitContext, Option<i64>), ApiError> {
let ctx = service
.context(space_name, repo_name)
.await
.map_err(super::super::errors::GitApiError::from)?;
if ctx.model.is_private {
let uid = viewer.ok_or_else(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, viewer))
}
}
pub async fn ensure_read_access(
service: &GitService,
viewer: Option<i64>,
ctx: &crate::context::facade::GitContext,
) -> Result<Option<i64>, ApiError> {
if ctx.model.is_private {
let uid = viewer.ok_or_else(ApiError::unauthorized)?;
access::authorize_repo_access(service, uid, ctx, false, false)
.await
.map_err(super::super::errors::GitApiError::from)?;
Ok(Some(uid))
} else {
Ok(viewer)
}
}
pub async fn require_writer(
service: &GitService,
uid: i64,
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)?;
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,
uid: i64,
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)?;
access::authorize_repo_access(service, uid, &ctx, true, true)
.await
.map_err(super::super::errors::GitApiError::from)?;
Ok((ctx, uid))
}