Skip to content

Commit a54e629

Browse files
Nicklas Warming JacobsenBennett Hardwick
authored andcommitted
Move fn prepare_record from Preparable trait to struct PreparedRecord
1 parent fc8d2c6 commit a54e629

File tree

3 files changed

+56
-65
lines changed

3 files changed

+56
-65
lines changed

src/encrypted_table/mod.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub use self::{
88
use crate::{
99
crypto::*,
1010
errors::*,
11-
traits::{Decryptable, Preparable, PrimaryKeyParts, Searchable},
11+
traits::{Decryptable, PrimaryKey, PrimaryKeyParts, Searchable},
1212
Identifiable, IndexType,
1313
};
1414
use aws_sdk_dynamodb::types::{AttributeValue, Delete, Put, TransactWriteItem};
@@ -115,6 +115,55 @@ impl PreparedRecord {
115115
sealer,
116116
}
117117
}
118+
119+
pub fn prepare_record<R>(record: R) -> Result<Self, SealError>
120+
where
121+
R: Searchable + Identifiable,
122+
{
123+
let type_name = R::type_name();
124+
125+
let PrimaryKeyParts { pk, sk } = record
126+
.get_primary_key()
127+
.into_parts(&type_name, R::sort_key_prefix().as_deref());
128+
129+
let protected_indexes = R::protected_indexes();
130+
let protected_attributes = R::protected_attributes();
131+
132+
let unsealed_indexes = protected_indexes
133+
.iter()
134+
.map(|(index_name, index_type)| {
135+
record
136+
.attribute_for_index(index_name, *index_type)
137+
.and_then(|attr| {
138+
R::index_by_name(index_name, *index_type)
139+
.map(|index| (attr, index, index_name.clone(), *index_type))
140+
})
141+
.ok_or(SealError::MissingAttribute(index_name.to_string()))
142+
})
143+
.collect::<Result<Vec<_>, _>>()?;
144+
145+
let unsealed = record.into_unsealed();
146+
147+
let sealer = Sealer {
148+
pk,
149+
sk,
150+
151+
is_sk_encrypted: R::is_sk_encrypted(),
152+
is_pk_encrypted: R::is_pk_encrypted(),
153+
154+
type_name,
155+
156+
unsealed_indexes,
157+
158+
unsealed,
159+
};
160+
161+
Ok(PreparedRecord::new(
162+
protected_indexes,
163+
protected_attributes,
164+
sealer,
165+
))
166+
}
118167
}
119168

120169
impl DynamoRecordPatch {
@@ -366,7 +415,7 @@ impl EncryptedTable<Dynamo> {
366415
where
367416
T: Searchable + Identifiable,
368417
{
369-
let record = record.prepare_record()?;
418+
let record = PreparedRecord::prepare_record(record)?;
370419

371420
let transact_items = self
372421
.create_put_patch(

src/traits/mod.rs

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1+
use crate::crypto::{SealError, Unsealed};
12
pub use crate::encrypted_table::{TableAttribute, TryFromTableAttr};
2-
use crate::{
3-
crypto::{SealError, Sealer, Unsealed},
4-
encrypted_table::PreparedRecord,
5-
};
63
use cipherstash_client::encryption::EncryptionError;
74
pub use cipherstash_client::{
85
credentials::{service_credentials::ServiceToken, Credentials},
@@ -151,57 +148,3 @@ pub trait Decryptable: Sized {
151148
/// Must be equal to or a subset of protected_attributes on the [`Encryptable`] type.
152149
fn plaintext_attributes() -> Cow<'static, [Cow<'static, str>]>;
153150
}
154-
155-
pub trait Preparable {
156-
fn prepare_record(self) -> Result<PreparedRecord, SealError>;
157-
}
158-
159-
impl<R> Preparable for R
160-
where
161-
R: Searchable + Identifiable,
162-
{
163-
fn prepare_record(self) -> Result<PreparedRecord, SealError> {
164-
let type_name = Self::type_name();
165-
166-
let PrimaryKeyParts { pk, sk } = self
167-
.get_primary_key()
168-
.into_parts(&type_name, Self::sort_key_prefix().as_deref());
169-
170-
let protected_indexes = Self::protected_indexes();
171-
let protected_attributes = Self::protected_attributes();
172-
173-
let unsealed_indexes = protected_indexes
174-
.iter()
175-
.map(|(index_name, index_type)| {
176-
self.attribute_for_index(index_name, *index_type)
177-
.and_then(|attr| {
178-
Self::index_by_name(index_name, *index_type)
179-
.map(|index| (attr, index, index_name.clone(), *index_type))
180-
})
181-
.ok_or(SealError::MissingAttribute(index_name.to_string()))
182-
})
183-
.collect::<Result<Vec<_>, _>>()?;
184-
185-
let unsealed = self.into_unsealed();
186-
187-
let sealer = Sealer {
188-
pk,
189-
sk,
190-
191-
is_sk_encrypted: Self::is_sk_encrypted(),
192-
is_pk_encrypted: Self::is_pk_encrypted(),
193-
194-
type_name,
195-
196-
unsealed_indexes,
197-
198-
unsealed,
199-
};
200-
201-
Ok(PreparedRecord::new(
202-
protected_indexes,
203-
protected_attributes,
204-
sealer,
205-
))
206-
}
207-
}

tests/headless_tests.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use aws_sdk_dynamodb::Client;
22
use cipherstash_dynamodb::{
3-
traits::Preparable, Decryptable, Encryptable, EncryptedTable, Identifiable, Searchable,
3+
encrypted_table::PreparedRecord, Decryptable, Encryptable, EncryptedTable, Identifiable,
4+
Searchable,
45
};
56
use serial_test::serial;
67
use std::future::Future;
@@ -60,10 +61,8 @@ async fn test_headless_roundtrip() {
6061
.await
6162
.expect("failed to init table");
6263

63-
let user_record = user
64-
.clone()
65-
.prepare_record()
66-
.expect("failed to prepare record");
64+
let user_record =
65+
PreparedRecord::prepare_record(user.clone()).expect("failed to prepare record");
6766

6867
let patch = table
6968
.create_put_patch(user_record, |_, _| true)

0 commit comments

Comments
 (0)