#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum DeploymentProfile {
#[default]
Unprofiled,
RegulatedMultiTenant,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum ProfileViolation {
#[error(
"regulated profile requires tenant binding: \
call with_tenant_binding[_strict](kv) before build"
)]
MissingTenantKv,
#[error(
"regulated profile requires a named (non-anonymous) principal: \
wire a non-anonymous Authenticator (not AllowAnonymous)"
)]
AnonymousAuth,
}
impl DeploymentProfile {
pub fn requires_strict_binding(self) -> bool {
matches!(self, Self::RegulatedMultiTenant)
}
pub fn requires_named_principal(self) -> bool {
matches!(self, Self::RegulatedMultiTenant)
}
pub fn validate(
self,
has_tenant_kv: bool,
authenticator_allows_anonymous: Option<bool>,
) -> Result<(), ProfileViolation> {
if self.requires_strict_binding() && !has_tenant_kv {
return Err(ProfileViolation::MissingTenantKv);
}
if self.requires_named_principal() && authenticator_allows_anonymous != Some(false) {
return Err(ProfileViolation::AnonymousAuth);
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unprofiled_requires_no_guards() {
let p = DeploymentProfile::Unprofiled;
assert!(!p.requires_strict_binding());
assert!(!p.requires_named_principal());
}
#[test]
fn regulated_requires_strict_binding_and_named_principal() {
let p = DeploymentProfile::RegulatedMultiTenant;
assert!(p.requires_strict_binding());
assert!(p.requires_named_principal());
}
#[test]
fn unprofiled_validates_any_config() {
assert_eq!(DeploymentProfile::Unprofiled.validate(false, None), Ok(()));
}
#[test]
fn regulated_without_tenant_kv_is_missing_kv() {
let err = DeploymentProfile::RegulatedMultiTenant
.validate(false, Some(false))
.unwrap_err();
assert_eq!(err, ProfileViolation::MissingTenantKv);
}
#[test]
fn regulated_with_anonymous_authenticator_is_anonymous_auth() {
let err = DeploymentProfile::RegulatedMultiTenant
.validate(true, Some(true))
.unwrap_err();
assert_eq!(err, ProfileViolation::AnonymousAuth);
}
#[test]
fn regulated_without_any_authenticator_is_anonymous_auth() {
let err = DeploymentProfile::RegulatedMultiTenant
.validate(true, None)
.unwrap_err();
assert_eq!(err, ProfileViolation::AnonymousAuth);
}
#[test]
fn regulated_with_named_principal_and_kv_is_ok() {
assert_eq!(
DeploymentProfile::RegulatedMultiTenant.validate(true, Some(false)),
Ok(())
);
}
}