diffcrypt 0.3.3 → 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: 9e77d7111ad066e219da5f2c20dd2930bdda46641aa477bd3ab03e6194e19695
4
- data.tar.gz: 6af61a30f44c3c18ff92e7dac0564fbbb8ea6384740835d15f84c88eb200c9e5
3
+ metadata.gz: e40a357c62cf93d9c49f336c7ad456d4f7510bd8389f3fb20c4913b91f4ef5f2
4
+ data.tar.gz: 4fb0296c2eaf901c59bdec117f974203500596f6347a9b8c12632b7dbe39ab77
5
5
  SHA512:
6
- metadata.gz: 2c28fd4f218a5dafc07074b38f0b7b772b1cbd0eec06fee19a51e3b1f65ef048c8df0fa43ada8a785c166f03e0db21cf0534ff6586c010f916e2f7814a1dec5f
7
- data.tar.gz: a8e8130402e6a7aff0eb169a3498a33bc64fe383cd1a85742f4efb18ed2861fbaa335ae30109c9ba30fc298df55fd937f118370a8d58ce41d4c46fcb9ad75b75
6
+ metadata.gz: d368c674a915b706b876a5a022c7003e3f7ecf30b38b581f2e7debf261d47102d759c27d317b85a71904bace22fd1a0306d9175b2c9496592375d786d3fe4fc1
7
+ data.tar.gz: 9e24c98075aab9c2f8e0550e757adea3df5b7f1e341f7d93d5644ee21e6a9ee9a352f7450a1a63afd609d876406c6efbe4aaff56e6c978c413259588625eedf5
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
 
9
9
 
10
+ ## [0.4.0] - 2020-10-01
11
+
12
+ ### Changed
13
+
14
+ - Encryptor can now use other ciphers than the default
15
+
16
+ ### Dependencies
17
+
18
+ - simplecov: 0.17.0 -> 0.18.0 (#20)
19
+ - rubocop: 0.88.0 -> 0.92.0 (#24)
20
+
21
+
22
+
10
23
  ## [0.3.3] - 2020-07-25
11
24
 
12
25
  ### Fixed
data/Gemfile CHANGED
@@ -7,6 +7,6 @@ gemspec
7
7
 
8
8
  gem 'minitest', '~> 5.0'
9
9
  gem 'rake', '~> 13.0'
10
- gem 'rubocop', '~> 0.88.0'
11
- gem 'simplecov', '~> 0.17.0', require: false # CodeClimate not compatible with 0.18+ yet - https://github.com/codeclimate/test-reporter/issues/413
10
+ gem 'rubocop', '~> 0.92.0'
11
+ gem 'simplecov', '~> 0.19.0', require: false # CodeClimate not compatible with 0.18+ yet - https://github.com/codeclimate/test-reporter/issues/413
12
12
  gem 'simplecov-lcov', '< 0.8'
data/README.md CHANGED
@@ -36,8 +36,8 @@ There are a few ways to use the library, depending on how advanced your use case
36
36
  The easiest way to get started is to use the CLI.
37
37
 
38
38
  ```shell
39
- diffcrypt decrypt -k $(cat test/fixtures/master.key) test/fixtures/example.yml.enc
40
- diffcrypt encrypt -k $(cat test/fixtures/master.key) test/fixtures/example.yml
39
+ diffcrypt decrypt -k $(cat test/fixtures/aes-128-gcm.key) test/fixtures/example.yml.enc
40
+ diffcrypt encrypt -k $(cat test/fixtures/aes-128-gcm.key) test/fixtures/example.yml
41
41
  ```
42
42
 
43
43
 
@@ -69,7 +69,7 @@ the built in encrypter. All existing `rails credentials:edit` also work with thi
69
69
  require 'diffcrypt/rails/encrypted_configuration'
70
70
  module Rails
71
71
  class Application
72
- def encrypted(path, key_path: 'config/master.key', env_key: 'RAILS_MASTER_KEY')
72
+ def encrypted(path, key_path: 'config/aes-128-gcm.key', env_key: 'RAILS_MASTER_KEY')
73
73
  Diffcrypt::Rails::EncryptedConfiguration.new(
74
74
  config_path: Rails.root.join(path),
75
75
  key_path: Rails.root.join(key_path),
@@ -83,6 +83,17 @@ end
83
83
 
84
84
 
85
85
 
86
+ ## Converting between ciphers
87
+
88
+ Sometimes you may want to rotate the cipher used on a file. You cab do this rogramtically using the ruby code above, or you can also chain the CLI commands like so:
89
+
90
+ ```shell
91
+ diffcrypt decrypt -k $(cat test/fixtures/aes-128-gcm.key) test/fixtures/example.yml.enc > test/fixtures/example.128.yml \
92
+ && diffcrypt encrypt --cipher aes-256-gcm -k $(cat test/fixtures/aes-256-gcm.key) test/fixtures/example.128.yml > test/fixtures/example.256.yml.enc && rm test/fixtures/example.128.yml
93
+ ```
94
+
95
+
96
+
86
97
  ## Development
87
98
 
88
99
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  # Specify which files should be added to the gem when it is released.
24
24
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
+ spec.files = Dir.chdir(::File.expand_path(__dir__)) do
26
26
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
27
  end
28
28
  spec.bindir = 'bin'
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative './encryptor'
4
+ require_relative './file'
4
5
  require_relative './version'
5
6
 
6
7
  module Diffcrypt
@@ -8,21 +9,22 @@ module Diffcrypt
8
9
  desc 'decrypt <path>', 'Decrypt a file'
9
10
  method_option :key, aliases: %i[k], required: true
10
11
  def decrypt(path)
11
- ensure_file_exists(path)
12
- contents = File.read(path)
13
- puts encryptor.decrypt(contents)
12
+ file = File.new(path)
13
+ ensure_file_exists(file)
14
+ say file.decrypt(key)
14
15
  end
15
16
 
16
17
  desc 'encrypt <path>', 'Encrypt a file'
17
18
  method_option :key, aliases: %i[k], required: true
19
+ method_option :cipher, default: Encryptor::DEFAULT_CIPHER
18
20
  def encrypt(path)
19
- ensure_file_exists(path)
20
- contents = File.read(path)
21
- puts encryptor.encrypt(contents)
21
+ file = File.new(path)
22
+ ensure_file_exists(file)
23
+ say file.encrypt(key, cipher: options[:cipher])
22
24
  end
23
25
 
24
26
  desc 'generate-key', 'Generate a 32 bit key'
25
- method_option :cipher, default: Encryptor::CIPHER
27
+ method_option :cipher, default: Encryptor::DEFAULT_CIPHER
26
28
  def generate_key
27
29
  say Encryptor.generate_key(options[:cipher])
28
30
  end
@@ -41,8 +43,9 @@ module Diffcrypt
41
43
  @encryptor ||= Encryptor.new(key)
42
44
  end
43
45
 
44
- def ensure_file_exists(path)
45
- abort('[ERROR] File does not exist') unless File.exist?(path)
46
+ # @param [Diffcrypt::File] path
47
+ def ensure_file_exists(file)
48
+ abort('[ERROR] File does not exist') unless file.exists?
46
49
  end
47
50
 
48
51
  def self.exit_on_failure?
@@ -12,15 +12,16 @@ require_relative './version'
12
12
 
13
13
  module Diffcrypt
14
14
  class Encryptor
15
- CIPHER = 'aes-128-gcm'
15
+ DEFAULT_CIPHER = 'aes-128-gcm'
16
16
 
17
- def self.generate_key(cipher = CIPHER)
17
+ def self.generate_key(cipher = DEFAULT_CIPHER)
18
18
  SecureRandom.hex(ActiveSupport::MessageEncryptor.key_len(cipher))
19
19
  end
20
20
 
21
- def initialize(key)
21
+ def initialize(key, cipher: DEFAULT_CIPHER)
22
22
  @key = key
23
- @encryptor ||= ActiveSupport::MessageEncryptor.new([key].pack('H*'), cipher: CIPHER)
23
+ @cipher = cipher
24
+ @encryptor ||= ActiveSupport::MessageEncryptor.new([key].pack('H*'), cipher: cipher)
24
25
  end
25
26
 
26
27
  # @param [String] contents The raw YAML string to be encrypted
@@ -50,7 +51,7 @@ module Diffcrypt
50
51
  data = encrypt_data contents, original_encrypted_contents
51
52
  YAML.dump(
52
53
  'client' => "diffcrypt-#{Diffcrypt::VERSION}",
53
- 'cipher' => CIPHER,
54
+ 'cipher' => @cipher,
54
55
  'data' => data,
55
56
  )
56
57
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './encryptor'
4
+
5
+ module Diffcrypt
6
+ class File
7
+ attr_reader :file
8
+
9
+ def initialize(path)
10
+ @path = ::File.absolute_path path
11
+ end
12
+
13
+ def encrypted?
14
+ to_yaml['cipher']
15
+ end
16
+
17
+ def cipher
18
+ to_yaml['cipher'] || Encryptor::DEFAULT_CIPHER
19
+ end
20
+
21
+ # @return [Boolean]
22
+ def exists?
23
+ ::File.exist?(@path)
24
+ end
25
+
26
+ # @return [String] Raw contents of the file
27
+ def read
28
+ @read ||= ::File.read(@path)
29
+ end
30
+
31
+ def encrypt(key, cipher: DEFAULT_CIPHER)
32
+ return read if encrypted?
33
+
34
+ Encryptor.new(key, cipher: cipher).encrypt(read)
35
+ end
36
+
37
+ # TODO: Add a test to verify this does descrypt properly
38
+ def decrypt(key)
39
+ return read unless encrypted?
40
+
41
+ Encryptor.new(key, cipher: cipher).decrypt(read)
42
+ end
43
+
44
+ def to_yaml
45
+ @to_yaml ||= YAML.safe_load(read)
46
+ end
47
+ end
48
+ end
@@ -9,6 +9,8 @@ require 'active_support/core_ext/hash'
9
9
  require 'active_support/core_ext/module/delegation'
10
10
  require 'active_support/core_ext/object/inclusion'
11
11
 
12
+ require 'diffcrypt/file'
13
+
12
14
  module Diffcrypt
13
15
  module Rails
14
16
  class EncryptedConfiguration
@@ -21,13 +23,13 @@ module Diffcrypt
21
23
  delegate_missing_to :options
22
24
 
23
25
  def initialize(config_path:, key_path:, env_key:, raise_if_missing_key:)
24
- @content_path = Pathname.new(File.absolute_path(config_path)).yield_self do |path|
26
+ @content_path = Pathname.new(::File.absolute_path(config_path)).yield_self do |path|
25
27
  path.symlink? ? path.realpath : path
26
28
  end
29
+ @diffcrypt_file = Diffcrypt::File.new(@content_path)
27
30
  @key_path = Pathname.new(key_path)
28
31
  @env_key = env_key
29
32
  @raise_if_missing_key = raise_if_missing_key
30
- @active_support_encryptor = ActiveSupport::MessageEncryptor.new([key].pack('H*'), cipher: Encryptor::CIPHER)
31
33
  end
32
34
 
33
35
  # Determines if file is using the diffable format, or still
@@ -73,7 +75,7 @@ module Diffcrypt
73
75
  # rubocop:disable Metrics/AbcSize
74
76
  def writing(contents)
75
77
  tmp_file = "#{Process.pid}.#{content_path.basename.to_s.chomp('.enc')}"
76
- tmp_path = Pathname.new File.join(Dir.tmpdir, tmp_file)
78
+ tmp_path = Pathname.new ::File.join(Dir.tmpdir, tmp_file)
77
79
  tmp_path.binwrite contents
78
80
 
79
81
  yield tmp_path
@@ -103,9 +105,18 @@ module Diffcrypt
103
105
  end
104
106
  end
105
107
 
108
+ # Rails applications with an existing credentials file, the inbuilt active support encryptor should be used
109
+ # @return [ActiveSupport::MessageEncryptor]
110
+ def active_support_encryptor
111
+ @active_support_encryptor = ActiveSupport::MessageEncryptor.new(
112
+ [key].pack('H*'),
113
+ cipher: @diffcrypt_file.cipher,
114
+ )
115
+ end
116
+
106
117
  # @return [Encryptor]
107
118
  def encryptor
108
- @encryptor ||= Encryptor.new key
119
+ @encryptor ||= Encryptor.new key, cipher: @diffcrypt_file.cipher
109
120
  end
110
121
 
111
122
  def read_env_key
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Diffcrypt
4
- VERSION = '0.3.3'
4
+ VERSION = '0.4.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diffcrypt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Qualie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-25 00:00:00.000000000 Z
11
+ date: 2020-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -70,8 +70,10 @@ files:
70
70
  - lib/diffcrypt.rb
71
71
  - lib/diffcrypt/cli.rb
72
72
  - lib/diffcrypt/encryptor.rb
73
+ - lib/diffcrypt/file.rb
73
74
  - lib/diffcrypt/rails/encrypted_configuration.rb
74
75
  - lib/diffcrypt/version.rb
76
+ - tmp/.keep
75
77
  homepage: https://github.com/marcqualie/diffcrypt
76
78
  licenses:
77
79
  - MIT
@@ -93,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
95
  - !ruby/object:Gem::Version
94
96
  version: '0'
95
97
  requirements: []
96
- rubygems_version: 3.1.4
98
+ rubygems_version: 3.0.3
97
99
  signing_key:
98
100
  specification_version: 4
99
101
  summary: Diffable encrypted configuration files