secret-keeper 0.2.5 → 2.0.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: 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