dotenv-vault-rails 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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