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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c2498829468fc91f5d62a80bffdbe4cacb60b452da0fa52bea294942cebe4ca
4
- data.tar.gz: b65a4b20a5c1b33239da2694b633d6c765434056f8601a8215c487e9279549f6
3
+ metadata.gz: 52add50daa3bd323beb1d314caebf3a7b289a61a7948053f40756407d5c47385
4
+ data.tar.gz: f11b2b4e205d23804130afe2d57b9c0f110ee84a003df2557c6e3560fb6d19f3
5
5
  SHA512:
6
- metadata.gz: 6201aec01c18d719e2d21455f0bd54f813958dd2658500e036fd51b97fe5eb775e57d71ff94c44713d5af9c3d2b403c8bae6ac75935b790aa54d7eb2082a069e
7
- data.tar.gz: a80a6fd4955cf1b3dc5827702c0b852dab047d502e3a3d7c8817547c19ca95a26050452b41f6199e10a7d88e79039f2ac580cb4e1a816c41f2732e20b000806d
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.3.2)
4
+ dotenv-vault (0.4.0)
5
5
  dotenv
6
- dotenv-vault-rails (0.3.2)
6
+ lockbox
7
+ dotenv-vault-rails (0.4.0)
7
8
  dotenv-rails
8
- dotenv-vault (= 0.3.2)
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
@@ -26,6 +26,7 @@ Gem::Specification.new "dotenv-vault" do |spec|
26
26
  spec.require_paths = ["lib"]
27
27
 
28
28
  spec.add_dependency "dotenv"
29
+ spec.add_dependency "lockbox"
29
30
 
30
31
  spec.add_development_dependency "rake"
31
32
  spec.add_development_dependency "rspec"
@@ -1,4 +1,4 @@
1
- require "dotenv-rails"
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
- DotenvVault.instrumenter = ActiveSupport::Notifications
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 < Rails::Railtie
33
+ class Railtie < ::Dotenv::Railtie
34
34
  def load
35
- Dotenv.load(*dotenv_files)
35
+ DotenvVault.load(*dotenv_files)
36
36
  end
37
37
 
38
38
  def overload
39
- Dotenv.overload(*dotenv_files)
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
@@ -1,3 +1,3 @@
1
1
  module DotenvVault
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.0"
3
3
  end
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 Error < StandardError; end
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
- Dotenv.load(*filenames)
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
- Dotenv.load!(*filenames)
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
- Dotenv.overload(*filenames)
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
- Dotenv.overload!(*filenames)
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
- Dotenv.parse(*filenames)
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.3.2
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-15 00:00:00.000000000 Z
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.3.2
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.3.2
40
+ version: 0.4.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: spring
43
43
  requirement: !ruby/object:Gem::Requirement