use gatekeep::Context;
use keepsake::{KeepsakeError, SubjectRef};
pub trait SubjectMapper: Send + Sync {
fn subject(&self, cx: &Context) -> Result<SubjectRef, KeepsakeError>;
}
#[derive(Clone, Copy, Debug, Default)]
pub struct TenantScopedSubjectMapper;
impl SubjectMapper for TenantScopedSubjectMapper {
fn subject(&self, cx: &Context) -> Result<SubjectRef, KeepsakeError> {
SubjectRef::new(
tenant_principal_kind(cx.tenant.as_str(), cx.principal.kind()),
cx.principal.id(),
)
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct PrincipalSubjectMapper;
impl SubjectMapper for PrincipalSubjectMapper {
fn subject(&self, cx: &Context) -> Result<SubjectRef, KeepsakeError> {
SubjectRef::new(cx.principal.kind(), cx.principal.id())
}
}
pub fn tenant_scoped_subject(cx: &Context) -> Result<SubjectRef, KeepsakeError> {
TenantScopedSubjectMapper.subject(cx)
}
pub fn principal_subject(cx: &Context) -> Result<SubjectRef, KeepsakeError> {
PrincipalSubjectMapper.subject(cx)
}
fn tenant_principal_kind(tenant: &str, principal_kind: &str) -> String {
format!(
"tenant:{}:{}principal:{}:{}",
tenant.len(),
tenant,
principal_kind.len(),
principal_kind
)
}