dry-credentials 0.1.0 → 0.2.0
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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +11 -1
- data/README.md +3 -3
- data/lib/dry/credentials/encryptor.rb +17 -19
- data/lib/dry/credentials/extension.rb +6 -4
- data/lib/dry/credentials/helpers.rb +1 -1
- data/lib/dry/credentials/settings.rb +1 -1
- data/lib/dry/credentials/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80d0cd76bf93e1c24651a2f55d9b2ca8493a33aab603e97bcf68db5ad1b3d88a
|
4
|
+
data.tar.gz: 14e831c767bb3b4b302b6cd042af12af3ebc21402290c9311773572ffd39dbf0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0057adafdb86c53b705125c7ef9317673010633b41a3856d1ac3cd27fd050925d0a8ded61b92b13e13bff9edbe3c7d85937445ec4a1aa9d07f627a4a6f5d135e
|
7
|
+
data.tar.gz: 46f17ca1795ad86c964fa78605b02c84a36c598cd1466823dac843181fb79d71b2f9a162c3cfea3482a80105d9a5543cf9da6c2b34fab5cf2facca939506afd4
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -2,9 +2,19 @@
|
|
2
2
|
|
3
3
|
Nothing so far
|
4
4
|
|
5
|
+
## 0.2.0
|
6
|
+
|
7
|
+
#### Breaking Changes
|
8
|
+
|
9
|
+
* Fall back to `APP_ENV` instead of `RACK_ENV`
|
10
|
+
|
11
|
+
#### Fixes
|
12
|
+
|
13
|
+
* Don't re-encrypt if credentials haven't been modified
|
14
|
+
|
5
15
|
## 0.1.0
|
6
16
|
|
7
|
-
#### Initial
|
17
|
+
#### Initial Implementation
|
8
18
|
|
9
19
|
* Require Ruby 3.0 or newer
|
10
20
|
* Class mixin featuring the `credentials` macro:
|
data/README.md
CHANGED
@@ -108,7 +108,7 @@ App.credentials.otp.meta.realm
|
|
108
108
|
|
109
109
|
Credentials are isolated into environments which most likely will, but don't necessarily have to align with the environments of the app framework you're using.
|
110
110
|
|
111
|
-
By default, the current environment is read from `RACK_ENV
|
111
|
+
By default, the current environment is read from `APP_ENV`. You shouldn't use `RACK_ENV` for this, [here's why](https://github.com/rack/rack/issues/1546).
|
112
112
|
|
113
113
|
⚠️ For safety reasons, don't share the same key across multiple environments!
|
114
114
|
|
@@ -148,7 +148,7 @@ App.credentials[:env] # => "production"
|
|
148
148
|
|
149
149
|
Setting | Default | Description
|
150
150
|
--------|---------|------------
|
151
|
-
`env` | `-> { ENV["
|
151
|
+
`env` | `-> { ENV["APP_ENV"] }` | environment such as `development`
|
152
152
|
`dir` | `"config/credentials"` | directory where encrypted credentials are stored
|
153
153
|
`cipher` | `"aes-256-gcm"` | any of `OpenSSL::Cipher.ciphers`
|
154
154
|
`digest` | `"sha256"` | sign digest used if the cipher doesn't support AEAD
|
@@ -164,4 +164,4 @@ bundle exec rake # run tests once
|
|
164
164
|
bundle exec guard # run tests whenever files are modified
|
165
165
|
```
|
166
166
|
|
167
|
-
You're welcome to [submit issues](https://github.com/svoop/dry-credentials/issues)
|
167
|
+
You're welcome to join the [discussion forum](https://github.com/svoop/dry-credentials/discussions) to ask questions or drop feature ideas, [submit issues](https://github.com/svoop/dry-credentials/issues) you may encounter or contribute code by [forking this project and submitting pull requests](https://docs.github.com/en/get-started/quickstart/fork-a-repo).
|
@@ -12,8 +12,6 @@ module Dry
|
|
12
12
|
DEFAULT_SERIALIZER = Marshal
|
13
13
|
SEPARATOR = '--'
|
14
14
|
|
15
|
-
attr_reader :cipher
|
16
|
-
|
17
15
|
# @param cipher [String] any of +OpenSSL::Cipher.ciphers+
|
18
16
|
# @param digest [String] any of +openssl list+
|
19
17
|
# @param serializer [Class] must respond to +dump+ and +load+
|
@@ -22,12 +20,12 @@ module Dry
|
|
22
20
|
@digest, @serializer = digest, serializer
|
23
21
|
end
|
24
22
|
|
25
|
-
# Generate a random key with the length
|
23
|
+
# Generate a random key with the length required by the current cipher,
|
26
24
|
# then Base64 encodes and unpacks all bytes to hex.
|
27
25
|
#
|
28
26
|
# @return [String] key
|
29
27
|
def generate_key
|
30
|
-
unpack(encode(SecureRandom.bytes(cipher.key_len)))
|
28
|
+
unpack(encode(SecureRandom.bytes(@cipher.key_len)))
|
31
29
|
end
|
32
30
|
|
33
31
|
# Encrypts the object
|
@@ -39,15 +37,15 @@ module Dry
|
|
39
37
|
# @param key [String] key (Base64 encoded and unpacked to hex)
|
40
38
|
# @return [String] encrypted and authenticated/signed string
|
41
39
|
def encrypt(object, key:)
|
42
|
-
cipher.encrypt
|
43
|
-
cipher.key = decoded_key = decode(pack(key.strip))
|
44
|
-
iv = cipher.random_iv
|
45
|
-
cipher.auth_data = '' if aead?
|
46
|
-
cipher.update(@serializer.dump(object)).then do |data|
|
47
|
-
data << cipher.final
|
40
|
+
@cipher.encrypt
|
41
|
+
@cipher.key = decoded_key = decode(pack(key.strip))
|
42
|
+
iv = @cipher.random_iv
|
43
|
+
@cipher.auth_data = '' if aead?
|
44
|
+
@cipher.update(@serializer.dump(object)).then do |data|
|
45
|
+
data << @cipher.final
|
48
46
|
data = encode(data) + SEPARATOR + encode(iv)
|
49
47
|
data << SEPARATOR + if aead?
|
50
|
-
encode(cipher.auth_tag)
|
48
|
+
encode(@cipher.auth_tag)
|
51
49
|
else
|
52
50
|
hmac(decoded_key, data)
|
53
51
|
end
|
@@ -60,8 +58,8 @@ module Dry
|
|
60
58
|
# @param key [String] key (Base64 encoded and unpacked to hex)
|
61
59
|
# @return [Object] verified and decrypted object
|
62
60
|
def decrypt(encrypted_object, key:)
|
63
|
-
cipher.decrypt
|
64
|
-
cipher.key = decoded_key = decode(pack(key.strip))
|
61
|
+
@cipher.decrypt
|
62
|
+
@cipher.key = decoded_key = decode(pack(key.strip))
|
65
63
|
payload, iv, auth_tag = encrypted_object.strip.split(SEPARATOR)
|
66
64
|
if auth_tag.nil? ||
|
67
65
|
(aead? && decode(auth_tag).bytes.length != auth_tag_length) ||
|
@@ -69,13 +67,13 @@ module Dry
|
|
69
67
|
then
|
70
68
|
fail Dry::Credentials::InvalidEncryptedObjectError
|
71
69
|
end
|
72
|
-
cipher.iv = decode(iv)
|
70
|
+
@cipher.iv = decode(iv)
|
73
71
|
if aead?
|
74
|
-
cipher.auth_tag = decode(auth_tag)
|
75
|
-
cipher.auth_data = ''
|
72
|
+
@cipher.auth_tag = decode(auth_tag)
|
73
|
+
@cipher.auth_data = ''
|
76
74
|
end
|
77
|
-
cipher.update(decode(payload)).then do |data|
|
78
|
-
data << cipher.final
|
75
|
+
@cipher.update(decode(payload)).then do |data|
|
76
|
+
data << @cipher.final
|
79
77
|
@serializer.load(data)
|
80
78
|
end
|
81
79
|
rescue OpenSSL::Cipher::CipherError, TypeError, ArgumentError
|
@@ -112,7 +110,7 @@ module Dry
|
|
112
110
|
# Associated Data) or not - in which case a HMAC signature using the
|
113
111
|
# +digest+ is used instead
|
114
112
|
def aead?
|
115
|
-
@auth ||= cipher.authenticated?
|
113
|
+
@auth ||= @cipher.authenticated?
|
116
114
|
end
|
117
115
|
|
118
116
|
def hmac(key, string)
|
@@ -36,13 +36,15 @@ module Dry
|
|
36
36
|
def edit!(env=nil)
|
37
37
|
helpers = Dry::Credentials::Helpers.new(self, env)
|
38
38
|
create = helpers.create?
|
39
|
-
yaml = helpers.read_yaml
|
39
|
+
yaml = read_yaml = helpers.read_yaml
|
40
40
|
begin
|
41
41
|
yaml = helpers.edit_yaml yaml
|
42
42
|
end until helpers.yaml_valid? yaml
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
unless yaml == read_yaml
|
44
|
+
helpers.write_yaml yaml
|
45
|
+
puts [helpers.key_ev, ENV[helpers.key_ev]].join('=') if create
|
46
|
+
reload!
|
47
|
+
end
|
46
48
|
end
|
47
49
|
|
48
50
|
# Query settings
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-credentials
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Schwyn
|
@@ -29,7 +29,7 @@ cert_chain:
|
|
29
29
|
kAyiRqgxF4dJviwtqI7mZIomWL63+kXLgjOjMe1SHxfIPo/0ji6+r1p4KYa7o41v
|
30
30
|
fwIwU1MKlFBdsjkd
|
31
31
|
-----END CERTIFICATE-----
|
32
|
-
date: 2023-
|
32
|
+
date: 2023-10-30 00:00:00.000000000 Z
|
33
33
|
dependencies:
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: debug
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
- !ruby/object:Gem::Dependency
|
77
|
-
name: minitest-
|
77
|
+
name: minitest-flash
|
78
78
|
requirement: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
@@ -203,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
203
203
|
- !ruby/object:Gem::Version
|
204
204
|
version: '0'
|
205
205
|
requirements: []
|
206
|
-
rubygems_version: 3.4.
|
206
|
+
rubygems_version: 3.4.21
|
207
207
|
signing_key:
|
208
208
|
specification_version: 4
|
209
209
|
summary: A mixin to use encrypted credentials in your classes
|
metadata.gz.sig
CHANGED
Binary file
|