rails_credentials_cipher 1.0.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 +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +21 -0
- data/.tool-versions +1 -0
- data/AGENTS.md +27 -0
- data/LICENSE.txt +21 -0
- data/README.md +70 -0
- data/Rakefile +3 -0
- data/lib/generators/rails_credentials_cipher/install/install_generator.rb +40 -0
- data/lib/rails_credentials_cipher/cipher.rb +66 -0
- data/lib/rails_credentials_cipher/railtie.rb +9 -0
- data/lib/rails_credentials_cipher/version.rb +5 -0
- data/lib/rails_credentials_cipher.rb +87 -0
- data/lib/tasks/credentials.rake +36 -0
- data/sig/rails_credentials_cipher.rbs +58 -0
- metadata +70 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 412dc01065aa8cd5f4fde42a2ee138a9d16309feee95cc8f662b83cead22804d
|
|
4
|
+
data.tar.gz: 20bd9b1fe47fb6f5fbe266e79a84cb08aed3ae06bae71ea83ecb17bd72cf5cb2
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 96e844c86ab106d790a1ec44117581e0dd1418a8b14bd8de9e60afd4125fba385264b0cd5bc62617c61f693e4e1fcbde39e8a0334eedd9887108812beaea964e
|
|
7
|
+
data.tar.gz: d1519c0a71b45fa7422822f7840ba0ed2b1ca5847b9c5dd43fc293de556622834b0872a9b8534e3a0b1ceaa482296cb0718764a894db4ba60e1b71d5ec6c08a5
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
plugins:
|
|
2
|
+
- rubocop-on-rbs
|
|
3
|
+
- rubocop-rake
|
|
4
|
+
- rubocop-rspec
|
|
5
|
+
|
|
6
|
+
AllCops:
|
|
7
|
+
# The oldest Ruby the gem supports (required_ruby_version), not the one in .tool-versions
|
|
8
|
+
TargetRubyVersion: 3.3
|
|
9
|
+
NewCops: enable
|
|
10
|
+
|
|
11
|
+
# Do not enforce documentation
|
|
12
|
+
Style/Documentation:
|
|
13
|
+
Enabled: false
|
|
14
|
+
|
|
15
|
+
# A round trip is one behaviour with a return value, a file on disk and a message
|
|
16
|
+
RSpec/MultipleExpectations:
|
|
17
|
+
Max: 3
|
|
18
|
+
|
|
19
|
+
# A round trip needs its setup, the call and the check on disk
|
|
20
|
+
RSpec/ExampleLength:
|
|
21
|
+
Enabled: false
|
data/.tool-versions
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby 4.0.5
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# RailsCredentialsCipher
|
|
2
|
+
|
|
3
|
+
@README.md
|
|
4
|
+
|
|
5
|
+
A gem that adds `credentials:decrypt` and `credentials:encrypt` rake tasks to Rails applications.
|
|
6
|
+
|
|
7
|
+
## Instructions
|
|
8
|
+
|
|
9
|
+
- MUST pass `bundle exec rspec`, `bundle exec rubocop` and `bundle exec steep check` before finishing. MUST NOT disable a cop or a Steep diagnostic without the reason next to it.
|
|
10
|
+
- MUST NOT print or log decrypted content; messages name paths only.
|
|
11
|
+
- Specs MUST NOT need a Rails application; `stub_rails` in `spec/spec_helper.rb` stands in for it.
|
|
12
|
+
- `sig/rails_credentials_cipher.rbs` types the gem and `sig/external/` the slice of Rails it calls; Steep checks `lib/` against both, so a method is not done until its signature is. `sig/external/` is not shipped with the gem.
|
|
13
|
+
- Ruby floor is the oldest version still maintained (3.3): `required_ruby_version`, `TargetRubyVersion` and the CI matrix move together, and `TargetRubyVersion` stays below `.tool-versions` on purpose.
|
|
14
|
+
|
|
15
|
+
## Development
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
mise install && bin/setup # Ruby from .tool-versions, then bundle install
|
|
19
|
+
bundle exec rspec # tests; add a path or path:line for one file or example
|
|
20
|
+
bundle exec rubocop -A # lint with auto-fix, RBS files included
|
|
21
|
+
bundle exec steep check # types: lib/ against sig/
|
|
22
|
+
bundle exec bundler-audit check --update # dependency audit
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
To try it in a Rails application, add `gem "rails_credentials_cipher", path: "../rails_credentials_cipher", group: :development` to its Gemfile and run `bin/rails credentials:decrypt` there with its `config/master.key` present.
|
|
26
|
+
|
|
27
|
+
Release: bump `lib/rails_credentials_cipher/version.rb`, `bundle install` so `Gemfile.lock` follows, commit, then `bundle exec rake release`.
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 thisismydesign
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# RailsCredentialsCipher
|
|
2
|
+
|
|
3
|
+
#### Decrypt, edit, and encrypt Rails credentials.
|
|
4
|
+
|
|
5
|
+
Rails keeps your credentials encrypted and only lets you change them through `bin/rails credentials:edit`, which opens them in a terminal editor. This gem lets you take them out as a plain file, edit that file with whatever you like — your IDE, a coding agent, a script — and encrypt it back.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add to your application's Gemfile:
|
|
10
|
+
|
|
11
|
+
```rb
|
|
12
|
+
gem "rails_credentials_cipher", group: :development
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Then keep the decrypted files out of git:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
bin/rails generate rails_credentials_cipher:install
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This adds to `.gitignore`:
|
|
22
|
+
|
|
23
|
+
```gitignore
|
|
24
|
+
/config/credentials.yml
|
|
25
|
+
/config/credentials/*.yml
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
bin/rails credentials:decrypt # config/credentials.yml.enc -> config/credentials.yml
|
|
32
|
+
# edit config/credentials.yml
|
|
33
|
+
bin/rails credentials:encrypt # config/credentials.yml -> config/credentials.yml.enc
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
For per-environment credentials, add the environment:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
bin/rails credentials:decrypt:production # config/credentials/production.yml.enc -> config/credentials/production.yml
|
|
40
|
+
bin/rails credentials:encrypt:production
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Development
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
mise install && bin/setup # Ruby from .tool-versions, then bundle install
|
|
47
|
+
bundle exec rspec # tests
|
|
48
|
+
bundle exec rubocop -A # lint with auto-fix
|
|
49
|
+
bundle exec steep check # types: lib/ against sig/
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
To try it in a Rails application, point its Gemfile at your checkout and run the tasks there:
|
|
53
|
+
|
|
54
|
+
```rb
|
|
55
|
+
gem "rails_credentials_cipher", path: "../rails_credentials_cipher", group: :development
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
To release, bump the version in `lib/rails_credentials_cipher/version.rb`, run `bundle install` so `Gemfile.lock` follows, commit, then:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
bundle exec rake release # tags v<version>, pushes the commits and the tag, pushes the gem to rubygems.org
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Contributing
|
|
65
|
+
|
|
66
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/thisismydesign/rails_credentials_cipher.
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
|
|
70
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails/generators'
|
|
4
|
+
|
|
5
|
+
module RailsCredentialsCipher
|
|
6
|
+
module Generators
|
|
7
|
+
# bin/rails generate rails_credentials_cipher:install
|
|
8
|
+
class InstallGenerator < Rails::Generators::Base
|
|
9
|
+
desc 'Adds the decrypted credentials files to .gitignore'
|
|
10
|
+
|
|
11
|
+
IGNORES = ['/config/credentials.yml', '/config/credentials/*.yml'].freeze
|
|
12
|
+
|
|
13
|
+
def ignore_decrypted_credentials
|
|
14
|
+
missing = IGNORES.reject { |pattern| ignored?(pattern) }
|
|
15
|
+
return say_status :identical, '.gitignore already ignores the decrypted credentials', :blue if missing.empty?
|
|
16
|
+
|
|
17
|
+
lines = "# Decrypted credentials, see rails_credentials_cipher\n#{missing.join("\n")}\n"
|
|
18
|
+
if File.exist?(gitignore_path)
|
|
19
|
+
append_to_file '.gitignore', "\n#{lines}"
|
|
20
|
+
else
|
|
21
|
+
create_file '.gitignore', lines
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def gitignore_path
|
|
28
|
+
File.join(destination_root, '.gitignore')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# A pattern with or without the leading slash covers the same file at the root.
|
|
32
|
+
def ignored?(pattern)
|
|
33
|
+
return false unless File.exist?(gitignore_path)
|
|
34
|
+
|
|
35
|
+
File.readlines(gitignore_path, chomp: true).map { |line| line.strip.delete_prefix('/') }
|
|
36
|
+
.include?(pattern.delete_prefix('/'))
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'pathname'
|
|
4
|
+
require 'active_support'
|
|
5
|
+
require 'active_support/encrypted_file'
|
|
6
|
+
|
|
7
|
+
module RailsCredentialsCipher
|
|
8
|
+
# Moves one encrypted file between its encrypted form (`config/credentials.yml.enc`)
|
|
9
|
+
# and a plain file next to it (`config/credentials.yml`), using the same
|
|
10
|
+
# ActiveSupport::EncryptedFile that Rails reads the credentials with.
|
|
11
|
+
class Cipher
|
|
12
|
+
attr_reader :encrypted_path, :key_path, :env_key, :plain_path
|
|
13
|
+
|
|
14
|
+
def initialize(encrypted_path:, key_path:, env_key: 'RAILS_MASTER_KEY', plain_path: nil)
|
|
15
|
+
@encrypted_path = Pathname(encrypted_path)
|
|
16
|
+
@key_path = Pathname(key_path)
|
|
17
|
+
@env_key = env_key
|
|
18
|
+
@plain_path = plain_path ? Pathname(plain_path) : default_plain_path
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Writes the decrypted content to the plain path. Returns the plain path.
|
|
22
|
+
def decrypt
|
|
23
|
+
plain_path.binwrite(encrypted_file.read)
|
|
24
|
+
plain_path
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Encrypts the plain file over the encrypted path. Returns the encrypted
|
|
28
|
+
# path when it was rewritten and nil when the content was already the same,
|
|
29
|
+
# so an unchanged file does not get a new ciphertext.
|
|
30
|
+
def encrypt
|
|
31
|
+
raise Error, "#{plain_path} does not exist, decrypt first" unless plain_path.exist?
|
|
32
|
+
|
|
33
|
+
contents = plain_path.binread
|
|
34
|
+
return if unchanged?(contents)
|
|
35
|
+
|
|
36
|
+
encrypted_file.write(contents)
|
|
37
|
+
encrypted_path
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def default_plain_path
|
|
43
|
+
unless encrypted_path.extname == '.enc'
|
|
44
|
+
raise Error,
|
|
45
|
+
"cannot derive a plain path from #{encrypted_path}, pass plain_path:"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
encrypted_path.sub_ext('')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def unchanged?(contents)
|
|
52
|
+
encrypted_path.exist? && encrypted_file.read == contents
|
|
53
|
+
rescue ActiveSupport::MessageEncryptor::InvalidMessage
|
|
54
|
+
false
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def encrypted_file
|
|
58
|
+
@encrypted_file ||= ActiveSupport::EncryptedFile.new(
|
|
59
|
+
content_path: encrypted_path,
|
|
60
|
+
key_path: key_path,
|
|
61
|
+
env_key: env_key,
|
|
62
|
+
raise_if_missing_key: true
|
|
63
|
+
)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'English'
|
|
4
|
+
require_relative 'rails_credentials_cipher/version'
|
|
5
|
+
require_relative 'rails_credentials_cipher/cipher'
|
|
6
|
+
require_relative 'rails_credentials_cipher/railtie' if defined?(Rails::Railtie)
|
|
7
|
+
|
|
8
|
+
module RailsCredentialsCipher
|
|
9
|
+
class Error < StandardError; end
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
# Decrypts the application's credentials into a plain file next to the
|
|
13
|
+
# encrypted one, and warns when that file is not ignored by git.
|
|
14
|
+
def decrypt(environment: nil, out: $stdout)
|
|
15
|
+
cipher = cipher(environment:)
|
|
16
|
+
explaining(cipher) { cipher.decrypt }
|
|
17
|
+
out.puts "Decrypted #{relative(cipher.encrypted_path)} to #{relative(cipher.plain_path)}"
|
|
18
|
+
out.puts "Warning: #{relative(cipher.plain_path)} is not ignored by git" if git_tracked?(cipher.plain_path)
|
|
19
|
+
cipher.plain_path
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Encrypts the plain file back over the application's credentials.
|
|
23
|
+
def encrypt(environment: nil, out: $stdout)
|
|
24
|
+
cipher = cipher(environment:)
|
|
25
|
+
if explaining(cipher) { cipher.encrypt }
|
|
26
|
+
out.puts "Encrypted #{relative(cipher.plain_path)} to #{relative(cipher.encrypted_path)}"
|
|
27
|
+
else
|
|
28
|
+
out.puts "#{relative(cipher.encrypted_path)} already matches #{relative(cipher.plain_path)}, nothing to do"
|
|
29
|
+
end
|
|
30
|
+
cipher.encrypted_path
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# The environments the application defines, which is what Rails' own
|
|
34
|
+
# credentials command offers for --environment.
|
|
35
|
+
def environments
|
|
36
|
+
Dir[Rails.root.join('config/environments/*.rb').to_s].map { |file| File.basename(file, '.rb') }.sort
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# The cipher for the credentials the running application would use, or for
|
|
40
|
+
# the given environment's `config/credentials/<environment>.yml.enc`. The key
|
|
41
|
+
# falls back from `config/credentials/<environment>.key` to `config/master.key`
|
|
42
|
+
# the way Rails does; `RAILS_MASTER_KEY` wins over both.
|
|
43
|
+
def cipher(environment: nil)
|
|
44
|
+
encrypted_path, key_path = paths(environment:)
|
|
45
|
+
Cipher.new(encrypted_path:, key_path:)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
# Turns the encryption errors into one Error whose message says what to do.
|
|
51
|
+
def explaining(cipher)
|
|
52
|
+
yield
|
|
53
|
+
rescue ActiveSupport::EncryptedFile::MissingKeyError
|
|
54
|
+
raise Error, "No key for #{relative(cipher.encrypted_path)}: " \
|
|
55
|
+
"set #{cipher.env_key} or write it to #{relative(cipher.key_path)}"
|
|
56
|
+
rescue ActiveSupport::MessageEncryptor::InvalidMessage
|
|
57
|
+
raise Error, "Could not decrypt #{relative(cipher.encrypted_path)}: " \
|
|
58
|
+
"the key in #{cipher.env_key} or #{relative(cipher.key_path)} is not the one it was encrypted with"
|
|
59
|
+
rescue ActiveSupport::EncryptedFile::MissingContentError
|
|
60
|
+
raise Error, "#{relative(cipher.encrypted_path)} does not exist"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def paths(environment:)
|
|
64
|
+
return app_paths unless environment
|
|
65
|
+
|
|
66
|
+
key_path = Rails.root.join("config/credentials/#{environment}.key")
|
|
67
|
+
key_path = Rails.root.join('config/master.key') unless key_path.exist?
|
|
68
|
+
[Rails.root.join("config/credentials/#{environment}.yml.enc"), key_path]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def app_paths
|
|
72
|
+
config = Rails.application.config.credentials
|
|
73
|
+
[Rails.root.join(config.content_path), Rails.root.join(config.key_path)]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def relative(path)
|
|
77
|
+
path.relative_path_from(Rails.root)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# True only when git says the file is not ignored; a missing git or a
|
|
81
|
+
# directory outside any repository is not a reason to warn.
|
|
82
|
+
def git_tracked?(path)
|
|
83
|
+
system('git', 'check-ignore', '-q', path.to_s, chdir: Rails.root.to_s, out: File::NULL, err: File::NULL)
|
|
84
|
+
$CHILD_STATUS&.exitstatus == 1
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Stops with the explanation instead of a stack trace.
|
|
4
|
+
abort_on_error = lambda do |&work|
|
|
5
|
+
work.call
|
|
6
|
+
rescue RailsCredentialsCipher::Error => e
|
|
7
|
+
abort e.message
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
namespace :credentials do
|
|
11
|
+
desc 'Decrypt the credentials into a plain file for editing'
|
|
12
|
+
task decrypt: :environment do
|
|
13
|
+
abort_on_error.call { RailsCredentialsCipher.decrypt }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
desc 'Encrypt the plain file back over the credentials'
|
|
17
|
+
task encrypt: :environment do
|
|
18
|
+
abort_on_error.call { RailsCredentialsCipher.encrypt }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
RailsCredentialsCipher.environments.each do |env|
|
|
22
|
+
namespace :decrypt do
|
|
23
|
+
desc "Decrypt config/credentials/#{env}.yml.enc into a plain file for editing"
|
|
24
|
+
task env => :environment do
|
|
25
|
+
abort_on_error.call { RailsCredentialsCipher.decrypt(environment: env) }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
namespace :encrypt do
|
|
30
|
+
desc "Encrypt the plain file back over config/credentials/#{env}.yml.enc"
|
|
31
|
+
task env => :environment do
|
|
32
|
+
abort_on_error.call { RailsCredentialsCipher.encrypt(environment: env) }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module RailsCredentialsCipher
|
|
2
|
+
VERSION: String
|
|
3
|
+
|
|
4
|
+
class Error < StandardError
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
interface _Puts
|
|
8
|
+
def puts: (*untyped) -> void
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
type paths = [Pathname, Pathname]
|
|
12
|
+
|
|
13
|
+
def self.decrypt: (?environment: String?, ?out: _Puts) -> Pathname
|
|
14
|
+
def self.encrypt: (?environment: String?, ?out: _Puts) -> Pathname
|
|
15
|
+
def self.environments: () -> Array[String]
|
|
16
|
+
def self.cipher: (?environment: String?) -> Cipher
|
|
17
|
+
|
|
18
|
+
def self.explaining: [T] (Cipher cipher) { () -> T } -> T
|
|
19
|
+
def self.paths: (environment: String?) -> paths
|
|
20
|
+
def self.app_paths: () -> paths
|
|
21
|
+
def self.relative: (Pathname path) -> Pathname
|
|
22
|
+
def self.git_tracked?: (Pathname path) -> bool
|
|
23
|
+
|
|
24
|
+
class Cipher
|
|
25
|
+
attr_reader encrypted_path: Pathname
|
|
26
|
+
attr_reader key_path: Pathname
|
|
27
|
+
attr_reader env_key: String
|
|
28
|
+
attr_reader plain_path: Pathname
|
|
29
|
+
|
|
30
|
+
@encrypted_file: ActiveSupport::EncryptedFile?
|
|
31
|
+
|
|
32
|
+
def initialize: (encrypted_path: String | Pathname, key_path: String | Pathname, ?env_key: String, ?plain_path: (String | Pathname)?) -> void
|
|
33
|
+
def decrypt: () -> Pathname
|
|
34
|
+
def encrypt: () -> Pathname?
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def default_plain_path: () -> Pathname
|
|
39
|
+
def unchanged?: (String contents) -> bool
|
|
40
|
+
def encrypted_file: () -> ActiveSupport::EncryptedFile
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class Railtie < Rails::Railtie
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
module Generators
|
|
47
|
+
class InstallGenerator < Rails::Generators::Base
|
|
48
|
+
IGNORES: Array[String]
|
|
49
|
+
|
|
50
|
+
def ignore_decrypted_credentials: () -> void
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def gitignore_path: () -> String
|
|
55
|
+
def ignored?: (String pattern) -> bool
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rails_credentials_cipher
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- thisismydesign
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: railties
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.1'
|
|
26
|
+
email:
|
|
27
|
+
- git.thisismydesign@gmail.com
|
|
28
|
+
executables: []
|
|
29
|
+
extensions: []
|
|
30
|
+
extra_rdoc_files: []
|
|
31
|
+
files:
|
|
32
|
+
- ".rspec"
|
|
33
|
+
- ".rubocop.yml"
|
|
34
|
+
- ".tool-versions"
|
|
35
|
+
- AGENTS.md
|
|
36
|
+
- LICENSE.txt
|
|
37
|
+
- README.md
|
|
38
|
+
- Rakefile
|
|
39
|
+
- lib/generators/rails_credentials_cipher/install/install_generator.rb
|
|
40
|
+
- lib/rails_credentials_cipher.rb
|
|
41
|
+
- lib/rails_credentials_cipher/cipher.rb
|
|
42
|
+
- lib/rails_credentials_cipher/railtie.rb
|
|
43
|
+
- lib/rails_credentials_cipher/version.rb
|
|
44
|
+
- lib/tasks/credentials.rake
|
|
45
|
+
- sig/rails_credentials_cipher.rbs
|
|
46
|
+
homepage: https://github.com/thisismydesign/rails_credentials_cipher
|
|
47
|
+
licenses:
|
|
48
|
+
- MIT
|
|
49
|
+
metadata:
|
|
50
|
+
homepage_uri: https://github.com/thisismydesign/rails_credentials_cipher
|
|
51
|
+
source_code_uri: https://github.com/thisismydesign/rails_credentials_cipher
|
|
52
|
+
rubygems_mfa_required: 'true'
|
|
53
|
+
rdoc_options: []
|
|
54
|
+
require_paths:
|
|
55
|
+
- lib
|
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 3.3.0
|
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '0'
|
|
66
|
+
requirements: []
|
|
67
|
+
rubygems_version: 4.0.10
|
|
68
|
+
specification_version: 4
|
|
69
|
+
summary: Decrypt, edit, and encrypt Rails credentials.
|
|
70
|
+
test_files: []
|