|
7 | 7 | //! ## Usage
|
8 | 8 | //!
|
9 | 9 | //! To use Cryptonamo, you must first create a table in DynamoDB.
|
10 |
| -//! The table must have a primary key and sort key, both of type String. |
| 10 | +//! The table must have a at least partition key, sort key, and term field - all of type String. |
| 11 | +//! |
| 12 | +//! Cryptonamo also expects a Global Secondary Index called "TermIndex" to exist if you want to |
| 13 | +//! search and query against records. This index should project all fields and have a key schema |
| 14 | +//! that is a hash on the term attribute. |
11 | 15 | //!
|
12 | 16 | //! You can use the the `aws` CLI to create a table with an appropriate schema as follows:
|
13 | 17 | //!
|
|
22 | 26 | //! AttributeName=pk,KeyType=HASH \
|
23 | 27 | //! AttributeName=sk,KeyType=RANGE \
|
24 | 28 | //! --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
|
25 |
| -//! --global-secondary-indexes "IndexName=TermIndex,KeySchema=[{AttributeName=term,KeyType=HASH},{AttributeName=pk,KeyType=RANGE}],Projection={ProjectionType=ALL},ProvisionedThroughput={ReadCapacityUnits=5,WriteCapacityUnits=5}" |
| 29 | +//! --global-secondary-indexes "IndexName=TermIndex,KeySchema=[{AttributeName=term,KeyType=HASH}],Projection={ProjectionType=ALL},ProvisionedThroughput={ReadCapacityUnits=5,WriteCapacityUnits=5}" |
26 | 30 | //! ```
|
27 | 31 | //!
|
28 | 32 | //! See below for more information on schema design for Cryptonamo tables.
|
29 | 33 | //!
|
30 | 34 | //! ### Annotating a Cryptanomo Type
|
31 | 35 | //!
|
32 |
| -//! To use Cryptonamo, you must first annotate a struct with the `Cryptonamo` derive macro. |
| 36 | +//! To use Cryptonamo, you must first annotate a struct with the `Encryptable` derive macro, as |
| 37 | +//! well as the `Searchable` and `Decryptable` macros if you want to support those features. |
33 | 38 | //!
|
34 | 39 | //! ```rust
|
35 | 40 | //! use cryptonamo::{Searchable, Decryptable, Encryptable};
|
|
42 | 47 | //! }
|
43 | 48 | //! ```
|
44 | 49 | //!
|
45 |
| -//! The `Cryptonamo` derive macro will generate implementations of the following traits: |
| 50 | +//! These derive macros will generate implementations for the following traits of the same name: |
46 | 51 | //!
|
47 | 52 | //! * `Decryptable` - a trait that allows you to decrypt a record from DynamoDB
|
48 | 53 | //! * `Encryptable` - a trait that allows you to encrypt a record for storage in DynamoDB
|
|
52 | 57 | //!
|
53 | 58 | //! ### Controlling Encryption
|
54 | 59 | //!
|
55 |
| -//! By default, all fields on a `Cryptanomo` type are encrypted and stored in the index. |
56 |
| -//! To store a field as a plaintext, use the `plaintext` attribute: |
| 60 | +//! By default, all fields on an annotated struct are stored encrypted in the table. |
| 61 | +//! |
| 62 | +//! To store a field as a plaintext, you can use the `plaintext` attribute: |
57 | 63 | //!
|
58 | 64 | //! ```rust
|
59 | 65 | //! use cryptonamo::{Searchable, Decryptable, Encryptable};
|
|
69 | 75 | //! }
|
70 | 76 | //! ```
|
71 | 77 | //!
|
72 |
| -//! Most basic rust types will work automatically but you can implement a conversion trait for [Plaintext] to support custom types. |
73 |
| -//! |
74 |
| -//! ```ignore |
75 |
| -//! impl From<MyType> for Plaintext { |
76 |
| -//! fn from(t: MyType) -> Self { |
77 |
| -//! t.as_bytes().into() |
78 |
| -//! } |
79 |
| -//! } |
80 |
| -//! ``` |
81 |
| -//! |
82 | 78 | //! If you don't want a field stored in the the database at all, you can annotate the field with `#[cryptonamo(skip)]`.
|
83 | 79 | //!
|
84 | 80 | //!```rust
|
|
95 | 91 | //! }
|
96 | 92 | //! ```
|
97 | 93 | //!
|
| 94 | +//! If you implement the `Decryptable` trait these skipped fields need to implement `Default`. |
| 95 | +//! |
98 | 96 | //! ### Sort keys
|
99 | 97 | //!
|
100 |
| -//! Cryptanomo requires every record to have a sort key and it derives it automatically based on the name of the struct. |
| 98 | +//! Cryptanomo requires every record to have a sort key. By default this will be derived based on the name of the struct. |
101 | 99 | //! However, if you want to specify your own, you can use the `sort_key_prefix` attribute:
|
102 | 100 | //!
|
103 | 101 | //!```rust
|
|
115 | 113 | //! }
|
116 | 114 | //! ```
|
117 | 115 | //!
|
| 116 | +//! #### Dynamic Sort keys |
| 117 | +//! |
| 118 | +//! Cryptonamo also supports specifying the sort key dynamically based on a field on the struct. |
| 119 | +//! You can choose the field using the `#[sort_key]` attribute. |
| 120 | +//! |
| 121 | +//! ```rust |
| 122 | +//! #[derive(Debug, Encryptable)] |
| 123 | +//! struct User { |
| 124 | +//! #[partition_key] |
| 125 | +//! email: String, |
| 126 | +//! #[sort_key] |
| 127 | +//! name: String, |
| 128 | +//! |
| 129 | +//! #[cryptonamo(skip)] |
| 130 | +//! not_required: String, |
| 131 | +//! } |
| 132 | +//! ``` |
| 133 | +//! |
| 134 | +//! Sort keys will contain that value and will be prefixed by the sort key prefix. |
| 135 | +//! |
118 | 136 | //! ## Indexing
|
119 | 137 | //!
|
120 | 138 | //! Cryptanomo supports indexing of encrypted fields for searching.
|
121 |
| -//! Exact, prefix and compound match types are all supported. |
| 139 | +//! Exact, prefix and compound match types are currently supported. |
122 | 140 | //! To index a field, use the `query` attribute:
|
123 | 141 | //!
|
124 | 142 | //! ```rust
|
|
136 | 154 | //! ```
|
137 | 155 | //!
|
138 | 156 | //! You can also specify a compound index by using the `compound` attribute.
|
139 |
| -//! All indexes with the same compound name are combined into a single index. |
| 157 | +//! Indexes with the same name will be combined into the one index. |
| 158 | +//! |
| 159 | +//! Compound index names must be a combination of field names separated by a #. |
| 160 | +//! Fields mentioned in the compound index name that aren't correctly annottated will result in a |
| 161 | +//! compilation error. |
140 | 162 | //!
|
141 | 163 | //! ```rust
|
142 | 164 | //! use cryptonamo::Encryptable;
|
|
152 | 174 | //! }
|
153 | 175 | //! ```
|
154 | 176 | //!
|
155 |
| -//! **NOTE:** Compound indexes defined using the `compound` attribute are not currently working. |
156 |
| -//! Check out [SearchableRecord] for more information on how to implement compound indexes. |
| 177 | +//! It's also possible to add more than one query attribute to support querying records in multiple |
| 178 | +//! different ways. |
| 179 | +//! |
| 180 | +//! |
| 181 | +//! ```rust |
| 182 | +//! use cryptonamo::Encryptable; |
| 183 | +//! |
| 184 | +//! #[derive(Debug, Encryptable)] |
| 185 | +//! struct User { |
| 186 | +//! #[cryptonamo(query = "exact")] |
| 187 | +//! #[cryptonamo(query = "exact", compound = "email#name")] |
| 188 | +//! #[partition_key] |
| 189 | +//! email: String, |
| 190 | +//! |
| 191 | +//! #[cryptonamo(query = "prefix")] |
| 192 | +//! #[cryptonamo(query = "exact")] |
| 193 | +//! #[cryptonamo(query = "prefix", compound = "email#name")] |
| 194 | +//! name: String, |
| 195 | +//! } |
| 196 | +//! ``` |
| 197 | +//! It's important to note that the more annotations that are added to a field the more index terms that will be generated. Adding too many attributes could result in a |
| 198 | +//! proliferation of terms and data. |
157 | 199 | //!
|
158 | 200 | //! ## Storing and Retrieving Records
|
159 | 201 | //!
|
|
327 | 369 | //! # }
|
328 | 370 | //! ```
|
329 | 371 | //!
|
| 372 | +//! Note: if you don't have the correct indexes defined this query builder will return a runtime |
| 373 | +//! error. |
| 374 | +//! |
330 | 375 | //! ## Table Verticalization
|
331 | 376 | //!
|
332 | 377 | //! Cryptonamo uses a technique called "verticalization" which is a popular approach to storing data in DynamoDB.
|
|
444 | 489 | //!
|
445 | 490 | //! ## Issues and TODO
|
446 | 491 | //!
|
447 |
| -//! - [ ] Support for plaintext types is currently not implemented |
448 |
| -//! - [ ] Using the derive macros for compound macros is not working correctly (you can implement the traits directly) |
449 | 492 | //! - [ ] Sort keys are not currently hashed (and should be)
|
450 | 493 | //!
|
451 | 494 | pub mod crypto;
|
|
0 commit comments