use super::*;
impl AuthStore {
pub fn assume_role_with_web_identity(
&mut self,
request: AssumeRoleWithWebIdentityRequest,
now_epoch_seconds: u64,
) -> Result<SessionCredential, AuthError> {
let provider = self
.identity_providers
.get(&request.provider_id)
.ok_or_else(|| AuthError::UnknownIdentityProvider(request.provider_id.clone()))?;
let subject = provider.verify_subject(&request.web_identity_token, now_epoch_seconds)?;
let principal_id = provider.principal_id(&subject);
let parent_secret = provider.parent_secret();
if !self.principals.contains_key(&principal_id) {
self.upsert_principal(provider.principal(&subject))?;
}
let parent_access_key_id = format!("web-identity-parent:{}", request.provider_id);
if !self.credentials.contains_key(&parent_access_key_id) {
self.put_access_key(AccessKey::active(
principal_id.clone(),
parent_access_key_id.clone(),
parent_secret,
))?;
}
let expires_at_epoch_seconds = now_epoch_seconds.saturating_add(request.duration_seconds);
let session = SessionCredential::new(
principal_id,
parent_access_key_id,
request.access_key_id,
request.secret_access_key,
request.session_token,
expires_at_epoch_seconds,
)
.with_scope(request.scope);
self.put_session(session.clone())?;
Ok(session)
}
pub fn assume_role_with_ldap(
&mut self,
request: AssumeRoleWithWebIdentityRequest,
now_epoch_seconds: u64,
) -> Result<SessionCredential, AuthError> {
match self.identity_providers.get(&request.provider_id) {
Some(IdentityProvider::Ldap(_)) => {
self.assume_role_with_web_identity(request, now_epoch_seconds)
}
Some(_) => Err(AuthError::UnsupportedIdentityProviderKind(
request.provider_id,
)),
None => Err(AuthError::UnknownIdentityProvider(request.provider_id)),
}
}
pub fn assume_role(
&mut self,
request: AssumeRoleRequest,
now_epoch_seconds: u64,
) -> Result<SessionCredential, AuthError> {
self.require_enabled_principal(&request.principal_id)?;
if !self.operator_action_allowed(
&request.principal_id,
OperatorAction::ManageCredentials,
&request.role_resource,
)? {
return Err(AuthError::RoleAssumptionDenied {
principal_id: request.principal_id,
role_name: request.role_name,
role_resource: request.role_resource,
});
}
self.issue_scoped_session(
request.principal_id,
format!("assume-role-parent:{}", request.role_name),
format!("bucketwarden-assume-role-parent:{}", request.role_name),
request.duration_seconds,
request.scope,
request.access_key_id,
request.secret_access_key,
request.session_token,
now_epoch_seconds,
)
}
pub fn assume_role_with_custom_identity(
&mut self,
request: AssumeRoleWithCustomIdentityRequest,
now_epoch_seconds: u64,
) -> Result<SessionCredential, AuthError> {
let identity = self
.custom_identities
.get(&request.principal_id)
.ok_or_else(|| AuthError::UnknownCustomIdentity(request.principal_id.clone()))?;
if !identity.enabled {
return Err(AuthError::DisabledCustomIdentity(
request.principal_id.clone(),
));
}
if !identity.verify_secret(&request.shared_secret) {
return Err(AuthError::InvalidCustomIdentitySecret(
request.principal_id.clone(),
));
}
self.require_enabled_principal(&request.principal_id)?;
self.issue_scoped_session(
request.principal_id,
"custom-identity-parent".to_string(),
identity.parent_secret(),
request.duration_seconds,
request.scope,
request.access_key_id,
request.secret_access_key,
request.session_token,
now_epoch_seconds,
)
}
pub fn role_assumption_support_report(&self) -> RoleAssumptionSupportReport {
RoleAssumptionSupportReport::current()
}
#[allow(clippy::too_many_arguments)]
fn issue_scoped_session(
&mut self,
principal_id: String,
parent_access_key_id: String,
parent_secret: String,
duration_seconds: u64,
scope: CredentialScope,
access_key_id: String,
secret_access_key: String,
session_token: String,
now_epoch_seconds: u64,
) -> Result<SessionCredential, AuthError> {
if !self.credentials.contains_key(&parent_access_key_id) {
self.put_access_key(AccessKey::active(
principal_id.clone(),
parent_access_key_id.clone(),
parent_secret,
))?;
}
let expires_at_epoch_seconds = now_epoch_seconds.saturating_add(duration_seconds);
let session = SessionCredential::new(
principal_id,
parent_access_key_id,
access_key_id,
secret_access_key,
session_token,
expires_at_epoch_seconds,
)
.with_scope(scope);
self.put_session(session.clone())?;
Ok(session)
}
}