use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use thiserror::Error;
use crate::admin_roles::RoleAssignment;
use crate::credentials::CredentialRecord;
use crate::credentials::MtlsClientCertificate;
use crate::identity::{CustomIdentity, Principal, Tenant};
use crate::providers::IdentityProvider;
use crate::sts::CredentialScope;
use bucketwarden_s3::sigv4::AwsCredentials;
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct AuthStore {
#[serde(default)]
pub(crate) tenants: BTreeMap<String, Tenant>,
pub(crate) principals: BTreeMap<String, Principal>,
pub(crate) credentials: BTreeMap<String, CredentialRecord>,
#[serde(default)]
pub(crate) mtls_certificates: BTreeMap<String, MtlsClientCertificate>,
#[serde(default)]
pub(crate) role_assignments: BTreeMap<String, Vec<RoleAssignment>>,
#[serde(default)]
pub(crate) identity_providers: BTreeMap<String, IdentityProvider>,
#[serde(default)]
pub(crate) custom_identities: BTreeMap<String, CustomIdentity>,
#[serde(default)]
pub(crate) login_attempts: BTreeMap<String, LoginAttemptRecord>,
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct LoginAttemptRecord {
pub principal_id: String,
pub consecutive_failed_attempts: u32,
pub last_failed_epoch_seconds: Option<u64>,
pub last_success_epoch_seconds: Option<u64>,
pub last_failure_detail: Option<String>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ResolvedCredential {
pub principal_id: String,
pub tenant_id: String,
pub access_key_id: String,
pub credentials: AwsCredentials,
pub scope: Option<CredentialScope>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ResolvedMtlsIdentity {
pub principal_id: String,
pub tenant_id: String,
pub certificate_fingerprint: String,
}
#[derive(Clone, Debug, Error, Eq, PartialEq)]
pub enum AuthError {
#[error("unknown tenant: {0}")]
UnknownTenant(String),
#[error("disabled tenant: {0}")]
DisabledTenant(String),
#[error("unknown principal: {0}")]
UnknownPrincipal(String),
#[error("disabled principal: {0}")]
DisabledPrincipal(String),
#[error("unknown access key: {0}")]
UnknownAccessKey(String),
#[error("unknown parent access key: {0}")]
UnknownParentAccessKey(String),
#[error("disabled access key: {0}")]
DisabledAccessKey(String),
#[error("unknown client certificate: {0}")]
UnknownClientCertificate(String),
#[error("disabled client certificate: {0}")]
DisabledClientCertificate(String),
#[error("revoked credential: {0}")]
RevokedCredential(String),
#[error("expired credential: {0}")]
ExpiredCredential(String),
#[error("not an access key: {0}")]
NotAccessKey(String),
#[error("unknown identity provider: {0}")]
UnknownIdentityProvider(String),
#[error("invalid web identity token: {0}")]
InvalidWebIdentityToken(String),
#[error("web identity token issuer mismatch: {0}")]
WebIdentityIssuerMismatch(String),
#[error("web identity token audience mismatch: {0}")]
WebIdentityAudienceMismatch(String),
#[error("web identity token expired")]
WebIdentityTokenExpired,
#[error("unsupported web identity token algorithm: {0}")]
UnsupportedWebIdentityAlgorithm(String),
#[error("web identity key id mismatch: {0}")]
WebIdentityKeyIdMismatch(String),
#[error("invalid identity provider token: {0}")]
InvalidIdentityProviderToken(String),
#[error("unknown directory subject: {0}")]
UnknownDirectorySubject(String),
#[error("disabled directory subject: {0}")]
DisabledDirectorySubject(String),
#[error("unsupported identity provider kind: {0}")]
UnsupportedIdentityProviderKind(String),
#[error(
"role assumption denied for principal {principal_id} on {role_resource} as {role_name}"
)]
RoleAssumptionDenied {
principal_id: String,
role_name: String,
role_resource: String,
},
#[error("unknown custom identity: {0}")]
UnknownCustomIdentity(String),
#[error("disabled custom identity: {0}")]
DisabledCustomIdentity(String),
#[error("invalid custom identity secret: {0}")]
InvalidCustomIdentitySecret(String),
#[error("too many failed login attempts for principal: {0}")]
TooManyLoginAttempts(String),
}