use super::*;
impl BucketWarden {
pub fn console_api_login(
&mut self,
request: ConsoleApiLoginRequest,
) -> Result<ConsoleApiSession, RuntimeError> {
self.browser_ui_login(BrowserUiLoginRequest {
principal_id: request.principal_id,
shared_secret: request.shared_secret,
})
}
pub fn console_api_identity_providers(&self) -> ConsoleApiIdentityProviderList {
ConsoleApiIdentityProviderList {
default_provider_id: "custom-shared-secret".to_string(),
providers: vec![
ConsoleApiIdentityProvider {
provider_id: "custom-shared-secret".to_string(),
label: "Shared secret".to_string(),
method: "principal-shared-secret".to_string(),
enabled: true,
description: "Use a configured BucketWarden principal and shared secret."
.to_string(),
},
ConsoleApiIdentityProvider {
provider_id: "external-oidc".to_string(),
label: "External OIDC".to_string(),
method: "oidc".to_string(),
enabled: false,
description:
"Reserved provider slot for deployments that configure external OIDC."
.to_string(),
},
],
}
}
pub fn console_api_current_user(
&self,
access_key_id: &str,
) -> Result<ConsoleApiSession, RuntimeError> {
self.browser_ui_current_user(access_key_id)
}
pub fn console_api_logout(&mut self, access_key_id: &str) -> Result<(), RuntimeError> {
self.browser_ui_logout(access_key_id)
}
pub(crate) fn console_api_principal(
&self,
access_key_id: &str,
) -> Result<String, RuntimeError> {
Ok(self
.auth
.resolve_credential(access_key_id, self.clock_epoch_seconds)?
.principal_id)
}
pub fn console_api_error_envelope(
&mut self,
error: &RuntimeError,
request_id: Option<&str>,
) -> ConsoleApiErrorEnvelope {
let (status, code, retryable) = console_api_error_shape(error);
ConsoleApiErrorEnvelope {
code: code.to_string(),
message: error.to_string(),
retryable,
status,
request_id: request_id
.map(str::to_string)
.unwrap_or_else(|| self.next_console_api_request_id()),
}
}
pub(crate) fn next_console_api_request_id(&mut self) -> String {
let request_id = format!("bwui{:012}", self.next_request);
self.next_request = self.next_request.saturating_add(1);
request_id
}
}
fn console_api_error_shape(error: &RuntimeError) -> (u16, &'static str, bool) {
match error {
RuntimeError::Auth(AuthError::ExpiredCredential(_)) | RuntimeError::ExpiredToken(_) => {
(401, "SessionExpired", false)
}
RuntimeError::Auth(AuthError::RevokedCredential(_))
| RuntimeError::Auth(AuthError::DisabledAccessKey(_)) => (401, "SessionInvalid", false),
RuntimeError::InvalidToken(_) => (401, "AuthenticationFailed", false),
RuntimeError::Auth(_) => (401, "AuthenticationFailed", false),
RuntimeError::AccessDenied { .. } | RuntimeError::OperatorActionDenied { .. } => {
(403, "PermissionDenied", false)
}
RuntimeError::NoSuchBucket(_) => (404, "NoSuchBucket", false),
RuntimeError::NoSuchKey(_) => (404, "NoSuchKey", false),
RuntimeError::NoSuchVersion { .. } => (404, "NoSuchVersion", false),
RuntimeError::InvalidListParameter { .. } => (400, "InvalidListParameter", false),
RuntimeError::InvalidObjectKey(_) => (400, "InvalidObjectKey", false),
RuntimeError::InvalidBucketName(_) => (400, "InvalidBucketName", false),
RuntimeError::QuotaExceeded { .. } => (429, "QuotaExceeded", true),
RuntimeError::SnapshotIo(_) => (503, "StorageUnavailable", true),
_ => (400, "InvalidRequest", false),
}
}