ba6fe0f
use std::future::Future;
use std::pin::Pin;
use actix_web::dev::Payload;
use actix_web::{FromRequest, HttpRequest};
use token::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 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 fn ensure_caller(session: &Session) -> Result<i64, ApiError> {
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<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 = 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<Option<i64>, 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))
}