familia 2.0.0.pre5 → 2.0.0.pre6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CLAUDE.md +8 -5
- data/Gemfile +1 -1
- data/Gemfile.lock +4 -3
- data/docs/wiki/API-Reference.md +95 -18
- data/docs/wiki/Connection-Pooling-Guide.md +437 -0
- data/docs/wiki/Encrypted-Fields-Overview.md +40 -3
- data/docs/wiki/Expiration-Feature-Guide.md +596 -0
- data/docs/wiki/Feature-System-Guide.md +600 -0
- data/docs/wiki/Features-System-Developer-Guide.md +892 -0
- data/docs/wiki/Field-System-Guide.md +784 -0
- data/docs/wiki/Home.md +72 -15
- data/docs/wiki/Implementation-Guide.md +126 -33
- data/docs/wiki/Quantization-Feature-Guide.md +721 -0
- data/docs/wiki/RelatableObjects-Guide.md +563 -0
- data/docs/wiki/Security-Model.md +65 -25
- data/docs/wiki/Transient-Fields-Guide.md +280 -0
- data/lib/familia/base.rb +1 -1
- data/lib/familia/data_type/types/counter.rb +38 -0
- data/lib/familia/data_type/types/hashkey.rb +18 -0
- data/lib/familia/data_type/types/lock.rb +43 -0
- data/lib/familia/data_type/types/string.rb +9 -2
- data/lib/familia/data_type.rb +2 -2
- data/lib/familia/encryption/encrypted_data.rb +137 -0
- data/lib/familia/encryption/manager.rb +21 -4
- data/lib/familia/encryption/providers/aes_gcm_provider.rb +20 -0
- data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +20 -0
- data/lib/familia/encryption.rb +1 -1
- data/lib/familia/errors.rb +17 -3
- data/lib/familia/features/encrypted_fields/concealed_string.rb +295 -0
- data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +94 -26
- data/lib/familia/features/expiration.rb +1 -1
- data/lib/familia/features/quantization.rb +1 -1
- data/lib/familia/features/safe_dump.rb +1 -1
- data/lib/familia/features/transient_fields/redacted_string.rb +1 -1
- data/lib/familia/features/transient_fields.rb +1 -1
- data/lib/familia/field_type.rb +5 -2
- data/lib/familia/horreum/{connection.rb → core/connection.rb} +2 -8
- data/lib/familia/horreum/{database_commands.rb → core/database_commands.rb} +14 -3
- data/lib/familia/horreum/core/serialization.rb +535 -0
- data/lib/familia/horreum/{utils.rb → core/utils.rb} +0 -2
- data/lib/familia/horreum/core.rb +21 -0
- data/lib/familia/horreum/{settings.rb → shared/settings.rb} +0 -2
- data/lib/familia/horreum/{definition_methods.rb → subclass/definition.rb} +44 -28
- data/lib/familia/horreum/{management_methods.rb → subclass/management.rb} +9 -8
- data/lib/familia/horreum/{related_fields_management.rb → subclass/related_fields_management.rb} +15 -10
- data/lib/familia/horreum.rb +17 -17
- data/lib/familia/version.rb +1 -1
- data/lib/familia.rb +1 -1
- data/try/core/create_method_try.rb +240 -0
- data/try/core/database_consistency_try.rb +299 -0
- data/try/core/errors_try.rb +25 -4
- data/try/core/familia_try.rb +1 -1
- data/try/core/persistence_operations_try.rb +297 -0
- data/try/data_types/counter_try.rb +93 -0
- data/try/data_types/lock_try.rb +133 -0
- data/try/debugging/debug_aad_process.rb +82 -0
- data/try/debugging/debug_concealed_internal.rb +59 -0
- data/try/debugging/debug_concealed_reveal.rb +61 -0
- data/try/debugging/debug_context_aad.rb +68 -0
- data/try/debugging/debug_context_simple.rb +80 -0
- data/try/debugging/debug_cross_context.rb +62 -0
- data/try/debugging/debug_database_load.rb +64 -0
- data/try/debugging/debug_encrypted_json_check.rb +53 -0
- data/try/debugging/debug_encrypted_json_step_by_step.rb +62 -0
- data/try/debugging/debug_exists_lifecycle.rb +54 -0
- data/try/debugging/debug_field_decrypt.rb +74 -0
- data/try/debugging/debug_fresh_cross_context.rb +73 -0
- data/try/debugging/debug_load_path.rb +66 -0
- data/try/debugging/debug_method_definition.rb +46 -0
- data/try/debugging/debug_method_resolution.rb +41 -0
- data/try/debugging/debug_minimal.rb +24 -0
- data/try/debugging/debug_provider.rb +68 -0
- data/try/debugging/debug_secure_behavior.rb +73 -0
- data/try/debugging/debug_string_class.rb +46 -0
- data/try/debugging/debug_test.rb +46 -0
- data/try/debugging/debug_test_design.rb +80 -0
- data/try/encryption/encryption_core_try.rb +3 -3
- data/try/features/encrypted_fields_core_try.rb +19 -11
- data/try/features/encrypted_fields_integration_try.rb +66 -70
- data/try/features/encrypted_fields_no_cache_security_try.rb +22 -8
- data/try/features/encrypted_fields_security_try.rb +151 -144
- data/try/features/encryption_fields/aad_protection_try.rb +108 -23
- data/try/features/encryption_fields/concealed_string_core_try.rb +250 -0
- data/try/features/encryption_fields/context_isolation_try.rb +29 -8
- data/try/features/encryption_fields/error_conditions_try.rb +6 -6
- data/try/features/encryption_fields/fresh_key_derivation_try.rb +20 -14
- data/try/features/encryption_fields/fresh_key_try.rb +27 -22
- data/try/features/encryption_fields/key_rotation_try.rb +16 -10
- data/try/features/encryption_fields/nonce_uniqueness_try.rb +15 -13
- data/try/features/encryption_fields/secure_by_default_behavior_try.rb +310 -0
- data/try/features/encryption_fields/thread_safety_try.rb +6 -6
- data/try/features/encryption_fields/universal_serialization_safety_try.rb +174 -0
- data/try/features/feature_dependencies_try.rb +3 -3
- data/try/features/transient_fields_core_try.rb +1 -1
- data/try/features/transient_fields_integration_try.rb +1 -1
- data/try/helpers/test_helpers.rb +25 -0
- data/try/horreum/enhanced_conflict_handling_try.rb +1 -1
- data/try/horreum/initialization_try.rb +1 -1
- data/try/horreum/relations_try.rb +1 -1
- data/try/horreum/serialization_persistent_fields_try.rb +8 -8
- data/try/horreum/serialization_try.rb +39 -4
- data/try/models/customer_safe_dump_try.rb +1 -1
- data/try/models/customer_try.rb +1 -1
- metadata +51 -10
- data/TEST_COVERAGE.md +0 -40
- data/lib/familia/horreum/serialization.rb +0 -473
@@ -12,16 +12,45 @@ Familia.debug = false
|
|
12
12
|
@customer.save
|
13
13
|
#=> true
|
14
14
|
|
15
|
+
## save_if_not_exists saves new customer successfully
|
16
|
+
Familia.dbclient.set('debug:starting_save_if_not_exists_tests', Time.now.to_s)
|
17
|
+
@test_id = "#{Time.now.to_i}-#{rand(1000)}"
|
18
|
+
@new_customer = Customer.new "new-customer-#{@test_id}@test.com"
|
19
|
+
@new_customer.name = 'New Customer'
|
20
|
+
@new_customer.save_if_not_exists
|
21
|
+
#=> true
|
22
|
+
|
23
|
+
## save_if_not_exists raises error when customer already exists
|
24
|
+
@duplicate_customer = Customer.new "new-customer-#{@test_id}@test.com"
|
25
|
+
@duplicate_customer.name = 'Duplicate Customer'
|
26
|
+
@duplicate_customer.save_if_not_exists
|
27
|
+
#=!> Familia::RecordExistsError
|
28
|
+
#==> error.message.include?("Key already exists")
|
29
|
+
|
30
|
+
## save_if_not_exists with update_expiration: false works
|
31
|
+
@another_new_customer = Customer.new "another-new-#{@test_id}@test.com"
|
32
|
+
@another_new_customer.name = 'Another New'
|
33
|
+
@another_new_customer.save_if_not_exists(update_expiration: false)
|
34
|
+
#=> true
|
35
|
+
|
36
|
+
## End of save_if_not_exists tests
|
37
|
+
Familia.dbclient.set('debug:ending_save_if_not_exists_tests', Time.now.to_s)
|
38
|
+
|
39
|
+
## save_if_not_exists persists data correctly
|
40
|
+
@another_new_customer.refresh!
|
41
|
+
@another_new_customer.name
|
42
|
+
#=> "Another New"
|
43
|
+
|
15
44
|
## to_h returns field hash with all Customer fields
|
16
45
|
@customer.to_h.class
|
17
46
|
#=> Hash
|
18
47
|
|
19
|
-
## to_h includes the fields we set (using
|
20
|
-
@customer.to_h[
|
48
|
+
## to_h includes the fields we set (using string keys)
|
49
|
+
@customer.to_h["name"]
|
21
50
|
#=> "John Doe"
|
22
51
|
|
23
|
-
## to_h includes the custid field (using
|
24
|
-
@customer.to_h[
|
52
|
+
## to_h includes the custid field (using string keys)
|
53
|
+
@customer.to_h["custid"]
|
25
54
|
#=> "tryouts-28@onetimesecret.dev"
|
26
55
|
|
27
56
|
## to_a returns field array in definition order
|
@@ -158,3 +187,9 @@ result.successful?
|
|
158
187
|
@fresh_customer.refresh!
|
159
188
|
[@fresh_customer.role, @fresh_customer.planid]
|
160
189
|
#=> ["admin", "premium"]
|
190
|
+
|
191
|
+
# Cleanup test data
|
192
|
+
[@customer, @new_customer, @another_new_customer, @fresh_customer].each do |obj|
|
193
|
+
next unless obj&.identifier && !obj.identifier.to_s.empty?
|
194
|
+
obj.destroy! if obj.exists?
|
195
|
+
end
|
@@ -45,7 +45,7 @@ require_relative '../helpers/test_helpers'
|
|
45
45
|
@customer.secrets_created.increment
|
46
46
|
@safe_dump = @customer.safe_dump
|
47
47
|
@safe_dump[:secrets_created]
|
48
|
-
#=>
|
48
|
+
#=> 1
|
49
49
|
|
50
50
|
## Safe dump includes correct active status when verified and not reset requested
|
51
51
|
@safe_dump[:active]
|
data/try/models/customer_try.rb
CHANGED
@@ -43,7 +43,7 @@ Customer.find_by_id(ident).planid
|
|
43
43
|
@customer.secrets_created.delete!
|
44
44
|
@customer.secrets_created.increment
|
45
45
|
@customer.secrets_created.value
|
46
|
-
#=>
|
46
|
+
#=> 1
|
47
47
|
|
48
48
|
## Customer can add custom domain via add method
|
49
49
|
@customer.custom_domains.add(@now, 'example.org')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: familia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.pre6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -132,15 +132,22 @@ files:
|
|
132
132
|
- Gemfile.lock
|
133
133
|
- LICENSE.txt
|
134
134
|
- README.md
|
135
|
-
- TEST_COVERAGE.md
|
136
135
|
- bin/irb
|
137
136
|
- docs/connection_pooling.md
|
138
137
|
- docs/overview.md
|
139
138
|
- docs/wiki/API-Reference.md
|
139
|
+
- docs/wiki/Connection-Pooling-Guide.md
|
140
140
|
- docs/wiki/Encrypted-Fields-Overview.md
|
141
|
+
- docs/wiki/Expiration-Feature-Guide.md
|
142
|
+
- docs/wiki/Feature-System-Guide.md
|
143
|
+
- docs/wiki/Features-System-Developer-Guide.md
|
144
|
+
- docs/wiki/Field-System-Guide.md
|
141
145
|
- docs/wiki/Home.md
|
142
146
|
- docs/wiki/Implementation-Guide.md
|
147
|
+
- docs/wiki/Quantization-Feature-Guide.md
|
148
|
+
- docs/wiki/RelatableObjects-Guide.md
|
143
149
|
- docs/wiki/Security-Model.md
|
150
|
+
- docs/wiki/Transient-Fields-Guide.md
|
144
151
|
- familia.gemspec
|
145
152
|
- lib/familia.rb
|
146
153
|
- lib/familia/base.rb
|
@@ -149,12 +156,15 @@ files:
|
|
149
156
|
- lib/familia/data_type.rb
|
150
157
|
- lib/familia/data_type/commands.rb
|
151
158
|
- lib/familia/data_type/serialization.rb
|
159
|
+
- lib/familia/data_type/types/counter.rb
|
152
160
|
- lib/familia/data_type/types/hashkey.rb
|
153
161
|
- lib/familia/data_type/types/list.rb
|
162
|
+
- lib/familia/data_type/types/lock.rb
|
154
163
|
- lib/familia/data_type/types/sorted_set.rb
|
155
164
|
- lib/familia/data_type/types/string.rb
|
156
165
|
- lib/familia/data_type/types/unsorted_set.rb
|
157
166
|
- lib/familia/encryption.rb
|
167
|
+
- lib/familia/encryption/encrypted_data.rb
|
158
168
|
- lib/familia/encryption/manager.rb
|
159
169
|
- lib/familia/encryption/provider.rb
|
160
170
|
- lib/familia/encryption/providers/aes_gcm_provider.rb
|
@@ -165,6 +175,7 @@ files:
|
|
165
175
|
- lib/familia/errors.rb
|
166
176
|
- lib/familia/features.rb
|
167
177
|
- lib/familia/features/encrypted_fields.rb
|
178
|
+
- lib/familia/features/encrypted_fields/concealed_string.rb
|
168
179
|
- lib/familia/features/encrypted_fields/encrypted_field_type.rb
|
169
180
|
- lib/familia/features/expiration.rb
|
170
181
|
- lib/familia/features/quantization.rb
|
@@ -176,14 +187,15 @@ files:
|
|
176
187
|
- lib/familia/features/transient_fields/transient_field_type.rb
|
177
188
|
- lib/familia/field_type.rb
|
178
189
|
- lib/familia/horreum.rb
|
179
|
-
- lib/familia/horreum/
|
180
|
-
- lib/familia/horreum/
|
181
|
-
- lib/familia/horreum/
|
182
|
-
- lib/familia/horreum/
|
183
|
-
- lib/familia/horreum/
|
184
|
-
- lib/familia/horreum/
|
185
|
-
- lib/familia/horreum/
|
186
|
-
- lib/familia/horreum/
|
190
|
+
- lib/familia/horreum/core.rb
|
191
|
+
- lib/familia/horreum/core/connection.rb
|
192
|
+
- lib/familia/horreum/core/database_commands.rb
|
193
|
+
- lib/familia/horreum/core/serialization.rb
|
194
|
+
- lib/familia/horreum/core/utils.rb
|
195
|
+
- lib/familia/horreum/shared/settings.rb
|
196
|
+
- lib/familia/horreum/subclass/definition.rb
|
197
|
+
- lib/familia/horreum/subclass/management.rb
|
198
|
+
- lib/familia/horreum/subclass/related_fields_management.rb
|
187
199
|
- lib/familia/logging.rb
|
188
200
|
- lib/familia/multi_result.rb
|
189
201
|
- lib/familia/refinements.rb
|
@@ -195,25 +207,51 @@ files:
|
|
195
207
|
- try/configuration/scenarios_try.rb
|
196
208
|
- try/core/base_enhancements_try.rb
|
197
209
|
- try/core/connection_try.rb
|
210
|
+
- try/core/create_method_try.rb
|
211
|
+
- try/core/database_consistency_try.rb
|
198
212
|
- try/core/errors_try.rb
|
199
213
|
- try/core/extensions_try.rb
|
200
214
|
- try/core/familia_extended_try.rb
|
201
215
|
- try/core/familia_try.rb
|
202
216
|
- try/core/middleware_try.rb
|
217
|
+
- try/core/persistence_operations_try.rb
|
203
218
|
- try/core/pools_try.rb
|
204
219
|
- try/core/secure_identifier_try.rb
|
205
220
|
- try/core/settings_try.rb
|
206
221
|
- try/core/tools_try.rb
|
207
222
|
- try/core/utils_try.rb
|
208
223
|
- try/data_types/boolean_try.rb
|
224
|
+
- try/data_types/counter_try.rb
|
209
225
|
- try/data_types/datatype_base_try.rb
|
210
226
|
- try/data_types/hash_try.rb
|
211
227
|
- try/data_types/list_try.rb
|
228
|
+
- try/data_types/lock_try.rb
|
212
229
|
- try/data_types/set_try.rb
|
213
230
|
- try/data_types/sorted_set_try.rb
|
214
231
|
- try/data_types/string_try.rb
|
215
232
|
- try/debugging/README.md
|
216
233
|
- try/debugging/cache_behavior_tracer.rb
|
234
|
+
- try/debugging/debug_aad_process.rb
|
235
|
+
- try/debugging/debug_concealed_internal.rb
|
236
|
+
- try/debugging/debug_concealed_reveal.rb
|
237
|
+
- try/debugging/debug_context_aad.rb
|
238
|
+
- try/debugging/debug_context_simple.rb
|
239
|
+
- try/debugging/debug_cross_context.rb
|
240
|
+
- try/debugging/debug_database_load.rb
|
241
|
+
- try/debugging/debug_encrypted_json_check.rb
|
242
|
+
- try/debugging/debug_encrypted_json_step_by_step.rb
|
243
|
+
- try/debugging/debug_exists_lifecycle.rb
|
244
|
+
- try/debugging/debug_field_decrypt.rb
|
245
|
+
- try/debugging/debug_fresh_cross_context.rb
|
246
|
+
- try/debugging/debug_load_path.rb
|
247
|
+
- try/debugging/debug_method_definition.rb
|
248
|
+
- try/debugging/debug_method_resolution.rb
|
249
|
+
- try/debugging/debug_minimal.rb
|
250
|
+
- try/debugging/debug_provider.rb
|
251
|
+
- try/debugging/debug_secure_behavior.rb
|
252
|
+
- try/debugging/debug_string_class.rb
|
253
|
+
- try/debugging/debug_test.rb
|
254
|
+
- try/debugging/debug_test_design.rb
|
217
255
|
- try/debugging/encryption_method_tracer.rb
|
218
256
|
- try/debugging/provider_diagnostics.rb
|
219
257
|
- try/edge_cases/empty_identifiers_try.rb
|
@@ -236,6 +274,7 @@ files:
|
|
236
274
|
- try/features/encrypted_fields_no_cache_security_try.rb
|
237
275
|
- try/features/encrypted_fields_security_try.rb
|
238
276
|
- try/features/encryption_fields/aad_protection_try.rb
|
277
|
+
- try/features/encryption_fields/concealed_string_core_try.rb
|
239
278
|
- try/features/encryption_fields/context_isolation_try.rb
|
240
279
|
- try/features/encryption_fields/error_conditions_try.rb
|
241
280
|
- try/features/encryption_fields/fresh_key_derivation_try.rb
|
@@ -244,7 +283,9 @@ files:
|
|
244
283
|
- try/features/encryption_fields/memory_security_try.rb
|
245
284
|
- try/features/encryption_fields/missing_current_key_version_try.rb
|
246
285
|
- try/features/encryption_fields/nonce_uniqueness_try.rb
|
286
|
+
- try/features/encryption_fields/secure_by_default_behavior_try.rb
|
247
287
|
- try/features/encryption_fields/thread_safety_try.rb
|
288
|
+
- try/features/encryption_fields/universal_serialization_safety_try.rb
|
248
289
|
- try/features/expiration_try.rb
|
249
290
|
- try/features/feature_dependencies_try.rb
|
250
291
|
- try/features/quantization_try.rb
|
data/TEST_COVERAGE.md
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
# Encryption Test Coverage
|
2
|
-
|
3
|
-
## Summary
|
4
|
-
- **149/150 tests passing** (99.3%)
|
5
|
-
- **12 test files**, 281ms execution
|
6
|
-
- **1 failing test** in integration suite
|
7
|
-
|
8
|
-
## Test Distribution
|
9
|
-
|
10
|
-
| Category | Files | Tests | Status |
|
11
|
-
|----------|-------|-------|---------|
|
12
|
-
| Core Encryption | 6 | 77 | ✅ All Pass |
|
13
|
-
| Providers | 2 | 39 | ✅ All Pass |
|
14
|
-
| Encrypted Fields | 4 | 53 | ⚠️ 1 Failure |
|
15
|
-
|
16
|
-
## Key Test Areas
|
17
|
-
|
18
|
-
### Security Testing (59 tests)
|
19
|
-
- No key caching (22 tests)
|
20
|
-
- AAD tampering detection (15 tests)
|
21
|
-
- Memory wiping verification (11 tests)
|
22
|
-
- Context isolation (11 tests)
|
23
|
-
|
24
|
-
### Provider Testing (39 tests)
|
25
|
-
- XChaCha20-Poly1305: 19 tests
|
26
|
-
- AES-GCM: 20 tests
|
27
|
-
- Round-trip encryption/decryption
|
28
|
-
- Nonce uniqueness and tampering detection
|
29
|
-
|
30
|
-
### Integration Testing (53 tests)
|
31
|
-
- Mixed field types with encryption
|
32
|
-
- Provider selection and algorithm handling
|
33
|
-
- Full model initialization workflows
|
34
|
-
|
35
|
-
## Action Items
|
36
|
-
- [ ] Fix failing integration test in `encrypted_fields_integration_try.rb:186`
|
37
|
-
- [x] All security properties validated
|
38
|
-
- [x] Both encryption providers fully tested
|
39
|
-
|
40
|
-
## Coverage Assessment: **Production Ready**
|