Add S3 encryption
All checks were successful
CI / Typos (push) Successful in 19s
CI / Build and test (push) Successful in 2m36s
CI / Clippy (push) Successful in 3m33s
CI / Build and test (all features) (push) Successful in 8m52s

This commit is contained in:
2026-03-21 21:03:52 -07:00
parent 39f3c7707b
commit 4737acbcf4
33 changed files with 1307 additions and 202 deletions

View File

@@ -1,11 +1,12 @@
use mime::Mime;
use pile_config::Label;
use pile_io::{ChaChaReaderAsync, S3Reader, SyncReadBridge};
use smartstring::{LazyCompact, SmartString};
use std::{collections::HashMap, fs::File, path::PathBuf, sync::Arc};
use crate::{
source::{DirDataSource, S3DataSource},
value::{ItemReader, S3Reader, SyncReadBridge},
source::{DirDataSource, S3DataSource, encrypt_path},
value::ItemReader,
};
//
@@ -40,13 +41,20 @@ impl Item {
Self::File { path, .. } => ItemReader::File(File::open(path)?),
Self::S3 { source, key, .. } => {
let logical_key = key.as_str();
let s3_key_part: SmartString<LazyCompact> = match &source.encryption_key {
None => logical_key.into(),
Some(enc_key) => encrypt_path(enc_key, logical_key).into(),
};
let full_key: SmartString<LazyCompact> = match &source.prefix {
None => key.clone(),
None => s3_key_part,
Some(p) => {
if p.ends_with('/') {
format!("{p}{key}").into()
format!("{p}{s3_key_part}").into()
} else {
format!("{p}/{key}").into()
format!("{p}/{s3_key_part}").into()
}
}
};
@@ -62,13 +70,29 @@ impl Item {
let size = head.content_length().unwrap_or(0) as u64;
ItemReader::S3(S3Reader {
client: source.client.clone(),
bucket: source.bucket.clone(),
key: full_key,
cursor: 0,
size,
})
match source.encryption_key {
None => ItemReader::S3(S3Reader {
client: source.client.clone(),
bucket: source.bucket.clone(),
key: full_key,
cursor: 0,
size,
}),
Some(enc_key) => ItemReader::EncryptedS3(
ChaChaReaderAsync::new(
S3Reader {
client: source.client.clone(),
bucket: source.bucket.clone(),
key: full_key,
cursor: 0,
size,
},
enc_key,
)
.await?,
),
}
}
})
}