use async_trait::async_trait;
use zeroize::Zeroizing;
use crate::Result;
pub const BUCKET_METADATA_CAPABILITY: &str = "admin.bucket-metadata";
pub const MAX_BUCKET_METADATA_ARCHIVE_BYTES: usize = 100 * 1024 * 1024;
pub struct BucketMetadataArchive {
bytes: Zeroizing<Vec<u8>>,
}
impl BucketMetadataArchive {
pub fn new(bytes: Vec<u8>) -> Result<Self> {
if bytes.len() > MAX_BUCKET_METADATA_ARCHIVE_BYTES {
return Err(crate::Error::RequestRejected(format!(
"Bucket metadata archive size {} exceeds the {} byte limit",
bytes.len(),
MAX_BUCKET_METADATA_ARCHIVE_BYTES
)));
}
Ok(Self {
bytes: Zeroizing::new(bytes),
})
}
pub fn as_bytes(&self) -> &[u8] {
self.bytes.as_slice()
}
pub fn into_bytes(self) -> Zeroizing<Vec<u8>> {
self.bytes
}
}
#[async_trait]
pub trait BucketMetadataApi: Send + Sync {
async fn export_bucket_metadata(&self, bucket: Option<&str>) -> Result<BucketMetadataArchive>;
async fn import_bucket_metadata(&self, archive: BucketMetadataArchive) -> Result<()>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn archive_rejects_oversized_input() {
let bytes = vec![0; MAX_BUCKET_METADATA_ARCHIVE_BYTES + 1];
assert!(BucketMetadataArchive::new(bytes).is_err());
}
}