use super::*;
impl BucketWarden {
pub fn register_sigv4_credentials(
&mut self,
principal: impl Into<String>,
access_key_id: impl Into<String>,
secret_access_key: impl Into<String>,
) -> Result<(), RuntimeError> {
let principal = principal.into();
self.auth.create_local_user(principal.clone());
self.auth
.put_access_key(AccessKey::active(
principal,
access_key_id,
secret_access_key,
))
.map_err(RuntimeError::Auth)
}
pub fn register_sigv4_session_credentials(
&mut self,
principal: impl Into<String>,
access_key_id: impl Into<String>,
secret_access_key: impl Into<String>,
session_token: impl Into<String>,
) -> Result<(), RuntimeError> {
let principal = principal.into();
let access_key_id = access_key_id.into();
self.auth.create_local_user(principal.clone());
let parent_access_key_id = format!("{access_key_id}:parent");
self.auth
.put_access_key(AccessKey::active(
principal.clone(),
parent_access_key_id.clone(),
"bucketwarden-session-parent",
))
.map_err(RuntimeError::Auth)?;
self.auth
.put_session(SessionCredential::new(
principal,
parent_access_key_id,
access_key_id,
secret_access_key,
session_token,
u64::MAX,
))
.map_err(RuntimeError::Auth)
}
pub fn create_local_user(&mut self, principal: impl Into<String>) {
self.auth.create_local_user(principal);
}
pub fn create_tenant(&mut self, tenant_id: impl Into<String>) {
self.auth.create_tenant(tenant_id);
}
pub fn create_local_user_in_tenant(
&mut self,
principal: impl Into<String>,
tenant_id: impl Into<String>,
) -> Result<(), RuntimeError> {
self.auth
.create_local_user_in_tenant(principal, tenant_id)
.map_err(RuntimeError::Auth)
}
pub fn create_custom_identity(
&mut self,
principal: impl Into<String>,
shared_secret: impl Into<String>,
) -> Result<(), RuntimeError> {
self.auth
.create_custom_identity(principal, shared_secret)
.map_err(RuntimeError::Auth)
}
pub fn create_service_account(&mut self, principal: impl Into<String>) {
self.auth.create_service_account(principal);
}
pub fn create_service_account_in_tenant(
&mut self,
principal: impl Into<String>,
tenant_id: impl Into<String>,
) -> Result<(), RuntimeError> {
self.auth
.create_service_account_in_tenant(principal, tenant_id)
.map_err(RuntimeError::Auth)
}
pub fn principal_tenant_id(&self, principal: &str) -> String {
self.auth
.principal_tenant_id(principal)
.unwrap_or(DEFAULT_TENANT_ID)
.to_string()
}
pub fn assign_operator_role(
&mut self,
actor: &str,
principal: impl Into<String>,
role: OperatorRole,
scope: impl Into<String>,
) -> Result<RoleAssignment, RuntimeError> {
let assignment = self.auth.assign_operator_role(principal, role, scope)?;
self.audit.append(
actor,
"auth:AssignOperatorRole",
&assignment.principal_id,
AuditOutcome::Allowed,
Some(format!("{:?}:{}", assignment.role, assignment.scope)),
);
Ok(assignment)
}
pub fn operator_role_assignments(&self, principal: &str) -> Vec<RoleAssignment> {
self.auth.role_assignments(principal)
}
pub fn operator_action_allowed(
&self,
principal: &str,
action: OperatorAction,
resource: &str,
) -> Result<bool, RuntimeError> {
self.auth
.operator_action_allowed(principal, action, resource)
.map_err(RuntimeError::Auth)
}
pub fn upsert_identity_provider(&mut self, provider: IdentityProvider) {
self.auth.upsert_identity_provider(provider);
}
pub fn identity_provider_count(&self) -> usize {
self.auth.identity_provider_count()
}
pub fn identity_provider_support_report(&self) -> IdentityProviderSupportReport {
self.auth.identity_provider_support_report()
}
pub fn credential_support_report(&self) -> CredentialSupportReport {
self.auth.credential_support_report()
}
pub fn temporary_credential_support_report(&self) -> TemporaryCredentialSupportReport {
self.auth.temporary_credential_support_report()
}
pub fn create_access_key(
&mut self,
principal: impl Into<String>,
access_key_id: impl Into<String>,
secret_access_key: impl Into<String>,
) -> Result<(), RuntimeError> {
self.auth
.put_access_key(AccessKey::active(
principal,
access_key_id,
secret_access_key,
))
.map_err(RuntimeError::Auth)
}
pub fn create_access_key_with_expiry(
&mut self,
principal: impl Into<String>,
access_key_id: impl Into<String>,
secret_access_key: impl Into<String>,
expires_at_epoch_seconds: u64,
) -> Result<(), RuntimeError> {
self.auth
.put_access_key(
AccessKey::active(principal, access_key_id, secret_access_key)
.with_expiry(expires_at_epoch_seconds),
)
.map_err(RuntimeError::Auth)
}
pub fn create_session_credential(
&mut self,
principal: impl Into<String>,
parent_access_key_id: impl Into<String>,
access_key_id: impl Into<String>,
secret_access_key: impl Into<String>,
session_token: impl Into<String>,
expires_at_epoch_seconds: u64,
) -> Result<(), RuntimeError> {
self.auth
.put_session(SessionCredential::new(
principal,
parent_access_key_id,
access_key_id,
secret_access_key,
session_token,
expires_at_epoch_seconds,
))
.map_err(RuntimeError::Auth)
}
pub fn assume_role_with_web_identity(
&mut self,
request: AssumeRoleWithWebIdentityRequest,
) -> Result<SessionCredential, RuntimeError> {
let provider_id = request.provider_id.clone();
let access_key_id = request.access_key_id.clone();
match self
.auth
.assume_role_with_web_identity(request, self.clock_epoch_seconds)
{
Ok(session) => {
self.audit.append(
&session.principal_id,
"auth:AssumeRoleWithWebIdentity",
&session.access_key_id,
AuditOutcome::Allowed,
session.scope.as_ref().map(|scope| {
format!(
"scope={:?}/{:?}",
scope.allowed_actions, scope.resource_prefixes
)
}),
);
Ok(session)
}
Err(error) => {
self.audit.append(
"anonymous",
"auth:AssumeRoleWithWebIdentity",
access_key_id,
AuditOutcome::Failed,
Some(format!("{provider_id}: {error}")),
);
Err(RuntimeError::Auth(error))
}
}
}
pub fn revoke_credential(&mut self, access_key_id: &str) -> Result<(), RuntimeError> {
self.auth
.revoke_credential(access_key_id, self.clock_epoch_seconds)
.map_err(RuntimeError::Auth)
}
pub fn rotate_access_key(
&mut self,
actor: &str,
old_access_key_id: &str,
new_access_key_id: impl Into<String>,
new_secret_access_key: impl Into<String>,
) -> Result<CredentialRotation, RuntimeError> {
let rotation = self.auth.rotate_access_key(
old_access_key_id,
new_access_key_id,
new_secret_access_key,
self.clock_epoch_seconds,
)?;
self.audit.append(
actor,
"auth:RotateAccessKey",
&rotation.new_access_key_id,
AuditOutcome::Allowed,
Some(format!("replaced={}", rotation.old_access_key_id)),
);
Ok(rotation)
}
pub fn report_leaked_access_key(
&mut self,
actor: &str,
access_key_id: &str,
) -> Result<LeakedKeyResponse, RuntimeError> {
let response = self
.auth
.report_leaked_access_key(access_key_id, self.clock_epoch_seconds)?;
self.audit.append(
actor,
"auth:ReportLeakedAccessKey",
access_key_id,
AuditOutcome::Allowed,
Some("credential revoked".to_string()),
);
Ok(response)
}
pub fn disable_access_key(&mut self, access_key_id: &str) -> Result<(), RuntimeError> {
self.auth
.disable_access_key(access_key_id)
.map_err(RuntimeError::Auth)
}
pub fn credential(&self, access_key_id: &str) -> Option<&CredentialRecord> {
self.auth.credential(access_key_id)
}
}