bucketwarden-server 0.1.0

BucketWarden storage server runtime.
Documentation
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)
    }
}