secret-keeper 0.2.5 → 2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8693d3499b65d7db741098ae2daeb82d5def5cc6b26d105ddb7308ac7e56bd76
4
- data.tar.gz: dc784b7d2155a5b2bfbe31210b29f9016109b9308ad27ec26161fb8f90558533
3
+ metadata.gz: 993613940fe2fd54b0db8ea676aeaeb82a1de574b6d986a904f14e166d9826a2
4
+ data.tar.gz: 92c2b76672090397d60871cf438fc597877351ae74c09cd4f43d927d2c3de0b1
5
5
  SHA512:
6
- metadata.gz: b49b2c0d43777d0b31dcb4fcc4ae39e656836e83edd119698c2a4e5e90b91a2a91e30dfc5ae8a9cb41f130f9109f95f3965a62ada02bcdfce3a831585e964a84
7
- data.tar.gz: cc0cc6b3c9ed69e424a7013677e9d44e1f31cb85c7e3d318b19524bbf8384f2240b68753be548a5e0415a1398251c3213ab69479ad50dc95f48835670843b4f0
6
+ metadata.gz: a3c9d114ab4bcd7b0958ff3fa999e2b2ffb3c4bda4eeab15e54841daa9596d24ec6c7323893d07995e8fe6f4c7fb47ccc082e88b5c89513fe12010a350ba1b84
7
+ data.tar.gz: 9a6e63acc12ef13e56237e8dde65e28b45a47423a700b71c6d79486fabcf89dbd3f13426f26e23ab08f54a9ca09fb186b00bcdefab19f6a3c1bc1e27c8682719
data/README.md CHANGED
@@ -12,6 +12,16 @@ with bundler, write follwing line in your Gemfile
12
12
 
13
13
  gem 'secret-keeper', require: false
14
14
 
15
+ ## Upgrade from v1 to v2
16
+
17
+ The *remove_production* parameter of *decrypt_files* has been removed after version 2.0.0.
18
+ If you wants to remove *production* settings after decrypt files, you can set *remove_production* option to *true* in *secret-keeper.yml*:
19
+
20
+ ```
21
+ options:
22
+ remove_production: false
23
+ ```
24
+
15
25
  ## Usage
16
26
  setup files need to be encrypted in config/secret-keeper.yml
17
27
 
@@ -19,6 +29,10 @@ setup files need to be encrypted in config/secret-keeper.yml
19
29
  development:
20
30
  ev_name: SECRET_KEEPER
21
31
  cipher: AES-256-CBC
32
+ options:
33
+ slience: false
34
+ remove_production: false
35
+ remove_source: false
22
36
  tasks:
23
37
  -
24
38
  encrypt_from: example/database.yml
@@ -55,16 +69,18 @@ decrypt files based on your tasks defined in config/secret-keeper.yml
55
69
  # * example/secrets.yml.enc --> example/secrets.yml, ok
56
70
  # Done!
57
71
 
58
- decrypt files and remove production configs
59
-
60
- irb> SecretKeeper.decrypt_files
61
- # Decrypting...
62
- # remove production configs after decrypted
63
- # * example/database.yml.enc --> example/database.yml, ok
64
- # * example/secrets.yml.enc --> example/secrets.yml, ok
65
- # Done!
66
-
67
72
  ## Available Ciphers
68
73
 
69
74
  irb> require 'openssl'
70
75
  irb> OpenSSL::Cipher.ciphers
76
+
77
+ ## Options
78
+
79
+ * slience
80
+ When this option set to *true*, the tasks will run in slience mode. Messages will not show no screen. Default is *false*.
81
+
82
+ * remove_production
83
+ When this option set to *true*, the *production* settings in the decrypted files will be removed after the decryption task. Default is *false*.
84
+
85
+ * remove_source
86
+ When this option set to *true*, the source file will be removed after either encrypt or decrypt tasks. Default is *false*.
data/lib/secret-keeper.rb CHANGED
@@ -2,43 +2,55 @@ require 'openssl'
2
2
  require 'yaml'
3
3
 
4
4
  class SecretKeeper
5
+ attr_reader :tasks, :options
6
+
5
7
  def self.encrypt_files
8
+ printer = ['Encrypting...']
6
9
  sk = SecretKeeper.new
7
- puts 'Encrypting...'
10
+ printer << '(production config removed)' if sk.options['remove_production']
11
+ printer << '(source files removed)' if sk.options['remove_source']
8
12
  ok_queue = []
9
13
  sk.tasks.each do |task|
10
- from = task['encrypt_from']
14
+ from = File.exists?(task['encrypt_from']) ? task['encrypt_from'] : task['decrypt_to']
11
15
  to = task['encrypt_to']
12
16
 
13
17
  result = sk.encrypt_file(from, to)
18
+ if result == :ok
19
+ result = sk.remove_file(from) if sk.options['remove_source']
20
+ end
21
+
14
22
  ok_queue << result if result == :ok
15
- puts " * #{from} --> #{to}, #{result}"
23
+ printer << " * #{from} --> #{to}, #{result}"
16
24
  end
17
25
  success = ok_queue.count == sk.tasks.count
18
- puts success ? 'Done!' : 'Failed!'
26
+ printer << (success ? 'Done!' : 'Failed!')
27
+ printer.each{ |row| puts row } unless sk.options['slience']
19
28
  success
20
29
  end
21
30
 
22
- def self.decrypt_files(remove_production=false)
31
+ def self.decrypt_files
32
+ printer = ['Decrypting...']
23
33
  sk = SecretKeeper.new
24
- puts 'Decrypting...'
25
- puts 'remove production configs after decrypted' if remove_production
34
+ printer << '(production config removed)' if sk.options['remove_production']
35
+ printer << '(source files removed)' if sk.options['remove_source']
36
+
26
37
  ok_queue = []
27
38
  sk.tasks.each do |task|
28
39
  from = task['decrypt_from'] || task['encrypt_to']
29
40
  to = task['decrypt_to'] || task['encrypt_from']
30
41
 
31
42
  result = sk.decrypt_file(from, to)
32
-
33
- if result == :ok && remove_production
34
- result = sk.remove_production_config(to)
43
+ if result == :ok
44
+ result = sk.remove_production_config(to) if sk.options['remove_production']
45
+ result = sk.remove_file(from) if sk.options['remove_source']
35
46
  end
36
47
 
37
48
  ok_queue << result if result == :ok
38
- puts " * #{from} --> #{to}, #{result}"
49
+ printer << " * #{from} --> #{to}, #{result}"
39
50
  end
40
51
  success = ok_queue.count == sk.tasks.count
41
- puts success ? 'Done!' : 'Failed!'
52
+ printer << (success ? 'Done!' : 'Failed!')
53
+ printer.each{ |row| puts row } unless sk.options['slience']
42
54
  success
43
55
  end
44
56
 
@@ -51,13 +63,11 @@ class SecretKeeper
51
63
  ev_name = config['ev_name'] || 'SECRET_KEEPER'
52
64
  fail "environment variable #{ev_name} not exist" if ENV[ev_name].nil?
53
65
 
54
- @cipher_digest = ENV[ev_name]
55
66
  @tasks = config['tasks']
56
- @using_cipher = OpenSSL::Cipher.new(config['cipher'])
57
- end
67
+ @using_cipher = OpenSSL::Cipher.new(config['cipher'] || 'AES-256-CBC')
68
+ @cipher_key = Digest::SHA2.hexdigest(ENV[ev_name])[0...@using_cipher.key_len]
58
69
 
59
- def tasks
60
- @tasks
70
+ @options = config['options']
61
71
  end
62
72
 
63
73
  def encrypt_file(from_file, to_file)
@@ -70,7 +80,7 @@ class SecretKeeper
70
80
 
71
81
  def decrypt_file(from_file, to_file)
72
82
  decrypted = File.open(from_file, 'rb') { |f| decrypt(f.read) }
73
- File.open(to_file, 'w') { |f| f.write(decrypted) }
83
+ File.open(to_file, 'w') { |f| f.write(decrypted.force_encoding('UTF-8')) }
74
84
  :ok
75
85
  rescue => e
76
86
  e
@@ -86,19 +96,24 @@ class SecretKeeper
86
96
  e
87
97
  end
88
98
 
99
+ def remove_file(file_path)
100
+ File.delete(file_path)
101
+ :ok
102
+ rescue => e
103
+ e
104
+ end
105
+
89
106
  private
90
107
 
91
108
  def encrypt(data)
92
109
  cipher = @using_cipher.encrypt
93
- key_size_range = 0..(cipher.key_len-1)
94
- cipher.key = Digest::SHA2.hexdigest(@cipher_digest)[key_size_range]
110
+ cipher.key = @cipher_key
95
111
  cipher.update(data) + cipher.final
96
112
  end
97
113
 
98
114
  def decrypt(data)
99
115
  cipher = @using_cipher.decrypt
100
- key_size_range = 0..(cipher.key_len-1)
101
- cipher.key = Digest::SHA2.hexdigest(@cipher_digest)[key_size_range]
116
+ cipher.key = @cipher_key
102
117
  cipher.update(data) + cipher.final
103
118
  end
104
119
  end
@@ -1,6 +1,12 @@
1
1
  describe SecretKeeper do
2
2
  before(:each) do
3
3
  ENV['SECRET_KEEPER'] = 'PASSWORD_HERE'
4
+ FileUtils.copy_entry('./example', './example_backup')
5
+ end
6
+
7
+ after(:each) do
8
+ FileUtils.rm_r('./example')
9
+ FileUtils.mv('./example_backup', './example')
4
10
  end
5
11
 
6
12
  describe '.encrypt_files' do
@@ -8,6 +14,24 @@ describe SecretKeeper do
8
14
  result = SecretKeeper.encrypt_files
9
15
  expect(result).to eq(true)
10
16
  end
17
+
18
+ it 'should return true on remove_source true' do
19
+ options = {
20
+ 'slience' => true,
21
+ 'remove_production' => false,
22
+ 'remove_source' => true
23
+ }
24
+ allow_any_instance_of(SecretKeeper).to receive(:options).and_return(options)
25
+
26
+ result = SecretKeeper.encrypt_files
27
+ expect(result).to eq(true)
28
+ SecretKeeper.new.tasks.each do |task|
29
+ source_file = task['encrypt_from']
30
+ target_file = task['encrypt_to']
31
+ expect(File.exists?(source_file)).to eq(false)
32
+ expect(File.exists?(target_file)).to eq(true)
33
+ end
34
+ end
11
35
  end
12
36
 
13
37
  describe '.decrypt_files' do
@@ -19,12 +43,58 @@ describe SecretKeeper do
19
43
  expect(hash['production']['secret_key_base']).to eq('339f639f4fe35c5ffaa47ace973260b12e51b0b4fe1f65effd283a5f054f47594b24bd565779e351a20dfd4ada4f777958f0417b305c06cdedbde392b8e1fd07')
20
44
  end
21
45
 
22
- it 'should return true on remove_production true' do
23
- result = SecretKeeper.decrypt_files(ENV['RAILS_ENV'] != 'production')
46
+ it 'should return true on remove_production true and remove_source false' do
47
+ options = {
48
+ 'slience' => true,
49
+ 'remove_production' => true,
50
+ 'remove_source' => false
51
+ }
52
+ allow_any_instance_of(SecretKeeper).to receive(:options).and_return(options)
53
+
54
+ result = SecretKeeper.decrypt_files
55
+ expect(result).to eq(true)
56
+ hash = YAML.load_file('example/secrets.yml')
57
+ expect(hash['development']['secret_key_base']).to eq('e8310af93d52f174f475940c41fbfb90417b300ebc19e1b24bd5639f4fe35c5ffaa5775a347ace9732958f656a47f6bb8e1fd0760b12e51b0b4fe1f65ef0a1d6')
58
+ expect(hash['production']).to be_nil
59
+ end
60
+
61
+ it 'should return true on remove_production false and remove_source true' do
62
+ options = {
63
+ 'slience' => true,
64
+ 'remove_production' => false,
65
+ 'remove_source' => true
66
+ }
67
+ allow_any_instance_of(SecretKeeper).to receive(:options).and_return(options)
68
+
69
+ result = SecretKeeper.decrypt_files
70
+ expect(result).to eq(true)
71
+ SecretKeeper.new.tasks.each do |task|
72
+ source_file = task['decrypt_from'] || task['encrypt_to']
73
+ target_file = task['decrypt_to'] || task['encrypt_from']
74
+ expect(File.exists?(source_file)).to eq(false)
75
+ expect(File.exists?(target_file)).to eq(true)
76
+ end
77
+ end
78
+
79
+ it 'should return true on remove_production true and remove_source true' do
80
+ options = {
81
+ 'slience' => true,
82
+ 'remove_production' => true,
83
+ 'remove_source' => true
84
+ }
85
+ allow_any_instance_of(SecretKeeper).to receive(:options).and_return(options)
86
+
87
+ result = SecretKeeper.decrypt_files
24
88
  expect(result).to eq(true)
25
89
  hash = YAML.load_file('example/secrets.yml')
26
90
  expect(hash['development']['secret_key_base']).to eq('e8310af93d52f174f475940c41fbfb90417b300ebc19e1b24bd5639f4fe35c5ffaa5775a347ace9732958f656a47f6bb8e1fd0760b12e51b0b4fe1f65ef0a1d6')
27
91
  expect(hash['production']).to be_nil
92
+ SecretKeeper.new.tasks.each do |task|
93
+ source_file = task['decrypt_from'] || task['encrypt_to']
94
+ target_file = task['decrypt_to'] || task['encrypt_from']
95
+ expect(File.exists?(source_file)).to eq(false)
96
+ expect(File.exists?(target_file)).to eq(true)
97
+ end
28
98
  end
29
99
 
30
100
  it 'should be false, if SECRET_KEEPER incorrect' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secret-keeper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ray Lee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-17 00:00:00.000000000 Z
11
+ date: 2022-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '3.9'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: '3.9'
27
27
  description: A Secret keeper
28
28
  email: ray-lee@kdanmobile.com
29
29
  executables: []
@@ -34,7 +34,7 @@ files:
34
34
  - README.md
35
35
  - lib/secret-keeper.rb
36
36
  - spec/secret-keeper_spec.rb
37
- homepage: https://github.com/redtear1115/secret-keeper
37
+ homepage: https://github.com/kdan-mobile-software-ltd/secret-keeper
38
38
  licenses:
39
39
  - MIT
40
40
  metadata: {}
@@ -47,14 +47,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
47
47
  requirements:
48
48
  - - ">="
49
49
  - !ruby/object:Gem::Version
50
- version: 2.3.1
50
+ version: 2.7.0
51
51
  required_rubygems_version: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
56
  requirements: []
57
- rubygems_version: 3.0.1
57
+ rubygems_version: 3.2.32
58
58
  signing_key:
59
59
  specification_version: 4
60
60
  summary: Keep all your secret files within openssl