Skip to content

Commit 72f76cd

Browse files
committed
Updated methods on encrypted table for dataset awareness
1 parent d7da4e2 commit 72f76cd

File tree

7 files changed

+70
-50
lines changed

7 files changed

+70
-50
lines changed

docker-compose.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
dynamodb:
53
build: ./local-dynamodb

src/crypto/attrs/flattened_encrypted_attributes.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
22
crypto::{attrs::flattened_protected_attributes::FlattenedAttrName, SealError},
3-
encrypted_table::{ScopedZeroKmsCipher, TableAttributes},
3+
encrypted_table::{TableAttributes, ZeroKmsCipher},
44
traits::TableAttribute,
55
};
66
use cipherstash_client::{
@@ -34,7 +34,7 @@ impl FlattenedEncryptedAttributes {
3434
/// Decrypt self, returning a [FlattenedProtectedAttributes].
3535
pub(crate) async fn decrypt_all(
3636
self,
37-
cipher: &ScopedZeroKmsCipher,
37+
cipher: &ZeroKmsCipher,
3838
) -> Result<FlattenedProtectedAttributes, SealError> {
3939
let descriptors = self
4040
.attrs

src/crypto/sealed.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
22
crypto::attrs::FlattenedEncryptedAttributes,
3-
encrypted_table::{ScopedZeroKmsCipher, TableEntry},
3+
encrypted_table::{TableEntry, ZeroKmsCipher},
44
traits::{ReadConversionError, WriteConversionError},
55
Decryptable, Identifiable,
66
};
@@ -68,7 +68,7 @@ impl SealedTableEntry {
6868
pub(crate) async fn unseal_all(
6969
items: Vec<Self>,
7070
spec: UnsealSpec<'_>,
71-
cipher: &ScopedZeroKmsCipher,
71+
cipher: &ZeroKmsCipher,
7272
) -> Result<Vec<Unsealed>, SealError> {
7373
let UnsealSpec {
7474
protected_attributes,
@@ -130,7 +130,7 @@ impl SealedTableEntry {
130130
pub(crate) async fn unseal(
131131
self,
132132
spec: UnsealSpec<'_>,
133-
cipher: &ScopedZeroKmsCipher,
133+
cipher: &ZeroKmsCipher,
134134
) -> Result<Unsealed, SealError> {
135135
let mut vec = Self::unseal_all(vec![self], spec, cipher).await?;
136136

@@ -203,14 +203,13 @@ impl TryFrom<SealedTableEntry> for HashMap<String, AttributeValue> {
203203

204204
#[cfg(test)]
205205
mod tests {
206-
use crate::encrypted_table::{ZeroKmsCipher, ScopedZeroKmsCipher};
206+
use crate::encrypted_table::{ZeroKmsCipher};
207207

208208
use super::SealedTableEntry;
209209
use cipherstash_client::{
210210
credentials::auto_refresh::AutoRefresh, ConsoleConfig, ZeroKMS, ZeroKMSConfig
211211
};
212212
use miette::IntoDiagnostic;
213-
use uuid::Uuid;
214213
use std::{borrow::Cow, sync::Arc};
215214

216215
// FIXME: Use the test cipher from CipherStash Client when that's ready
@@ -240,11 +239,7 @@ mod tests {
240239
sort_key_prefix: "test".to_string(),
241240
};
242241
let cipher = get_cipher().await?;
243-
// TODO: Temporary obvs
244-
let dataset_id = Uuid::parse_str("93e10481-2692-4d65-a619-37e36a496e64").unwrap();
245-
let scoped_cipher = ScopedZeroKmsCipher::init(cipher, dataset_id).await.unwrap();
246-
247-
let results = SealedTableEntry::unseal_all(vec![], spec, &scoped_cipher)
242+
let results = SealedTableEntry::unseal_all(vec![], spec, &cipher)
248243
.await
249244
.into_diagnostic()?;
250245

src/encrypted_table/mod.rs

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -279,20 +279,14 @@ impl<D> EncryptedTable<D> {
279279
) -> Result<Vec<T>, DecryptError>
280280
where T: Decryptable + Identifiable,
281281
{
282-
// TODO: Decryption _may_ not need to be scoped
283-
// TODO: Temporary obvs
284-
let dataset_id = Uuid::parse_str("93e10481-2692-4d65-a619-37e36a496e64").unwrap();
285-
let scoped_cipher = ScopedZeroKmsCipher::init(self.cipher.clone(), dataset_id).await.unwrap();
286-
287-
decrypt_all(&scoped_cipher, items).await
282+
decrypt_all(&self.cipher, items).await
288283
}
289284

290285
pub async fn create_delete_patch(
291286
&self,
292287
delete: PreparedDelete,
288+
dataset_id: Option<Uuid>,
293289
) -> Result<DynamoRecordPatch, DeleteError> {
294-
// TODO: Temporary obvs
295-
let dataset_id = Uuid::parse_str("93e10481-2692-4d65-a619-37e36a496e64").unwrap();
296290
let scoped_cipher = ScopedZeroKmsCipher::init(self.cipher.clone(), dataset_id).await.unwrap();
297291

298292
let PrimaryKeyParts { pk, sk } = encrypt_primary_key_parts(&scoped_cipher, delete.primary_key)?;
@@ -324,14 +318,12 @@ impl<D> EncryptedTable<D> {
324318
pub async fn create_put_patch(
325319
&self,
326320
record: PreparedRecord,
327-
dataset_id: Uuid,
321+
dataset_id: Option<Uuid>,
328322
// TODO: Make sure the index_predicate is used correctly
329323
index_predicate: impl FnMut(&AttributeName, &TableAttribute) -> bool,
330324
) -> Result<DynamoRecordPatch, PutError> {
331325
let mut seen_sk = HashSet::new();
332326

333-
// TODO: Temporary obvs
334-
let dataset_id = Uuid::parse_str("93e10481-2692-4d65-a619-37e36a496e64").unwrap();
335327
let indexable_cipher = ScopedZeroKmsCipher::init(self.cipher.clone(), dataset_id).await.unwrap();
336328

337329
let PreparedRecord {
@@ -405,13 +397,26 @@ impl EncryptedTable<Dynamo> {
405397
where
406398
T: Decryptable + Identifiable,
407399
{
408-
// TODO: Temporary obvs
409-
let dataset_id = Uuid::parse_str("93e10481-2692-4d65-a619-37e36a496e64").unwrap();
410-
let scoped_cipher = ScopedZeroKmsCipher::init(self.cipher.clone(), dataset_id).await.unwrap();
400+
// TODO: Don't unwrap
401+
let scoped_cipher = ScopedZeroKmsCipher::init(self.cipher.clone(), None).await.unwrap();
402+
self.get_inner(k, scoped_cipher).await
403+
}
411404

412-
let PrimaryKeyParts { pk, sk } =
413-
encrypt_primary_key_parts(&scoped_cipher, PreparedPrimaryKey::new::<T>(k))?;
405+
pub async fn get_via<T>(&self, k: impl Into<T::PrimaryKey>, dataset_id: Uuid) -> Result<Option<T>, GetError>
406+
where
407+
T: Decryptable + Identifiable,
408+
{
409+
// TODO: Don't unwrap
410+
let scoped_cipher = ScopedZeroKmsCipher::init(self.cipher.clone(), Some(dataset_id)).await.unwrap();
411+
self.get_inner(k, scoped_cipher).await
412+
}
414413

414+
async fn get_inner<T>(&self, k: impl Into<T::PrimaryKey>, cipher: ScopedZeroKmsCipher) -> Result<Option<T>, GetError>
415+
where
416+
T: Decryptable + Identifiable,
417+
{
418+
let PrimaryKeyParts { pk, sk } =
419+
encrypt_primary_key_parts(&cipher, PreparedPrimaryKey::new::<T>(k))?;
415420

416421
let result = self
417422
.db
@@ -423,10 +428,8 @@ impl EncryptedTable<Dynamo> {
423428
.await
424429
.map_err(|e| GetError::Aws(format!("{e:?}")))?;
425430

426-
println!("RESULT {:?}", result);
427-
428431
if let Some(item) = result.item {
429-
Ok(Some(decrypt(&scoped_cipher, item).await?))
432+
Ok(Some(decrypt(&self.cipher, item).await?))
430433
} else {
431434
Ok(None)
432435
}
@@ -435,9 +438,25 @@ impl EncryptedTable<Dynamo> {
435438
pub async fn delete<E: Searchable + Identifiable>(
436439
&self,
437440
k: impl Into<E::PrimaryKey>,
441+
) -> Result<(), DeleteError> {
442+
self.delete_inner::<E>(k.into(), None).await
443+
}
444+
445+
pub async fn delete_via<E: Searchable + Identifiable>(
446+
&self,
447+
k: impl Into<E::PrimaryKey>,
448+
dataset_id: Uuid,
449+
) -> Result<(), DeleteError> {
450+
self.delete_inner::<E>(k.into(), Some(dataset_id)).await
451+
}
452+
453+
async fn delete_inner<E: Searchable + Identifiable>(
454+
&self,
455+
k: E::PrimaryKey,
456+
dataset_id: Option<Uuid>,
438457
) -> Result<(), DeleteError> {
439458
let transact_items = self
440-
.create_delete_patch(PreparedDelete::new::<E>(k))
459+
.create_delete_patch(PreparedDelete::new::<E>(k), dataset_id)
441460
.await?
442461
.into_transact_write_items(&self.db.table_name)?;
443462

@@ -455,6 +474,20 @@ impl EncryptedTable<Dynamo> {
455474
}
456475

457476
pub async fn put<T>(&self, record: T) -> Result<(), PutError>
477+
where
478+
T: Searchable + Identifiable,
479+
{
480+
self.put_inner(record, None).await
481+
}
482+
483+
pub async fn put_via<T>(&self, record: T, dataset_id: Uuid) -> Result<(), PutError>
484+
where
485+
T: Searchable + Identifiable,
486+
{
487+
self.put_inner(record, Some(dataset_id)).await
488+
}
489+
490+
async fn put_inner<T>(&self, record: T, dataset_id: Option<Uuid>) -> Result<(), PutError>
458491
where
459492
T: Searchable + Identifiable,
460493
{
@@ -463,6 +496,7 @@ impl EncryptedTable<Dynamo> {
463496
let transact_items = self
464497
.create_put_patch(
465498
record,
499+
dataset_id,
466500
// include all records in the indexes
467501
|_, _| true,
468502
)
@@ -502,7 +536,7 @@ fn encrypt_primary_key_parts(
502536
Ok(PrimaryKeyParts { pk, sk })
503537
}
504538

505-
async fn decrypt<T>(scoped_cipher: &ScopedZeroKmsCipher, item: HashMap<String, AttributeValue>) -> Result<T, DecryptError>
539+
async fn decrypt<T>(scoped_cipher: &ZeroKmsCipher, item: HashMap<String, AttributeValue>) -> Result<T, DecryptError>
506540
where
507541
T: Decryptable + Identifiable,
508542
{
@@ -514,7 +548,7 @@ where
514548
}
515549

516550
async fn decrypt_all<T>(
517-
scoped_cipher: &ScopedZeroKmsCipher,
551+
scoped_cipher: &ZeroKmsCipher,
518552
items: impl IntoIterator<Item = HashMap<String, AttributeValue>>,
519553
) -> Result<Vec<T>, DecryptError>
520554
where

src/encrypted_table/query.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use cipherstash_client::{
66
},
77
};
88
use itertools::Itertools;
9-
use uuid::Uuid;
109
use std::{borrow::Cow, collections::HashMap, marker::PhantomData};
1110

1211
use crate::{
@@ -128,19 +127,18 @@ impl<S> QueryBuilder<S, &EncryptedTable<Dynamo>>
128127
where
129128
S: Searchable + Identifiable,
130129
{
130+
// TODO: Add load_via
131131
pub async fn load<T>(self) -> Result<Vec<T>, QueryError>
132132
where
133133
T: Decryptable + Identifiable,
134134
{
135-
// TODO: Temporary obvs
136-
let dataset_id = Uuid::parse_str("93e10481-2692-4d65-a619-37e36a496e64").unwrap();
137-
let scoped_cipher = ScopedZeroKmsCipher::init(self.storage.cipher.clone(), dataset_id).await.unwrap();
135+
let scoped_cipher = ScopedZeroKmsCipher::init(self.storage.cipher.clone(), None).await.unwrap();
138136

139137
let storage = self.storage;
140138
let query = self.build()?;
141139

142140
let items = query.send(storage, &scoped_cipher).await?;
143-
let results = super::decrypt_all(&scoped_cipher, items).await?;
141+
let results = super::decrypt_all(&storage.cipher, items).await?;
144142

145143
Ok(results)
146144
}

tests/headless_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ async fn test_headless_roundtrip() {
6565
PreparedRecord::prepare_record(user.clone()).expect("failed to prepare record");
6666

6767
let patch = table
68-
.create_put_patch(user_record, |_, _| true)
68+
.create_put_patch(user_record, None, |_, _| true)
6969
.await
7070
.expect("failed to encrypt");
7171

tests/query_builder_direct.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ use cipherstash_dynamodb::{
33
};
44
use itertools::Itertools;
55
use serial_test::serial;
6-
use uuid::Uuid;
76
use std::future::Future;
8-
97
mod common;
108

119
#[derive(
@@ -89,8 +87,7 @@ async fn test_query_single_exact() {
8987
.build()
9088
.expect("failed to build query");
9189

92-
let dataset_id = Uuid::parse_str("93e10481-2692-4d65-a619-37e36a496e64").unwrap();
93-
let scoped_cipher = ScopedZeroKmsCipher::init(table.cipher(), dataset_id).await.unwrap();
90+
let scoped_cipher = ScopedZeroKmsCipher::init(table.cipher(), None).await.unwrap();
9491

9592
let term = query
9693
.encrypt(&scoped_cipher)
@@ -132,8 +129,7 @@ async fn test_query_single_prefix() {
132129
.await
133130
.expect("failed to init table");
134131

135-
let dataset_id = Uuid::parse_str("93e10481-2692-4d65-a619-37e36a496e64").unwrap();
136-
let scoped_cipher = ScopedZeroKmsCipher::init(table.cipher(), dataset_id).await.unwrap();
132+
let scoped_cipher = ScopedZeroKmsCipher::init(table.cipher(), None).await.unwrap();
137133

138134
let query = QueryBuilder::<User>::new()
139135
.starts_with("name", "Dan")
@@ -189,8 +185,7 @@ async fn test_query_compound() {
189185
.build()
190186
.expect("failed to build query");
191187

192-
let dataset_id = Uuid::parse_str("93e10481-2692-4d65-a619-37e36a496e64").unwrap();
193-
let scoped_cipher = ScopedZeroKmsCipher::init(table.cipher(), dataset_id).await.unwrap();
188+
let scoped_cipher = ScopedZeroKmsCipher::init(table.cipher(), None).await.unwrap();
194189

195190
let term = query
196191
.encrypt(&scoped_cipher)

0 commit comments

Comments
 (0)