kreds 1.1.1 → 1.1.2
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/CHANGELOG.md +5 -0
- data/README.md +105 -59
- data/kreds.gemspec +2 -1
- data/lib/kreds/fetch.rb +22 -45
- data/lib/kreds/inputs.rb +28 -0
- data/lib/kreds/version.rb +1 -1
- data/lib/kreds.rb +2 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 256854440242a87fc2debc95c8c7cda4c2c8fb836946179eccba3d8946863b25
|
4
|
+
data.tar.gz: 05c8465b2e8ab5a16f8b94cef84b85b074d5153bd60a143bd20719b0645b48e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea580b8a4dca8c842c7e6f9c84a678cac94b3136b084dc1c91cb8c44b73d69077532441138c4a9c8bd91f84aec8c80bbb5919a27313cc18cb20d6d2df838bc6d
|
7
|
+
data.tar.gz: a36ab8f0fe482843697cc96e28c903f08a61e35d0554bf56e696a06b4116af25ab8bb546fc546d2fa781bc37d1b137501f122224059dba298269d2128cd3bfac
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,27 +1,56 @@
|
|
1
|
-
# Kreds
|
1
|
+
# Kreds: Streamlined Rails Credentials Access
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/kreds)
|
4
4
|
[](https://github.com/brownboxdev/kreds/actions/workflows/ci.yml)
|
5
5
|
|
6
|
-
Kreds is a simpler, shorter, and safer way to access Rails credentials, with a few
|
6
|
+
Kreds is a simpler, shorter, and safer way to access Rails credentials, with a few extra features built in. Rails credentials are a convenient way to store secrets, but retrieving them could be more intuitive — that's where Kreds comes in.
|
7
7
|
|
8
|
-
|
8
|
+
**Key Features:**
|
9
|
+
|
10
|
+
- Simplified credential access with clear error messages
|
11
|
+
- Environment variable fallback support
|
12
|
+
- Environment-scoped credentials access (production, staging, development)
|
13
|
+
- Automatic blank value detection and prevention
|
14
|
+
|
15
|
+
**Before and After:**
|
9
16
|
|
10
17
|
```ruby
|
18
|
+
# Instead of this (long, silent failures if value is missing):
|
11
19
|
Rails.application.credentials[:recaptcha][:site_key]
|
12
|
-
|
20
|
+
# => nil
|
13
21
|
|
14
|
-
|
22
|
+
# Or this (long, unclear errors):
|
23
|
+
Rails.application.credentials[:captcha][:site_key]
|
24
|
+
# => undefined method `[]' for nil:NilClass (NoMethodError)
|
15
25
|
|
16
|
-
|
26
|
+
# Or even this (longer, still unclear errors):
|
27
|
+
Rails.application.credentials.fetch(:recaptcha).fetch(:key)
|
28
|
+
# => key not found: :key (KeyError)
|
29
|
+
|
30
|
+
# You can write this (shorter, human-readable errors):
|
17
31
|
Kreds.fetch!(:recaptcha, :site_key)
|
32
|
+
# => Blank value in credentials: [:recaptcha][:site_key] (Kreds::BlankCredentialsError)
|
33
|
+
Kreds.fetch!(:captcha, :site_key)
|
34
|
+
# => Credentials key not found: [:captcha] (Kreds::UnknownCredentialsError)
|
18
35
|
```
|
19
36
|
|
20
|
-
|
37
|
+
## Table of Contents
|
38
|
+
|
39
|
+
**Gem Usage:**
|
40
|
+
- [Installation](#installation)
|
41
|
+
- [Credential Fetching](#credential-fetching)
|
42
|
+
- [Environment-Scoped Credentials](#environment-scoped-credentials)
|
43
|
+
- [Environment Variables](#environment-variables)
|
44
|
+
- [Debug and Inspection](#debug-and-inspection)
|
45
|
+
|
46
|
+
**Community Resources:**
|
47
|
+
- [Contributing](#contributing)
|
48
|
+
- [License](#license)
|
49
|
+
- [Code of Conduct](#code-of-conduct)
|
21
50
|
|
22
51
|
## Installation
|
23
52
|
|
24
|
-
Add
|
53
|
+
Add Kreds to your Gemfile:
|
25
54
|
|
26
55
|
```ruby
|
27
56
|
gem "kreds"
|
@@ -29,98 +58,115 @@ gem "kreds"
|
|
29
58
|
|
30
59
|
And then execute:
|
31
60
|
|
32
|
-
```
|
61
|
+
```bash
|
33
62
|
bundle install
|
34
63
|
```
|
35
64
|
|
36
|
-
##
|
37
|
-
|
38
|
-
### Fetch from credentials
|
65
|
+
## Credential Fetching
|
39
66
|
|
40
|
-
|
41
|
-
Kreds.fetch!(:aws, :s3, :credentials, :access_key_id)
|
42
|
-
```
|
43
|
-
|
44
|
-
If you make a typo, such as writing `access_key` instead of `access_key_id`, Kreds will raise `Kreds::UnknownCredentialsError` with the message: `Credentials key not found: [:aws][:s3][:credentials][:access_key]`.
|
67
|
+
**`Kreds.fetch!(*keys, var: nil, &block)`**
|
45
68
|
|
46
|
-
|
69
|
+
Fetches credentials from the Rails credentials store.
|
47
70
|
|
48
|
-
|
71
|
+
**Parameters:**
|
72
|
+
- `*keys` - Variable number of symbols representing the key path
|
73
|
+
- `var` - Optional environment variable name as fallback
|
74
|
+
- `&block` - Optional block to execute if fetch fails
|
49
75
|
|
50
|
-
|
76
|
+
**Returns:** The credential value
|
51
77
|
|
52
|
-
|
78
|
+
**Raises:**
|
79
|
+
- `Kreds::UnknownCredentialsError` - if the key path doesn't exist
|
80
|
+
- `Kreds::BlankCredentialsError` - if the value exists but is blank
|
53
81
|
|
54
82
|
```ruby
|
55
|
-
|
56
|
-
|
83
|
+
# Basic usage
|
84
|
+
Kreds.fetch!(:aws, :s3, :credentials, :access_key_id)
|
57
85
|
|
58
|
-
|
86
|
+
# With environment variable fallback
|
87
|
+
Kreds.fetch!(:aws, :access_key_id, var: "AWS_ACCESS_KEY_ID")
|
59
88
|
|
60
|
-
|
89
|
+
# With block
|
90
|
+
Kreds.fetch!(:api_key) do
|
91
|
+
raise MyCustomError, "API key not configured"
|
92
|
+
end
|
93
|
+
```
|
61
94
|
|
62
|
-
|
95
|
+
## Environment-Scoped Credentials
|
63
96
|
|
64
|
-
|
97
|
+
**`Kreds.env_fetch!(*keys, var: nil, &block)`**
|
65
98
|
|
66
|
-
|
67
|
-
Kreds.var!("AWS_ACCESS_KEY_ID")
|
68
|
-
```
|
99
|
+
Fetches credentials scoped by the current Rails environment (e.g., `:production`, `:staging`, `:development`).
|
69
100
|
|
70
|
-
|
101
|
+
**Parameters:** Same as `fetch!`
|
71
102
|
|
72
|
-
|
103
|
+
**Returns:** The credential value from `Rails.application.credentials[Rails.env]` followed by the provided key path
|
73
104
|
|
74
|
-
|
105
|
+
**Raises:** Same exceptions as `fetch!`
|
75
106
|
|
76
107
|
```ruby
|
108
|
+
# Looks in credentials[:production][:recaptcha][:site_key] in production
|
77
109
|
Kreds.env_fetch!(:recaptcha, :site_key)
|
78
110
|
```
|
79
111
|
|
80
|
-
|
112
|
+
## Environment Variables
|
81
113
|
|
82
|
-
|
114
|
+
**`Kreds.var!(name, &block)`**
|
83
115
|
|
84
|
-
|
85
|
-
|
86
|
-
|
116
|
+
Fetches a value directly from environment variables.
|
117
|
+
|
118
|
+
**Parameters:**
|
119
|
+
- `name` - Environment variable name
|
120
|
+
- `&block` - Optional block to execute if variable is missing/blank
|
87
121
|
|
88
|
-
|
122
|
+
**Returns:** The environment variable value
|
89
123
|
|
90
|
-
|
124
|
+
**Raises:**
|
125
|
+
- `Kreds::UnknownEnvironmentVariableError` - if the variable doesn't exist
|
126
|
+
- `Kreds::BlankEnvironmentVariableError` - if the variable exists but is blank
|
91
127
|
|
92
128
|
```ruby
|
93
|
-
|
94
|
-
|
95
|
-
end
|
129
|
+
# Direct environment variable access
|
130
|
+
Kreds.var!("AWS_ACCESS_KEY_ID")
|
96
131
|
|
132
|
+
# With block
|
97
133
|
Kreds.var!("THREADS") { 1 }
|
98
134
|
```
|
99
135
|
|
100
|
-
|
136
|
+
## Debug and Inspection
|
101
137
|
|
102
|
-
|
138
|
+
**`Kreds.show`**
|
139
|
+
|
140
|
+
Useful for debugging and exploring available credentials in the Rails console.
|
141
|
+
|
142
|
+
**Returns:** Hash containing all credentials
|
103
143
|
|
104
144
|
```ruby
|
105
145
|
Kreds.show
|
146
|
+
# => { aws: { access_key_id: "...", secret_access_key: "..." }, ... }
|
106
147
|
```
|
107
148
|
|
108
|
-
Useful for debugging or working in the Rails console.
|
109
|
-
|
110
|
-
## Problems?
|
111
|
-
|
112
|
-
Facing a problem or want to suggest an enhancement?
|
113
|
-
|
114
|
-
- **Open a Discussion**: If you have a question, experience difficulties using the gem, or have a suggestion for improvements, feel free to use the Discussions section.
|
115
|
-
|
116
|
-
Encountered a bug?
|
117
|
-
|
118
|
-
- **Create an Issue**: If you've identified a bug, please create an issue. Be sure to provide detailed information about the problem, including the steps to reproduce it.
|
119
|
-
- **Contribute a Solution**: Found a fix for the issue? Feel free to create a pull request with your changes.
|
120
|
-
|
121
149
|
## Contributing
|
122
150
|
|
123
|
-
|
151
|
+
### Getting Help
|
152
|
+
Have a question or need assistance? Open a discussion in our [discussions section](https://github.com/brownboxdev/kreds/discussions) for:
|
153
|
+
- Usage questions
|
154
|
+
- Implementation guidance
|
155
|
+
- Feature suggestions
|
156
|
+
|
157
|
+
### Reporting Issues
|
158
|
+
Found a bug? Please [create an issue](https://github.com/brownboxdev/kreds/issues) with:
|
159
|
+
- A clear description of the problem
|
160
|
+
- Steps to reproduce the issue
|
161
|
+
- Your environment details (Rails version, Ruby version, etc.)
|
162
|
+
|
163
|
+
### Contributing Code
|
164
|
+
Ready to contribute? You can:
|
165
|
+
- Fix bugs by submitting pull requests
|
166
|
+
- Improve documentation
|
167
|
+
- Add new features (please discuss first in our [discussions section](https://github.com/brownboxdev/kreds/discussions))
|
168
|
+
|
169
|
+
Before contributing, please read the [contributing guidelines](https://github.com/brownboxdev/kreds/blob/master/CONTRIBUTING.md)
|
124
170
|
|
125
171
|
## License
|
126
172
|
|
data/kreds.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.homepage = "https://github.com/brownboxdev/kreds"
|
8
8
|
spec.metadata["homepage_uri"] = spec.homepage
|
9
9
|
spec.metadata["source_code_uri"] = spec.homepage
|
10
|
-
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/
|
10
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/master/CHANGELOG.md"
|
11
11
|
spec.metadata["rubygems_mfa_required"] = "true"
|
12
12
|
spec.summary = "The missing shorthand for Rails credentials"
|
13
13
|
spec.license = "MIT"
|
@@ -19,5 +19,6 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
+
spec.add_dependency "dry-types", "~> 1.8"
|
22
23
|
spec.add_dependency "rails", ">= 7.1", "< 8.1"
|
23
24
|
end
|
data/lib/kreds/fetch.rb
CHANGED
@@ -1,82 +1,59 @@
|
|
1
1
|
module Kreds
|
2
2
|
module Fetch
|
3
3
|
def fetch!(*keys, var: nil, &)
|
4
|
-
|
5
|
-
validate_var!(var)
|
4
|
+
symbolized_keys = Kreds::Inputs.process(keys, as: :symbol_array)
|
6
5
|
|
7
6
|
path = []
|
8
7
|
|
9
|
-
|
8
|
+
symbolized_keys.reduce(Kreds.show) do |hash, key|
|
10
9
|
path << key
|
11
|
-
fetch_key(hash, key, path,
|
10
|
+
fetch_key(hash, key, path, symbolized_keys)
|
12
11
|
end
|
13
12
|
rescue Kreds::BlankCredentialsError, Kreds::UnknownCredentialsError => e
|
14
|
-
fallback_to_var(e, var, &)
|
13
|
+
fallback_to_var(e, Kreds::Inputs.process(var, as: :string, optional: true), &)
|
15
14
|
end
|
16
15
|
|
17
16
|
def env_fetch!(*keys, var: nil, &)
|
18
|
-
fetch!(Rails.env, *keys, var
|
17
|
+
fetch!(Rails.env, *keys, var:, &)
|
19
18
|
end
|
20
19
|
|
21
20
|
def var!(var, &)
|
22
|
-
|
21
|
+
value = ENV.fetch(Kreds::Inputs.process(var, as: :string))
|
23
22
|
|
24
|
-
|
23
|
+
return raise_or_yield(Kreds::BlankEnvironmentVariableError.new("Blank value in environment variable: #{var.inspect}"), &) if value.blank?
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
raise_or_yield(
|
25
|
+
value
|
26
|
+
rescue KeyError
|
27
|
+
raise_or_yield(Kreds::UnknownEnvironmentVariableError.new("Environment variable not found: #{var.inspect}"), &)
|
29
28
|
end
|
30
29
|
|
31
30
|
private
|
32
31
|
|
33
|
-
def validate_keys!(keys)
|
34
|
-
raise Kreds::InvalidArgumentError, "No keys provided" if keys.empty?
|
35
|
-
|
36
|
-
return if keys.all? { _1.is_a?(Symbol) || _1.is_a?(String) }
|
37
|
-
|
38
|
-
raise Kreds::InvalidArgumentError, "Credentials Key must be a Symbol or a String"
|
39
|
-
end
|
40
|
-
|
41
|
-
def validate_var!(var)
|
42
|
-
raise Kreds::InvalidArgumentError, "Environment variable must be a String" if var.present? && !var.is_a?(String)
|
43
|
-
end
|
44
|
-
|
45
32
|
def fetch_key(hash, key, path, keys)
|
46
|
-
value = hash.fetch(key
|
33
|
+
value = hash.fetch(key)
|
47
34
|
|
48
|
-
raise Kreds::BlankCredentialsError, "Blank value in credentials:
|
49
|
-
raise Kreds::UnknownCredentialsError, "Credentials key not found:
|
35
|
+
raise Kreds::BlankCredentialsError, "Blank value in credentials: #{path_to_s(path)}" if value.blank?
|
36
|
+
raise Kreds::UnknownCredentialsError, "Credentials key not found: #{path_to_s(path)}[:#{keys[path.size]}]" unless value.is_a?(Hash) || keys == path
|
50
37
|
|
51
38
|
value
|
52
39
|
rescue KeyError
|
53
|
-
raise Kreds::UnknownCredentialsError, "Credentials key not found:
|
40
|
+
raise Kreds::UnknownCredentialsError, "Credentials key not found: #{path_to_s(path)}"
|
54
41
|
end
|
55
42
|
|
56
43
|
def fallback_to_var(error, var, &)
|
57
|
-
if var.
|
58
|
-
result, success = check_var(var)
|
59
|
-
|
60
|
-
return result if success
|
44
|
+
return raise_or_yield(error, &) if var.blank?
|
61
45
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
raise_or_yield(error, &)
|
66
|
-
end
|
67
|
-
|
68
|
-
def check_var(var)
|
69
|
-
value = ENV.fetch(var)
|
70
|
-
|
71
|
-
return [Kreds::BlankEnvironmentVariableError.new("Blank value in environment variable: #{var.inspect}"), false] if value.blank?
|
72
|
-
|
73
|
-
[value, true]
|
74
|
-
rescue KeyError
|
75
|
-
[Kreds::UnknownEnvironmentVariableError.new("Environment variable not found: #{var.inspect}"), false]
|
46
|
+
var!(var, &)
|
47
|
+
rescue Kreds::BlankEnvironmentVariableError, Kreds::UnknownEnvironmentVariableError => e
|
48
|
+
raise_or_yield(Kreds::Error.new("#{error.message}, #{e.message}"), &)
|
76
49
|
end
|
77
50
|
|
78
51
|
def raise_or_yield(error, &)
|
79
52
|
block_given? ? yield : raise(error)
|
80
53
|
end
|
54
|
+
|
55
|
+
def path_to_s(path)
|
56
|
+
"[:#{path.join("][:")}]"
|
57
|
+
end
|
81
58
|
end
|
82
59
|
end
|
data/lib/kreds/inputs.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "dry-types"
|
2
|
+
|
3
|
+
module Kreds
|
4
|
+
module Inputs
|
5
|
+
extend self
|
6
|
+
|
7
|
+
include Dry.Types()
|
8
|
+
|
9
|
+
TYPES = {
|
10
|
+
symbol_array: -> { self::Array.of(self::Coercible::Symbol).constrained(min_size: 1) },
|
11
|
+
string: -> { self::Strict::String },
|
12
|
+
boolean: -> { self::Strict::Bool }
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
def process(value, as:, optional: false)
|
16
|
+
checker = type_for(as)
|
17
|
+
checker = checker.optional if optional
|
18
|
+
|
19
|
+
checker[value]
|
20
|
+
rescue Dry::Types::CoercionError => e
|
21
|
+
raise Kreds::InvalidArgumentError, e
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def type_for(name) = Kreds::Inputs::TYPES.fetch(name).call
|
27
|
+
end
|
28
|
+
end
|
data/lib/kreds/version.rb
CHANGED
data/lib/kreds.rb
CHANGED
@@ -2,6 +2,7 @@ require_relative "kreds/version"
|
|
2
2
|
|
3
3
|
require "rails"
|
4
4
|
|
5
|
+
require_relative "kreds/inputs"
|
5
6
|
require_relative "kreds/fetch"
|
6
7
|
require_relative "kreds/show"
|
7
8
|
|
@@ -13,6 +14,6 @@ module Kreds
|
|
13
14
|
class UnknownCredentialsError < Error; end
|
14
15
|
class UnknownEnvironmentVariableError < Error; end
|
15
16
|
|
16
|
-
extend ::Kreds::Fetch
|
17
17
|
extend ::Kreds::Show
|
18
|
+
extend ::Kreds::Fetch
|
18
19
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kreds
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- enjaku4
|
@@ -9,6 +9,20 @@ bindir: bin
|
|
9
9
|
cert_chain: []
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: dry-types
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '1.8'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '1.8'
|
12
26
|
- !ruby/object:Gem::Dependency
|
13
27
|
name: rails
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,6 +53,7 @@ files:
|
|
39
53
|
- kreds.gemspec
|
40
54
|
- lib/kreds.rb
|
41
55
|
- lib/kreds/fetch.rb
|
56
|
+
- lib/kreds/inputs.rb
|
42
57
|
- lib/kreds/show.rb
|
43
58
|
- lib/kreds/version.rb
|
44
59
|
homepage: https://github.com/brownboxdev/kreds
|
@@ -47,7 +62,7 @@ licenses:
|
|
47
62
|
metadata:
|
48
63
|
homepage_uri: https://github.com/brownboxdev/kreds
|
49
64
|
source_code_uri: https://github.com/brownboxdev/kreds
|
50
|
-
changelog_uri: https://github.com/brownboxdev/kreds/blob/
|
65
|
+
changelog_uri: https://github.com/brownboxdev/kreds/blob/master/CHANGELOG.md
|
51
66
|
rubygems_mfa_required: 'true'
|
52
67
|
rdoc_options: []
|
53
68
|
require_paths:
|