loggable_activity 0.1.46 → 0.1.48
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/GETTING-STARTED.md +6 -0
- data/README.md +2 -0
- data/lib/loggable_activity/activity.rb +2 -0
- data/lib/loggable_activity/encryption.rb +25 -18
- data/lib/loggable_activity/encryption_key.rb +6 -3
- data/lib/loggable_activity/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee3e20a374ac054a343ce5ff1c35c5fcce765fb631788fb6d9b738e52161a16a
|
4
|
+
data.tar.gz: 042cc1db90cf6b99eeb2c8d5ab3f16a5473178c00085f42400c4eec344a99731
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f4063eb4cd98a16061d151759735e0b5cc98e7747151dc2c56856f2010f23936c2c338991c5cc85dfd3c72af4f60133a4e39271f29ec76e5ee04383ad6dd073
|
7
|
+
data.tar.gz: 8be57a52cfd948825e273648ffaec5809975dc14863f49206ee8f364f07b58a193758d80d867155f21760522a24bc2cf49d183ba757c503af1fdf51317b78202
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
- nothing so far
|
3
|
+
|
4
|
+
## [0.1.48] - 2024-02-16
|
5
|
+
### Breaking change
|
6
|
+
- Updated encryption_key to be 32 bytes
|
7
|
+
- Updated README.md
|
8
|
+
- Updated GETTING_STARTED.md
|
9
|
+
- Added PULL_REQUEST_TEMPLATE.md
|
10
|
+
## [0.1.46] - 2024-02-16
|
11
|
+
- Fixed spelling error in EncryptionKey
|
3
12
|
## [0.1.43] - 2024-02-15
|
4
13
|
- Updated README.md and GETTING-STARTED.md
|
5
14
|
## [0.1.39] - 2024-02-12
|
@@ -7,6 +16,5 @@
|
|
7
16
|
## [0.1.38] - 2024-02-12
|
8
17
|
- Removed dependency on awesome print
|
9
18
|
## [0.1.35] - 2024-02-11
|
10
|
-
|
11
19
|
- Initial release
|
12
20
|
|
data/GETTING-STARTED.md
CHANGED
@@ -78,3 +78,9 @@ Then an `LoggableActivity::Activity` is created. You can inspect it from the ter
|
|
78
78
|
puts activity = Loggable::Activity.last
|
79
79
|
puts activity.attrs
|
80
80
|
```
|
81
|
+
|
82
|
+
## For developers
|
83
|
+
If you want to contribute to the development and try it out in the process
|
84
|
+
- 1 Down the demo project from [demo project on github](https://github.com/maxgronlund/LoggableActivityDemoApp)
|
85
|
+
- 2 Update the Gemfile in the demo project so it points to your localhost.
|
86
|
+
- 3 you can now build and test you version of the gem `$ gem build loggable_activity.gemspec`
|
data/README.md
CHANGED
@@ -5,6 +5,8 @@ Secure protect data and log how it is handled
|
|
5
5
|
- Prepare for General Data Protection Regulation (GDPR) compliance.
|
6
6
|
- Handles activities that involves more than one table in the DB.
|
7
7
|
|
8
|
+
### Important!
|
9
|
+
This project is under development and not ready for production. There might be breaking changes, so please consult the CHANGELOG.md
|
8
10
|
### What it is not
|
9
11
|
- An error logging system
|
10
12
|
- A paper trails system with rollback.
|
@@ -260,11 +260,13 @@ module LoggableActivity
|
|
260
260
|
|
261
261
|
def record_key
|
262
262
|
return nil if record.nil?
|
263
|
+
|
263
264
|
LoggableActivity::EncryptionKey.for_record(record)&.key
|
264
265
|
end
|
265
266
|
|
266
267
|
def actor_key
|
267
268
|
return nil if actor.nil?
|
269
|
+
|
268
270
|
LoggableActivity::EncryptionKey.for_record(actor)&.key
|
269
271
|
end
|
270
272
|
|
@@ -19,17 +19,21 @@ module LoggableActivity
|
|
19
19
|
# Returns:
|
20
20
|
# "SOME_ENCRYPTED_STRING"
|
21
21
|
#
|
22
|
-
def self.encrypt(data,
|
23
|
-
return nil if data.nil?
|
24
|
-
|
25
|
-
|
22
|
+
def self.encrypt(data, encoded_key)
|
23
|
+
return nil if data.nil? || encoded_key.nil?
|
24
|
+
|
25
|
+
encryption_key = Base64.decode64(encoded_key)
|
26
|
+
raise EncryptionError, "Encryption failed: Invalid encryption key length #{encryption_key.bytesize}" unless encryption_key.bytesize == 32
|
27
|
+
|
28
|
+
cipher = OpenSSL::Cipher.new('AES-256-CBC').encrypt
|
29
|
+
cipher.key = encryption_key
|
30
|
+
cipher.iv = iv = cipher.random_iv
|
26
31
|
|
27
|
-
cipher = OpenSSL::Cipher.new('AES-128-CBC').encrypt
|
28
|
-
cipher.key = Digest::SHA1.hexdigest(encryption_key)[0..15]
|
29
32
|
encrypted = cipher.update(data.to_s) + cipher.final
|
30
|
-
Base64
|
33
|
+
# Combine IV with encrypted data, encode with Base64 for storage/transmission
|
34
|
+
Base64.encode64(iv + encrypted)
|
31
35
|
rescue OpenSSL::Cipher::CipherError => e
|
32
|
-
raise EncryptionError, "Encryption failed: #{e.message}
|
36
|
+
raise EncryptionError, "Encryption failed: #{e.message}"
|
33
37
|
end
|
34
38
|
|
35
39
|
# Decrypts the given data using the given encryption key
|
@@ -40,19 +44,22 @@ module LoggableActivity
|
|
40
44
|
# Returns:
|
41
45
|
# "my secret data"
|
42
46
|
#
|
43
|
-
def self.decrypt(data,
|
44
|
-
return
|
45
|
-
|
47
|
+
def self.decrypt(data, encoded_key)
|
48
|
+
return '' if data.nil? || encoded_key.nil?
|
49
|
+
|
50
|
+
encryption_key = Base64.decode64(encoded_key)
|
51
|
+
raise EncryptionError, 'Decryption failed: Invalid encryption key length' unless encryption_key.bytesize == 32
|
52
|
+
|
53
|
+
cipher = OpenSSL::Cipher.new('AES-256-CBC').decrypt
|
54
|
+
cipher.key = encryption_key
|
46
55
|
|
47
|
-
|
48
|
-
cipher.
|
49
|
-
decrypted_data =
|
50
|
-
decrypted_output = cipher.update(decrypted_data) + cipher.final
|
51
|
-
raise 'Decryption failed: Invalid UTF-8 output' unless decrypted_output.valid_encoding?
|
56
|
+
raw_data = Base64.decode64(data)
|
57
|
+
cipher.iv = raw_data[0...cipher.iv_len] # Extract IV from the beginning of raw_data
|
58
|
+
decrypted_data = cipher.update(raw_data[cipher.iv_len..]) + cipher.final
|
52
59
|
|
53
|
-
|
60
|
+
decrypted_data.force_encoding('UTF-8')
|
54
61
|
rescue OpenSSL::Cipher::CipherError => e
|
55
|
-
raise EncryptionError, e.message
|
62
|
+
raise EncryptionError, "Decryption failed: #{e.message}"
|
56
63
|
end
|
57
64
|
|
58
65
|
def self.blank?(value)
|
@@ -9,7 +9,7 @@ module LoggableActivity
|
|
9
9
|
# Associations
|
10
10
|
belongs_to :record, polymorphic: true, optional: true
|
11
11
|
belongs_to :parent_key, class_name: 'LoggableActivity::EncryptionKey', optional: true,
|
12
|
-
|
12
|
+
foreign_key: 'parent_key_id'
|
13
13
|
|
14
14
|
# Marks the encryption key as deleted by updating the key to nil.
|
15
15
|
def mark_as_deleted
|
@@ -90,7 +90,7 @@ module LoggableActivity
|
|
90
90
|
#
|
91
91
|
def self.create_encryption_key(record_type, record_id, parent_key = nil)
|
92
92
|
if parent_key
|
93
|
-
create(record_type:, record_id:, key: random_key, parent_key:
|
93
|
+
create(record_type:, record_id:, key: random_key, parent_key:)
|
94
94
|
else
|
95
95
|
create(record_type:, record_id:, key: random_key)
|
96
96
|
end
|
@@ -107,7 +107,10 @@ module LoggableActivity
|
|
107
107
|
# "a8f4774e7f42eb253045a4db7de7b79e"
|
108
108
|
#
|
109
109
|
def self.random_key
|
110
|
-
|
110
|
+
# Generate 32 random bytes (256 bits) directly
|
111
|
+
encryption_key = SecureRandom.random_bytes(32)
|
112
|
+
# Encode the key in Base64 to ensure it's in a transferable format
|
113
|
+
Base64.encode64(encryption_key).strip
|
111
114
|
end
|
112
115
|
end
|
113
116
|
end
|