use apiplant_abi::FunctionAccess;
use apiplant_auth::Principal;
use ntex::web::types::State;
use ntex::web::{HttpRequest, HttpResponse};
use crate::response::error;
use crate::state::AppState;
pub async fn check(
state: &State<AppState>,
req: &HttpRequest,
access: &FunctionAccess,
missing: &str,
) -> Result<Option<Principal>, HttpResponse> {
let principal = state.resolve_principal(req).await;
match access {
FunctionAccess::Public => {}
FunctionAccess::Private => return Err(error(404, missing.to_string())),
FunctionAccess::Authenticated => {
if principal.is_none() {
return Err(error(401, "authentication required"));
}
}
FunctionAccess::Member | FunctionAccess::Role(_) => {
if principal.is_none() {
return Err(error(401, "authentication required"));
}
let org = state.active_org(req, &principal);
let ok = match (access, org, principal.as_ref()) {
(FunctionAccess::Member, Some(org), Some(caller)) => caller.is_member(org),
(FunctionAccess::Role(required), Some(org), Some(caller)) => {
caller.has_role_in(org, required)
}
_ => false,
};
if !ok {
return Err(error(403, "forbidden"));
}
}
}
Ok(principal)
}