use super::StorageBuilder;
use crate::{
encryption::{
indexer::IndexerInit, EncryptionError, JsonIndexer, MatchIndexer, OreIndexer, Plaintext,
PlaintextTarget, UniqueIndexer,
},
zerokms::IndexKey,
};
use std::borrow::Cow;
use uuid::Uuid;
use zerokms_protocol::cipherstash_config::column::IndexType;
pub trait Encryptable<'k> {
type Output;
fn build_encryptable(
self,
index_key: &'k IndexKey,
keyset_id: Uuid,
) -> Result<StorageBuilder<'k, Self::Output>, EncryptionError>;
}
impl<'k> Encryptable<'k> for PlaintextTarget {
type Output = Plaintext;
fn build_encryptable(
self,
index_key: &'k IndexKey,
keyset_id: Uuid,
) -> Result<StorageBuilder<'k, Self::Output>, EncryptionError> {
let PlaintextTarget {
plaintext,
config,
context,
..
} = self;
let mut builder = StorageBuilder::new(plaintext, index_key, keyset_id)
.with_descriptor(config.name)
.set_context(Cow::Owned(context));
for index in config.indexes.iter() {
match &index.index_type {
unique @ IndexType::Unique { .. } => {
let index = UniqueIndexer::try_init(unique)?;
builder = builder.index_with(index)?;
}
match_ @ IndexType::Match { .. } => {
let index = MatchIndexer::try_init(match_)?;
builder = builder.index_with(index)?;
}
ore @ IndexType::Ore => {
let index = OreIndexer::try_init(ore)?;
builder = builder.index_with(index)?;
}
json @ IndexType::SteVec { .. } => {
let index = JsonIndexer::try_init(json)?;
builder = builder.index_with(index)?;
}
}
}
Ok(builder)
}
}
#[cfg(test)]
mod tests {
use super::*;
use uuid::Uuid;
use zerokms_protocol::cipherstash_config::column::ColumnConfig;
#[test]
fn build_encryptable_sets_keyset_id_correctly() -> Result<(), EncryptionError> {
let keyset_id = Uuid::new_v4();
let index_key = IndexKey::from([0; 32]);
let config = ColumnConfig::build("test_column");
let plaintext_target = PlaintextTarget::new("hello world", config);
let storage_builder = plaintext_target.build_encryptable(&index_key, keyset_id)?;
assert_eq!(storage_builder.keyset_id(), keyset_id);
Ok(())
}
}