dotenv-vault-rails 0.3.2 → 0.4.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
- data/Gemfile.lock +5 -3
- data/dotenv-vault.gemspec +1 -0
- data/lib/dotenv-vault/rails.rb +5 -26
- data/lib/dotenv-vault/version.rb +1 -1
- data/lib/dotenv-vault.rb +104 -6
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52add50daa3bd323beb1d314caebf3a7b289a61a7948053f40756407d5c47385
|
4
|
+
data.tar.gz: f11b2b4e205d23804130afe2d57b9c0f110ee84a003df2557c6e3560fb6d19f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5fe76da20b724172f3b714f614be72092372634b3e496d2838efa02742ec9843cdf05adc7063193c87688834ed62eae25e5c835a72b7663620b3b5a339b2f691
|
7
|
+
data.tar.gz: 25a8c6491705632524b232769223eada1d793a7ae4c432fbde1c3db4bd6fa6c8bed6f4943cd48ecd7aa22d84d15abcfd5f18050082797016322d5cec3a9c6c19
|
data/Gemfile.lock
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dotenv-vault (0.
|
4
|
+
dotenv-vault (0.4.0)
|
5
5
|
dotenv
|
6
|
-
|
6
|
+
lockbox
|
7
|
+
dotenv-vault-rails (0.4.0)
|
7
8
|
dotenv-rails
|
8
|
-
dotenv-vault (= 0.
|
9
|
+
dotenv-vault (= 0.4.0)
|
9
10
|
|
10
11
|
GEM
|
11
12
|
remote: https://rubygems.org/
|
@@ -40,6 +41,7 @@ GEM
|
|
40
41
|
erubi (1.11.0)
|
41
42
|
i18n (1.12.0)
|
42
43
|
concurrent-ruby (~> 1.0)
|
44
|
+
lockbox (1.0.0)
|
43
45
|
loofah (2.19.0)
|
44
46
|
crass (~> 1.0.2)
|
45
47
|
nokogiri (>= 1.5.9)
|
data/dotenv-vault.gemspec
CHANGED
data/lib/dotenv-vault/rails.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "dotenv-
|
1
|
+
require "dotenv-vault"
|
2
2
|
|
3
3
|
# Fix for rake tasks loading in development
|
4
4
|
#
|
@@ -16,7 +16,7 @@ if defined?(Rake.application)
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
Dotenv.instrumenter = ActiveSupport::Notifications
|
20
20
|
|
21
21
|
# Watch all loaded env files with Spring
|
22
22
|
begin
|
@@ -30,34 +30,13 @@ rescue LoadError, ArgumentError
|
|
30
30
|
end
|
31
31
|
|
32
32
|
module DotenvVault
|
33
|
-
class Railtie <
|
33
|
+
class Railtie < ::Dotenv::Railtie
|
34
34
|
def load
|
35
|
-
|
35
|
+
DotenvVault.load(*dotenv_files)
|
36
36
|
end
|
37
37
|
|
38
38
|
def overload
|
39
|
-
|
39
|
+
DotenvVault.overload(*dotenv_files)
|
40
40
|
end
|
41
|
-
|
42
|
-
def root
|
43
|
-
Rails.root || Pathname.new(ENV["RAILS_ROOT"] || Dir.pwd)
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.load
|
47
|
-
instance.load
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
def dotenv_files
|
53
|
-
[
|
54
|
-
root.join(".env.#{Rails.env}.local"),
|
55
|
-
(root.join(".env.local") unless Rails.env.test?),
|
56
|
-
root.join(".env.#{Rails.env}"),
|
57
|
-
root.join(".env")
|
58
|
-
].compact
|
59
|
-
end
|
60
|
-
|
61
|
-
config.before_configuration { load }
|
62
41
|
end
|
63
42
|
end
|
data/lib/dotenv-vault/version.rb
CHANGED
data/lib/dotenv-vault.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
require "dotenv"
|
2
|
+
require "lockbox"
|
2
3
|
require "dotenv-vault/version"
|
3
4
|
|
4
5
|
module DotenvVault
|
5
|
-
class
|
6
|
+
class NotFoundDotenvKey < ArgumentError; end
|
7
|
+
class NotFoundDotenvEnvironment < ArgumentError; end
|
8
|
+
class NotFoundDotenvVault < ArgumentError; end
|
9
|
+
class InvalidDotenvKey < ArgumentError; end
|
10
|
+
class DecryptionFailed < StandardError; end
|
11
|
+
|
12
|
+
include ::Dotenv
|
6
13
|
|
7
14
|
class << self
|
8
15
|
attr_accessor :instrumenter
|
@@ -11,27 +18,47 @@ module DotenvVault
|
|
11
18
|
module_function
|
12
19
|
|
13
20
|
def load(*filenames)
|
14
|
-
|
21
|
+
if using_vault?
|
22
|
+
load_vault(*filenames)
|
23
|
+
else
|
24
|
+
Dotenv.load(*filenames) # fallback
|
25
|
+
end
|
15
26
|
end
|
16
27
|
|
17
28
|
# same as `load`, but raises Errno::ENOENT if any files don't exist
|
18
29
|
def load!(*filenames)
|
19
|
-
|
30
|
+
if using_vault?
|
31
|
+
load_vault(*filenames)
|
32
|
+
else
|
33
|
+
Dotenv.load!(*filenames)
|
34
|
+
end
|
20
35
|
end
|
21
36
|
|
22
37
|
# same as `load`, but will override existing values in `ENV`
|
23
38
|
def overload(*filenames)
|
24
|
-
|
39
|
+
if using_vault?
|
40
|
+
overload_vault(*filenames)
|
41
|
+
else
|
42
|
+
Dotenv.overload(*filenames)
|
43
|
+
end
|
25
44
|
end
|
26
45
|
|
27
46
|
# same as `overload`, but raises Errno:ENOENT if any files don't exist
|
28
47
|
def overload!(*filenames)
|
29
|
-
|
48
|
+
if using_vault?
|
49
|
+
overload_vault(*filenames)
|
50
|
+
else
|
51
|
+
Dotenv.overload!(*filenames)
|
52
|
+
end
|
30
53
|
end
|
31
54
|
|
32
55
|
# returns a hash of parsed key/value pairs but does not modify ENV
|
33
56
|
def parse(*filenames)
|
34
|
-
|
57
|
+
if using_vault?
|
58
|
+
parse_vault(*filenames)
|
59
|
+
else
|
60
|
+
Dotenv.parse(*filenames)
|
61
|
+
end
|
35
62
|
end
|
36
63
|
|
37
64
|
# Internal: Helper to expand list of filenames.
|
@@ -52,4 +79,75 @@ module DotenvVault
|
|
52
79
|
def ignoring_nonexistent_files
|
53
80
|
Dotenv.ignoring_nonexistent_files
|
54
81
|
end
|
82
|
+
|
83
|
+
# Vault: Load from .env.vault
|
84
|
+
#
|
85
|
+
# Decrypts and loads to ENV
|
86
|
+
def load_vault(*filenames)
|
87
|
+
parsed = parse_vault(*filenames)
|
88
|
+
|
89
|
+
# Set ENV
|
90
|
+
parsed.each { |k, v| ENV[k] ||= v }
|
91
|
+
|
92
|
+
{ parsed: parsed }
|
93
|
+
end
|
94
|
+
|
95
|
+
# Vault: Overload from .env.vault
|
96
|
+
#
|
97
|
+
# Decrypts and overloads to ENV
|
98
|
+
def overload_vault(*filenames)
|
99
|
+
parsed = parse_vault(*filenames)
|
100
|
+
|
101
|
+
# Set ENV
|
102
|
+
parsed.each { |k, v| ENV[k] = v }
|
103
|
+
|
104
|
+
{ parsed: parsed }
|
105
|
+
end
|
106
|
+
|
107
|
+
def parse_vault(*filenames)
|
108
|
+
# Warn the developer unless both are set
|
109
|
+
raise NotFoundDotenvKey, "NOT_FOUND_DOTENV_KEY: Cannot find ENV['DOTENV_KEY']" unless present?(ENV["DOTENV_KEY"])
|
110
|
+
raise NotFoundDotenvEnvironment, "NOT_FOUND_DOTENV_ENVIRONMENT: Cannot find ENV['DOTENV_ENVIRONMENT']" unless present?(ENV["DOTENV_ENVIRONMENT"])
|
111
|
+
|
112
|
+
# Locate .env.vault
|
113
|
+
vault_path = ".env.vault"
|
114
|
+
raise NotFoundDotenvVault, "NotFoundDotenvVault: Cannot find .env.vault at ${vaultPath}" unless File.file?(vault_path)
|
115
|
+
|
116
|
+
# Parse .env.vault
|
117
|
+
parsed = Dotenv.parse(vault_path)
|
118
|
+
|
119
|
+
# Get ciphertext
|
120
|
+
environment_key = "DOTENV_VAULT_#{ENV["DOTENV_ENVIRONMENT"].upcase}"
|
121
|
+
ciphertext = parsed[environment_key] # DOTENV_VAULT_PRODUCTION
|
122
|
+
raise NotFoundDotenvEnvironment, "NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate #{environment_key} in .env.vault" unless ciphertext
|
123
|
+
|
124
|
+
# Decrypt ciphertext
|
125
|
+
decrypted = decrypt(ciphertext)
|
126
|
+
|
127
|
+
# Parse decrypted .env string
|
128
|
+
Dotenv::Parser.call(decrypted, true)
|
129
|
+
end
|
130
|
+
|
131
|
+
def using_vault?
|
132
|
+
present?(ENV["DOTENV_ENVIRONMENT"]) && present?(ENV["DOTENV_KEY"])
|
133
|
+
end
|
134
|
+
|
135
|
+
def present?(str)
|
136
|
+
!(str.nil? || str.empty?)
|
137
|
+
end
|
138
|
+
|
139
|
+
def decrypt(ciphertext)
|
140
|
+
raise NotFoundDotenvKey, "NOT_FOUND_DOTENV_KEY: Cannot find ENV['DOTENV_KEY']" unless present?(ENV["DOTENV_KEY"])
|
141
|
+
|
142
|
+
key = ENV["DOTENV_KEY"][-64..-1] # last 64 characters. allows for passing keys with preface like key_*****
|
143
|
+
|
144
|
+
raise InvalidDotenvKey, "INVALID_DOTENV_KEY: It must be 64 characters long (or more)" unless key.to_s.length == 64
|
145
|
+
|
146
|
+
lockbox = Lockbox.new(key: key, encode: true)
|
147
|
+
begin
|
148
|
+
lockbox.decrypt(ciphertext)
|
149
|
+
rescue Lockbox::Error
|
150
|
+
raise DecryptionFailed, "DECRYPTION_FAILED: Please check your DOTENV_KEY"
|
151
|
+
end
|
152
|
+
end
|
55
153
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dotenv-vault-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- motdotla
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dotenv-rails
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.4.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.4.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: spring
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|