use super::*;
mod bucket_metadata_helpers;
use bucket_metadata_helpers::*;
const METADATA_TABLE_NAMESPACE: &str = "aws_s3_metadata";
impl BucketWarden {
pub fn create_bucket_metadata_configuration(
&mut self,
principal: &str,
bucket: &str,
mut configuration: BucketMetadataConfiguration,
) -> Result<(), RuntimeError> {
self.authorize(
principal,
S3Action::CreateBucketMetadataConfiguration,
bucket,
)?;
validate_bucket_metadata_configuration(&configuration)?;
configuration.bucket = bucket.to_string();
let bucket_state = self.require_bucket_mut(bucket)?;
bucket_state.metadata_table_configuration = None;
bucket_state.metadata_configuration = Some(configuration.clone());
self.audit_allowed(
principal,
S3Action::CreateBucketMetadataConfiguration,
bucket,
Some(metadata_configuration_audit_detail(&configuration)),
);
Ok(())
}
pub fn get_bucket_metadata_configuration(
&mut self,
principal: &str,
bucket: &str,
) -> Result<MetadataConfigurationResult, RuntimeError> {
self.authorize(principal, S3Action::GetBucketMetadataConfiguration, bucket)?;
let bucket_state = self.require_bucket(bucket)?;
let result = if let Some(configuration) = bucket_state.metadata_configuration.clone() {
synthesize_metadata_configuration_result(&configuration)
} else if let Some(configuration) = bucket_state.metadata_table_configuration.clone() {
synthesize_v2_result_from_v1(&configuration)
} else {
return Err(RuntimeError::NoSuchBucketMetadataConfiguration(
bucket.to_string(),
));
};
self.audit_allowed(
principal,
S3Action::GetBucketMetadataConfiguration,
bucket,
Some("compatible metadata configuration read".to_string()),
);
Ok(result)
}
pub fn delete_bucket_metadata_configuration(
&mut self,
principal: &str,
bucket: &str,
) -> Result<(), RuntimeError> {
self.authorize(
principal,
S3Action::DeleteBucketMetadataConfiguration,
bucket,
)?;
let bucket_state = self.require_bucket_mut(bucket)?;
bucket_state.metadata_configuration = None;
bucket_state.metadata_table_configuration = None;
self.audit_allowed(
principal,
S3Action::DeleteBucketMetadataConfiguration,
bucket,
None,
);
Ok(())
}
pub fn update_bucket_metadata_journal_table_configuration(
&mut self,
principal: &str,
bucket: &str,
journal_table_configuration: JournalTableConfiguration,
) -> Result<MetadataConfigurationResult, RuntimeError> {
self.authorize(
principal,
S3Action::UpdateBucketMetadataJournalTableConfiguration,
bucket,
)?;
validate_metadata_table_encryption(
journal_table_configuration
.encryption_configuration
.as_ref(),
)?;
validate_record_expiration(&journal_table_configuration.record_expiration)?;
let bucket_state = self.require_bucket_mut(bucket)?;
let configuration = bucket_state
.metadata_configuration
.as_mut()
.ok_or_else(|| RuntimeError::NoSuchBucketMetadataConfiguration(bucket.to_string()))?;
configuration.journal_table_configuration = journal_table_configuration;
let configuration = configuration.clone();
self.audit_allowed(
principal,
S3Action::UpdateBucketMetadataJournalTableConfiguration,
bucket,
Some(metadata_configuration_audit_detail(&configuration)),
);
Ok(synthesize_metadata_configuration_result(&configuration))
}
pub fn update_bucket_metadata_inventory_table_configuration(
&mut self,
principal: &str,
bucket: &str,
inventory_table_configuration: InventoryTableConfiguration,
) -> Result<MetadataConfigurationResult, RuntimeError> {
self.authorize(
principal,
S3Action::UpdateBucketMetadataInventoryTableConfiguration,
bucket,
)?;
validate_metadata_table_encryption(
inventory_table_configuration
.encryption_configuration
.as_ref(),
)?;
match inventory_table_configuration.configuration_state.as_str() {
"ENABLED" | "DISABLED" => {}
other => {
return Err(RuntimeError::InvalidBucketMetadataConfiguration(format!(
"invalid inventory configuration state: {other}"
)))
}
}
let bucket_state = self.require_bucket_mut(bucket)?;
let configuration = bucket_state
.metadata_configuration
.as_mut()
.ok_or_else(|| RuntimeError::NoSuchBucketMetadataConfiguration(bucket.to_string()))?;
configuration.inventory_table_configuration = Some(inventory_table_configuration);
let configuration = configuration.clone();
self.audit_allowed(
principal,
S3Action::UpdateBucketMetadataInventoryTableConfiguration,
bucket,
Some(metadata_configuration_audit_detail(&configuration)),
);
Ok(synthesize_metadata_configuration_result(&configuration))
}
pub fn create_bucket_metadata_table_configuration(
&mut self,
principal: &str,
bucket: &str,
mut configuration: BucketMetadataTableConfiguration,
) -> Result<(), RuntimeError> {
self.authorize(
principal,
S3Action::CreateBucketMetadataTableConfiguration,
bucket,
)?;
validate_bucket_metadata_table_configuration(&configuration)?;
let bucket_state = self.require_bucket_mut(bucket)?;
if bucket_state.metadata_configuration.is_some() {
return Err(RuntimeError::BucketMetadataTableApiNotAvailable(
bucket.to_string(),
));
}
configuration.bucket = bucket.to_string();
bucket_state.metadata_table_configuration = Some(configuration.clone());
self.audit_allowed(
principal,
S3Action::CreateBucketMetadataTableConfiguration,
bucket,
Some(metadata_table_configuration_audit_detail(&configuration)),
);
Ok(())
}
pub fn get_bucket_metadata_table_configuration(
&mut self,
principal: &str,
bucket: &str,
) -> Result<GetBucketMetadataTableConfigurationResult, RuntimeError> {
self.authorize(
principal,
S3Action::GetBucketMetadataTableConfiguration,
bucket,
)?;
let bucket_state = self.require_bucket(bucket)?;
if bucket_state.metadata_configuration.is_some() {
return Err(RuntimeError::BucketMetadataTableApiNotAvailable(
bucket.to_string(),
));
}
let configuration = bucket_state
.metadata_table_configuration
.clone()
.ok_or_else(|| {
RuntimeError::NoSuchBucketMetadataTableConfiguration(bucket.to_string())
})?;
let result = synthesize_metadata_table_configuration_result(&configuration);
self.audit_allowed(
principal,
S3Action::GetBucketMetadataTableConfiguration,
bucket,
Some(metadata_table_configuration_audit_detail(&configuration)),
);
Ok(result)
}
pub fn delete_bucket_metadata_table_configuration(
&mut self,
principal: &str,
bucket: &str,
) -> Result<(), RuntimeError> {
self.authorize(
principal,
S3Action::DeleteBucketMetadataTableConfiguration,
bucket,
)?;
let bucket_state = self.require_bucket_mut(bucket)?;
if bucket_state.metadata_configuration.is_some() {
return Err(RuntimeError::BucketMetadataTableApiNotAvailable(
bucket.to_string(),
));
}
bucket_state.metadata_table_configuration = None;
self.audit_allowed(
principal,
S3Action::DeleteBucketMetadataTableConfiguration,
bucket,
None,
);
Ok(())
}
}