dotenv-vault 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: a75c615d4948134bc23799924f8f1b5784024f84215fc561d92b6acb81fde35d
4
- data.tar.gz: bad69794d2daf690dfb4d5362af5ef1cdf9e617b9e6685fcbc74e196db474c63
3
+ metadata.gz: 43532f3eb3ddc9a9b407131c2961446cf58664e34e5bcc763efc516d9b0143cb
4
+ data.tar.gz: b0a76f6e83ddd50fd3525976fffe0c09c759a91286120266ca7396e3b636095c
5
5
  SHA512:
6
- metadata.gz: 5b50a15ed04b0feb1109df7f816b1158b95317d79e3b82f8a284c53909d8e36257f7721f66449230208de25cd614225678c513817c70b915f83019d7a564ce5f
7
- data.tar.gz: eb6e961c7dee465f749316cb57afb4615bdc7c35427fb00cfe85b7b2059a4c8e4ac3bf3770c199e8c635a3aa28584c4cf733cc140a35cdc0b7b8325cc0bed08c
6
+ metadata.gz: e01b952fbf0d9de42f8cb35a7ab622ba95bfb85bb53685712340500524c472895d01c42d3c22ff16796526b29b7c6584777b2170629b0f093fd3188ee907da25
7
+ data.tar.gz: cdabb9c5af4aa7ecfdc3797fa91cc15452497b85184c25709fa3e853adcadc826c2a1aaf01526a8ff0c86a93d3576179e7f5fc7c37d4913647f7aef0e95c4fcb
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
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
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: lockbox
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement