use serde::{Deserialize, Serialize};
pub const DEFAULT_TENANT_ID: &str = "default";
fn default_tenant_id() -> String {
DEFAULT_TENANT_ID.to_string()
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Tenant {
pub id: String,
pub enabled: bool,
}
impl Tenant {
pub fn active(id: impl Into<String>) -> Self {
Self {
id: id.into(),
enabled: true,
}
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum PrincipalKind {
LocalUser,
ServiceAccount,
FederatedWebIdentity,
LdapUser,
ActiveDirectoryUser,
SamlSubject,
MtlsClient,
CustomIdentity,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Principal {
pub id: String,
pub kind: PrincipalKind,
#[serde(default = "default_tenant_id")]
pub tenant_id: String,
pub enabled: bool,
}
impl Principal {
pub fn local_user(id: impl Into<String>) -> Self {
Self::local_user_in_tenant(id, DEFAULT_TENANT_ID)
}
pub fn local_user_in_tenant(id: impl Into<String>, tenant_id: impl Into<String>) -> Self {
Self {
id: id.into(),
kind: PrincipalKind::LocalUser,
tenant_id: tenant_id.into(),
enabled: true,
}
}
pub fn service_account(id: impl Into<String>) -> Self {
Self::service_account_in_tenant(id, DEFAULT_TENANT_ID)
}
pub fn service_account_in_tenant(id: impl Into<String>, tenant_id: impl Into<String>) -> Self {
Self {
id: id.into(),
kind: PrincipalKind::ServiceAccount,
tenant_id: tenant_id.into(),
enabled: true,
}
}
pub fn federated_web_identity(id: impl Into<String>) -> Self {
Self::federated_web_identity_in_tenant(id, DEFAULT_TENANT_ID)
}
pub fn federated_web_identity_in_tenant(
id: impl Into<String>,
tenant_id: impl Into<String>,
) -> Self {
Self::with_kind(id, PrincipalKind::FederatedWebIdentity, tenant_id)
}
pub fn ldap_user(id: impl Into<String>) -> Self {
Self::ldap_user_in_tenant(id, DEFAULT_TENANT_ID)
}
pub fn ldap_user_in_tenant(id: impl Into<String>, tenant_id: impl Into<String>) -> Self {
Self::with_kind(id, PrincipalKind::LdapUser, tenant_id)
}
pub fn active_directory_user(id: impl Into<String>) -> Self {
Self::active_directory_user_in_tenant(id, DEFAULT_TENANT_ID)
}
pub fn active_directory_user_in_tenant(
id: impl Into<String>,
tenant_id: impl Into<String>,
) -> Self {
Self::with_kind(id, PrincipalKind::ActiveDirectoryUser, tenant_id)
}
pub fn saml_subject(id: impl Into<String>) -> Self {
Self::saml_subject_in_tenant(id, DEFAULT_TENANT_ID)
}
pub fn saml_subject_in_tenant(id: impl Into<String>, tenant_id: impl Into<String>) -> Self {
Self::with_kind(id, PrincipalKind::SamlSubject, tenant_id)
}
pub fn mtls_client(id: impl Into<String>) -> Self {
Self::mtls_client_in_tenant(id, DEFAULT_TENANT_ID)
}
pub fn mtls_client_in_tenant(id: impl Into<String>, tenant_id: impl Into<String>) -> Self {
Self::with_kind(id, PrincipalKind::MtlsClient, tenant_id)
}
pub fn custom_identity(id: impl Into<String>) -> Self {
Self::custom_identity_in_tenant(id, DEFAULT_TENANT_ID)
}
pub fn custom_identity_in_tenant(id: impl Into<String>, tenant_id: impl Into<String>) -> Self {
Self::with_kind(id, PrincipalKind::CustomIdentity, tenant_id)
}
pub fn with_kind(
id: impl Into<String>,
kind: PrincipalKind,
tenant_id: impl Into<String>,
) -> Self {
Self {
id: id.into(),
kind,
tenant_id: tenant_id.into(),
enabled: true,
}
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct CustomIdentity {
pub principal_id: String,
shared_secret: String,
pub enabled: bool,
}
impl CustomIdentity {
pub fn active(principal_id: impl Into<String>, shared_secret: impl Into<String>) -> Self {
Self {
principal_id: principal_id.into(),
shared_secret: shared_secret.into(),
enabled: true,
}
}
pub fn disable(&mut self) {
self.enabled = false;
}
pub fn verify_secret(&self, shared_secret: &str) -> bool {
self.enabled && self.shared_secret == shared_secret
}
pub fn parent_secret(&self) -> String {
format!("bucketwarden-custom-identity-parent:{}", self.principal_id)
}
}