diffcrypt 0.1.1 → 0.3.3

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: b9a07ad0aa1385421550a40093fe6e724337f7697e71f7af081a7011daa05a8c
4
- data.tar.gz: 40406c43e1a8ef7396577e70d62e3bee026db6500563e56aadf113b95203069d
3
+ metadata.gz: 9e77d7111ad066e219da5f2c20dd2930bdda46641aa477bd3ab03e6194e19695
4
+ data.tar.gz: 6af61a30f44c3c18ff92e7dac0564fbbb8ea6384740835d15f84c88eb200c9e5
5
5
  SHA512:
6
- metadata.gz: b3f03e909e4b49740dfd7e6e8e4bdab3a39decca30556149e4645f2071156b9632e3a54827f33fc6fcac7a419443eb066bf8fca249eca98219a9be5989ef3840
7
- data.tar.gz: 001bf874603205e1421a0a99ac8d2c14e15b187495505adb1141f84108b0270d159f58c703c730fea6d69a974b1c8e32b2268437a93b590a9adf8d851f854a37
6
+ metadata.gz: 2c28fd4f218a5dafc07074b38f0b7b772b1cbd0eec06fee19a51e3b1f65ef048c8df0fa43ada8a785c166f03e0db21cf0534ff6586c010f916e2f7814a1dec5f
7
+ data.tar.gz: a8e8130402e6a7aff0eb169a3498a33bc64fe383cd1a85742f4efb18ed2861fbaa335ae30109c9ba30fc298df55fd937f118370a8d58ce41d4c46fcb9ad75b75
@@ -0,0 +1,26 @@
1
+ version: 2.1
2
+
3
+ jobs:
4
+ build:
5
+ docker:
6
+ - image: circleci/ruby:2.6.6
7
+ working_directory: /mnt/ramdisk
8
+ steps:
9
+ - checkout
10
+ - run: bundle install
11
+ - run:
12
+ name: Setup Code Climate test-reporter
13
+ command: |
14
+ # download test reporter as a static binary
15
+ curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
16
+ chmod +x ./cc-test-reporter
17
+ - run:
18
+ name: rake test
19
+ command: |
20
+ ./cc-test-reporter before-build
21
+ bundle exec rake test
22
+ ./cc-test-reporter after-build --coverage-input-type lcov --exit-code $?
23
+ - run:
24
+ name: rubocop
25
+ command: bundle exec rubocop
26
+ when: always
@@ -0,0 +1,7 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ rebase-strategy: auto
6
+ schedule:
7
+ interval: daily
@@ -9,6 +9,12 @@ Style/Documentation:
9
9
  Metrics/MethodLength:
10
10
  Exclude:
11
11
  - test/**/*_test.rb
12
+ TrailingCommaInArrayLiteral:
13
+ EnforcedStyleForMultiline: consistent_comma
14
+ Style/TrailingCommaInArguments:
15
+ EnforcedStyleForMultiline: consistent_comma
16
+ Style/AccessorGrouping:
17
+ EnforcedStyle: separated
12
18
 
13
19
  Layout/LineLength:
14
20
  Exclude:
@@ -0,0 +1,82 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+
9
+
10
+ ## [0.3.3] - 2020-07-25
11
+
12
+ ### Fixed
13
+
14
+ - Explicit FileUtils require to avoid potentially warning logs
15
+
16
+
17
+
18
+ ## [0.3.2] - 2020-07-20
19
+
20
+ ### Added
21
+
22
+ - CLI: `diffcrypt generate-key` command to generate a new key for a cipher
23
+ - Internal: Library now generates and publishes code coverage publically on Code Climate
24
+
25
+ ### Changed
26
+
27
+ - Only support ruby 2.5+ since 2.4 is no longer maintained
28
+
29
+ ### Removed
30
+
31
+ - No longer generate and store a checksum. Backwards compatible since it wasn't used
32
+
33
+
34
+
35
+ ## [0.3.1] - 2020-07-08
36
+
37
+ ### Fixed
38
+
39
+ - Thor deprecation error no longer shows on CLI failure
40
+
41
+ ### Changed
42
+
43
+ - Thor 0.20+ can now be used alongside this gem
44
+
45
+
46
+
47
+ ## [0.3.0] - 2020-06-30
48
+
49
+ ## Added
50
+
51
+ - CLI: Use diffcrypt from command line of any project without requiring ruby integration
52
+ - CLI: `diffcrypt encrypt` Directly encrypt any file and output the contents
53
+ - CLI: `diffcrypt decrypt` Directly decrypt any file and output the contents
54
+
55
+
56
+
57
+ ## [0.2.0] - 2020-06-28
58
+
59
+ ### Added
60
+
61
+ - Store client, cipher and checksum in file metadata
62
+
63
+ ### Fixed
64
+
65
+ - Only attenpt to decrypt original content if it exists
66
+
67
+
68
+
69
+ ## [0.1.1] - 2020-06-28
70
+
71
+ ### Fixed
72
+
73
+ - Converting rails native credentials files would fail on first run
74
+
75
+
76
+
77
+ ## [0.1.0] - 2020-06-28
78
+
79
+ ### Added
80
+
81
+ - First release!
82
+ - Rails support via monkey patch
data/Gemfile CHANGED
@@ -7,4 +7,6 @@ gemspec
7
7
 
8
8
  gem 'minitest', '~> 5.0'
9
9
  gem 'rake', '~> 13.0'
10
- gem 'rubocop', '~> 0.86'
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
12
+ gem 'simplecov-lcov', '< 0.8'
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Diffcrypt
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/diffcrypt.svg)](https://rubygems.org/gems/diffcrypt)
4
+ [![CircleCI](https://circleci.com/gh/marcqualie/diffcrypt.svg?style=svg)](https://circleci.com/gh/marcqualie/diffcrypt)
5
+
6
+
3
7
  Diffable encrypted files that you can safely commit into your repo.
4
8
 
5
9
 
@@ -16,7 +20,7 @@ And then execute:
16
20
 
17
21
  $ bundle install
18
22
 
19
- Or install it yourself as:
23
+ Or install it globally (to use the CLI from any project):
20
24
 
21
25
  $ gem install diffcrypt
22
26
 
@@ -24,8 +28,24 @@ Or install it yourself as:
24
28
 
25
29
  ## Usage
26
30
 
31
+ There are a few ways to use the library, depending on how advanced your use case is.
32
+
27
33
 
28
- ### Encrypt existing file
34
+ ### CLI
35
+
36
+ The easiest way to get started is to use the CLI.
37
+
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
41
+ ```
42
+
43
+
44
+ ### Ruby
45
+
46
+ A direct API is exposed so `Diffcrypt::Encryptor` can be used in any ruby project.
47
+
48
+ **NOTE:** This API may change any time until v1.0
29
49
 
30
50
  ```ruby
31
51
  encryptor = Diffcrypt::Encryptor.new('99e1f86b9e61f24c56ff4108dd415091')
@@ -34,18 +54,16 @@ encrypted = encryptor.encrypt(yaml)
34
54
  File.write('tmp/example.yml.enc', encrypted)
35
55
  ```
36
56
 
37
- ### Decrypt a file
38
-
39
57
  ```ruby
40
58
  encryptor = Diffcrypt::Encryptor.new('99e1f86b9e61f24c56ff4108dd415091')
41
59
  yaml = File.read('test/fixtures/example.yml.enc')
42
60
  config = YAML.safe_load(encryptor.decrypt(yaml))
43
61
  ```
44
62
 
45
- ### Rails
63
+ ### Ruby on Rails
46
64
 
47
65
  Currently there is not native support for rails, but ActiveSupport can be monkeypatched to override
48
- the build in encrypter.
66
+ the built in encrypter. All existing `rails credentials:edit` also work with this method.
49
67
 
50
68
  ```ruby
51
69
  require 'diffcrypt/rails/encrypted_configuration'
@@ -0,0 +1,17 @@
1
+ # Security Policy
2
+
3
+
4
+
5
+ ## Supported Versions
6
+
7
+ Since the internal APIs may change dramatically until v1.0, here is a list of the versions that are supported.
8
+
9
+ | Version | Supported |
10
+ | ------- | ------------------ |
11
+ | 0.3.x | :white_check_mark: |
12
+
13
+
14
+
15
+ ## Reporting a Vulnerability
16
+
17
+ Please email security@marcqualie.com to report any security issues.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'thor'
5
+
6
+ require_relative '../lib/diffcrypt/cli'
7
+
8
+ Diffcrypt::CLI.start(ARGV)
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = 'Diffable encrypted configuration files that can be safely committed into a git repository'
13
13
  spec.homepage = 'https://github.com/marcqualie/diffcrypt'
14
14
  spec.license = 'MIT'
15
- spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
16
16
 
17
17
  # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
18
18
 
@@ -25,9 +25,10 @@ Gem::Specification.new do |spec|
25
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
- spec.bindir = 'exe'
29
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.bindir = 'bin'
29
+ spec.executables = %w[diffcrypt]
30
30
  spec.require_paths = ['lib']
31
31
 
32
32
  spec.add_runtime_dependency 'activesupport', '~> 6.0.0'
33
+ spec.add_runtime_dependency 'thor', '>= 0.20', '< 2'
33
34
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './encryptor'
4
+ require_relative './version'
5
+
6
+ module Diffcrypt
7
+ class CLI < Thor
8
+ desc 'decrypt <path>', 'Decrypt a file'
9
+ method_option :key, aliases: %i[k], required: true
10
+ def decrypt(path)
11
+ ensure_file_exists(path)
12
+ contents = File.read(path)
13
+ puts encryptor.decrypt(contents)
14
+ end
15
+
16
+ desc 'encrypt <path>', 'Encrypt a file'
17
+ method_option :key, aliases: %i[k], required: true
18
+ def encrypt(path)
19
+ ensure_file_exists(path)
20
+ contents = File.read(path)
21
+ puts encryptor.encrypt(contents)
22
+ end
23
+
24
+ desc 'generate-key', 'Generate a 32 bit key'
25
+ method_option :cipher, default: Encryptor::CIPHER
26
+ def generate_key
27
+ say Encryptor.generate_key(options[:cipher])
28
+ end
29
+
30
+ desc 'version', 'Show client version'
31
+ def version
32
+ say Diffcrypt::VERSION
33
+ end
34
+
35
+ no_commands do
36
+ def key
37
+ options[:key]
38
+ end
39
+
40
+ def encryptor
41
+ @encryptor ||= Encryptor.new(key)
42
+ end
43
+
44
+ def ensure_file_exists(path)
45
+ abort('[ERROR] File does not exist') unless File.exist?(path)
46
+ end
47
+
48
+ def self.exit_on_failure?
49
+ true
50
+ end
51
+ end
52
+ end
53
+ end
@@ -8,12 +8,14 @@ require 'yaml'
8
8
 
9
9
  require 'active_support/message_encryptor'
10
10
 
11
+ require_relative './version'
12
+
11
13
  module Diffcrypt
12
14
  class Encryptor
13
15
  CIPHER = 'aes-128-gcm'
14
16
 
15
- def self.generate_key
16
- SecureRandom.hex(ActiveSupport::MessageEncryptor.key_len(CIPHER))
17
+ def self.generate_key(cipher = CIPHER)
18
+ SecureRandom.hex(ActiveSupport::MessageEncryptor.key_len(cipher))
17
19
  end
18
20
 
19
21
  def initialize(key)
@@ -24,7 +26,7 @@ module Diffcrypt
24
26
  # @param [String] contents The raw YAML string to be encrypted
25
27
  def decrypt(contents)
26
28
  yaml = YAML.safe_load contents
27
- decrypted = decrypt_hash yaml
29
+ decrypted = decrypt_hash yaml['data']
28
30
  YAML.dump decrypted
29
31
  end
30
32
 
@@ -43,11 +45,23 @@ module Diffcrypt
43
45
 
44
46
  # @param [String] contents The raw YAML string to be encrypted
45
47
  # @param [String, nil] original_encrypted_contents The original (encrypted) content to determine which keys have changed
48
+ # @return [String]
46
49
  def encrypt(contents, original_encrypted_contents = nil)
50
+ data = encrypt_data contents, original_encrypted_contents
51
+ YAML.dump(
52
+ 'client' => "diffcrypt-#{Diffcrypt::VERSION}",
53
+ 'cipher' => CIPHER,
54
+ 'data' => data,
55
+ )
56
+ end
57
+
58
+ # @param [String] contents The raw YAML string to be encrypted
59
+ # @param [String, nil] original_encrypted_contents The original (encrypted) content to determine which keys have changed
60
+ # @return [Hash] Encrypted hash containing the data
61
+ def encrypt_data(contents, original_encrypted_contents = nil)
47
62
  yaml = YAML.safe_load contents
48
- original_yaml = original_encrypted_contents ? YAML.safe_load(original_encrypted_contents) : nil
49
- encrypted = encrypt_values yaml, original_yaml
50
- YAML.dump encrypted
63
+ original_yaml = original_encrypted_contents ? YAML.safe_load(original_encrypted_contents)['data'] : nil
64
+ encrypt_values yaml, original_yaml
51
65
  end
52
66
 
53
67
  # @param [String] value Plain text string that needs encrypting
@@ -66,7 +80,7 @@ module Diffcrypt
66
80
  data[key] = if value.is_a?(Hash) || value.is_a?(Array)
67
81
  encrypt_values(value, original_encrypted_value)
68
82
  else
69
- original_decrypted_value = original_data ? decrypt_string(original_encrypted_value) : nil
83
+ original_decrypted_value = original_encrypted_value ? decrypt_string(original_encrypted_value) : nil
70
84
  key_changed = original_decrypted_value.nil? || original_decrypted_value != value
71
85
  key_changed ? encrypt_string(value) : original_encrypted_value
72
86
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'fileutils'
3
4
  require 'pathname'
4
5
  require 'tmpdir'
5
6
 
@@ -50,7 +51,7 @@ module Diffcrypt
50
51
  deserialize(contents)
51
52
 
52
53
  IO.binwrite "#{content_path}.tmp", encrypt(contents, original_encrypted_contents)
53
- FileUtils.mv "#{content_path}.tmp", content_path
54
+ ::FileUtils.mv "#{content_path}.tmp", content_path
54
55
  end
55
56
 
56
57
  def config
@@ -81,7 +82,7 @@ module Diffcrypt
81
82
 
82
83
  write(updated_contents, content_path_diffable? && content_path.binread)
83
84
  ensure
84
- FileUtils.rm(tmp_path) if tmp_path&.exist?
85
+ ::FileUtils.rm(tmp_path) if tmp_path&.exist?
85
86
  end
86
87
  # rubocop:enable Metrics/AbcSize
87
88
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Diffcrypt
4
- VERSION = '0.1.1'
4
+ VERSION = '0.3.3'
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.1.1
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Qualie
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-28 00:00:00.000000000 Z
11
+ date: 2020-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,25 +24,51 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 6.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0.20'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '2'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0.20'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '2'
27
47
  description: Diffable encrypted configuration files that can be safely committed into
28
48
  a git repository
29
49
  email:
30
50
  - marc@marcqualie.com
31
- executables: []
51
+ executables:
52
+ - diffcrypt
32
53
  extensions: []
33
54
  extra_rdoc_files: []
34
55
  files:
56
+ - ".circleci/config.yml"
57
+ - ".github/dependabot.yml"
35
58
  - ".gitignore"
36
59
  - ".rubocop.yml"
37
- - ".travis.yml"
60
+ - CHANGELOG.md
38
61
  - Gemfile
39
62
  - LICENSE.txt
40
63
  - README.md
41
64
  - Rakefile
65
+ - SECURITY.md
42
66
  - bin/console
67
+ - bin/diffcrypt
43
68
  - bin/setup
44
69
  - diffcrypt.gemspec
45
70
  - lib/diffcrypt.rb
71
+ - lib/diffcrypt/cli.rb
46
72
  - lib/diffcrypt/encryptor.rb
47
73
  - lib/diffcrypt/rails/encrypted_configuration.rb
48
74
  - lib/diffcrypt/version.rb
@@ -60,14 +86,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
60
86
  requirements:
61
87
  - - ">="
62
88
  - !ruby/object:Gem::Version
63
- version: 2.3.0
89
+ version: 2.5.0
64
90
  required_rubygems_version: !ruby/object:Gem::Requirement
65
91
  requirements:
66
92
  - - ">="
67
93
  - !ruby/object:Gem::Version
68
94
  version: '0'
69
95
  requirements: []
70
- rubygems_version: 3.0.3
96
+ rubygems_version: 3.1.4
71
97
  signing_key:
72
98
  specification_version: 4
73
99
  summary: Diffable encrypted configuration files
@@ -1,6 +0,0 @@
1
- ---
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.6.6
6
- before_install: gem install bundler -v 2.1.4