Skip to content

Commit 8c15d36

Browse files
committed
Store client and cipher in comitted file
This can help with debugging + compatilibty issues as the library evolves
1 parent 5aa4e25 commit 8c15d36

File tree

3 files changed

+39
-16
lines changed

3 files changed

+39
-16
lines changed

lib/diffcrypt/encryptor.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def initialize(key)
2424
# @param [String] contents The raw YAML string to be encrypted
2525
def decrypt(contents)
2626
yaml = YAML.safe_load contents
27-
decrypted = decrypt_hash yaml
27+
decrypted = decrypt_hash yaml['data']
2828
YAML.dump decrypted
2929
end
3030

@@ -43,11 +43,23 @@ def decrypt_hash(data)
4343

4444
# @param [String] contents The raw YAML string to be encrypted
4545
# @param [String, nil] original_encrypted_contents The original (encrypted) content to determine which keys have changed
46+
# @return [String]
4647
def encrypt(contents, original_encrypted_contents = nil)
48+
data = encrypt_data contents, original_encrypted_contents
49+
YAML.dump(
50+
'client' => "diffcrypt-#{Diffcrypt::VERSION}",
51+
'cipher' => CIPHER,
52+
'data' => data,
53+
)
54+
end
55+
56+
# @param [String] contents The raw YAML string to be encrypted
57+
# @param [String, nil] original_encrypted_contents The original (encrypted) content to determine which keys have changed
58+
# @return [Hash] Encrypted hash containing the data
59+
def encrypt_data(contents, original_encrypted_contents = nil)
4760
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
61+
original_yaml = original_encrypted_contents ? YAML.safe_load(original_encrypted_contents)['data'] : nil
62+
encrypt_values yaml, original_yaml
5163
end
5264

5365
# @param [String] value Plain text string that needs encrypting

test/diffcrypt/encryptor_test.rb

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,19 @@
55
# Since the encrypted values use openssl and are non-deterministic, we can never know the
66
# actual value to test against. All we can do is ensure the value is in the correct format
77
# for the encrypted content, which verifies it's not in the original state
8-
ENCRYPTED_VALUE_PATTERN = %('?([a-z0-9A-Z=/+]+)\-\-([a-z0-9A-Z=/+]+)\-\-([a-z0-9A-Z=/+]+)'?)
8+
ENCRYPTED_VALUE_PATTERN = %(['"]?([a-z0-9A-Z=/+]+)\-\-([a-z0-9A-Z=/+]+)\-\-([a-z0-9A-Z=/+]+)['"]?)
99

1010
class Diffcrypt::EncryptorTest < Minitest::Test
11+
def test_it_includes_client_info_at_root
12+
content = "---\nkey: value"
13+
expected_pattern = /---\nclient: diffcrypt-#{Diffcrypt::VERSION}\ncipher: #{Diffcrypt::Encryptor::CIPHER}\ndata:\n key: #{ENCRYPTED_VALUE_PATTERN}\n/
14+
assert_match expected_pattern, Diffcrypt::Encryptor.new(TEST_KEY).encrypt(content)
15+
end
16+
1117
def test_it_decrypts_root_values
1218
encrypted_content = <<~CONTENT
13-
secret_key_base: 88Ry6HESUoXBr6QUFXmni9zzfCIYt9qGNFvIWFcN--4xoecI5mqbNRBibI--62qPJbkzzh5h8lhFEFOSaQ==
19+
data:
20+
secret_key_base: 88Ry6HESUoXBr6QUFXmni9zzfCIYt9qGNFvIWFcN--4xoecI5mqbNRBibI--62qPJbkzzh5h8lhFEFOSaQ==
1421
CONTENT
1522
expected = <<~CONTENT
1623
---
@@ -27,14 +34,15 @@ def test_it_encrypts_root_values
2734
CONTENT
2835
expected_pattern = /---\nsecret_key_base: #{ENCRYPTED_VALUE_PATTERN}\n/
2936

30-
assert_match expected_pattern, Diffcrypt::Encryptor.new(TEST_KEY).encrypt(content)
37+
assert_match expected_pattern, Diffcrypt::Encryptor.new(TEST_KEY).encrypt_data(content).to_yaml
3138
end
3239

3340
def test_it_decrypts_nested_structures
3441
encrypted_content = <<~CONTENT
35-
secret_key_base: 88Ry6HESUoXBr6QUFXmni9zzfCIYt9qGNFvIWFcN--4xoecI5mqbNRBibI--62qPJbkzzh5h8lhFEFOSaQ==
36-
aws:
37-
access_key_id: Ot/uCTEL+8kp61EPctnxNlg=--Be6sg7OdvjZlfxgR--7qRbbf0lA4VgjnUGUrrFwg==
42+
data:
43+
secret_key_base: 88Ry6HESUoXBr6QUFXmni9zzfCIYt9qGNFvIWFcN--4xoecI5mqbNRBibI--62qPJbkzzh5h8lhFEFOSaQ==
44+
aws:
45+
access_key_id: Ot/uCTEL+8kp61EPctnxNlg=--Be6sg7OdvjZlfxgR--7qRbbf0lA4VgjnUGUrrFwg==
3846
CONTENT
3947
expected = <<~CONTENT
4048
---
@@ -55,16 +63,16 @@ def test_it_encrypts_nested_structures
5563
CONTENT
5664
expected_pattern = /---\nsecret_key_base: #{ENCRYPTED_VALUE_PATTERN}\naws:\n access_key_id: #{ENCRYPTED_VALUE_PATTERN}\n/
5765

58-
assert_match expected_pattern, Diffcrypt::Encryptor.new(TEST_KEY).encrypt(content)
66+
assert_match expected_pattern, Diffcrypt::Encryptor.new(TEST_KEY).encrypt_data(content).to_yaml
5967
end
6068

6169
# Verifies that a change to one key does not cause the encrypted values for other keys to be recomputed
6270
# Mainly used in conjunction with rails credentials editor
6371
def test_it_only_updates_changed_values
64-
original_encrypted_content = "---\nsecret_key_base_1: 88Ry6HESUoXBr6QUFXmni9zzfCIYt9qGNFvIWFcN--4xoecI5mqbNRBibI--62qPJbkzzh5h8lhFEFOSaQ==\naws:\n secret_access_key: 88Ry6HESUoXBr6QUFXmni9zzfCIYt9qGNFvIWFcN--4xoecI5mqbNRBibI--62qPJbkzzh5h8lhFEFOSaQ==\n"
72+
original_encrypted_content = "---\ndata:\n secret_key_base_1: 88Ry6HESUoXBr6QUFXmni9zzfCIYt9qGNFvIWFcN--4xoecI5mqbNRBibI--62qPJbkzzh5h8lhFEFOSaQ==\naws:\n secret_access_key: 88Ry6HESUoXBr6QUFXmni9zzfCIYt9qGNFvIWFcN--4xoecI5mqbNRBibI--62qPJbkzzh5h8lhFEFOSaQ==\n"
6573
updated_content = "---\nsecret_key_base_1: secret_key_base_test\naws:\n secret_access_key: secret_access_key_2"
6674
expected_pattern = /---\nsecret_key_base_1: 88Ry6HESUoXBr6QUFXmni9zzfCIYt9qGNFvIWFcN--4xoecI5mqbNRBibI--62qPJbkzzh5h8lhFEFOSaQ==\naws:\n secret_access_key: #{ENCRYPTED_VALUE_PATTERN}\n/
6775

68-
assert_match expected_pattern, Diffcrypt::Encryptor.new(TEST_KEY).encrypt(updated_content, original_encrypted_content)
76+
assert_match expected_pattern, Diffcrypt::Encryptor.new(TEST_KEY).encrypt_data(updated_content, original_encrypted_content).to_yaml
6977
end
7078
end

test/fixtures/example.yml.enc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
---
2-
secret_key_base: q/nKM+MSI0IAUUGTxn336uQDgDXbJxDu6GNI3vlL--I6DThmOJBJYK6SDZ--8wmyBE0O3tGtiZK8gw69Bg==
3-
aws:
4-
access_key_id: HEnbrD9fiNclsf2hFNAyPw==--hbJkPko9OV1QXxAq--zEkhplu33aZ9a5YCPs6mlg==
2+
client: diffcrypt-0.1.1
3+
cipher: aes-128-gcm
4+
data:
5+
secret_key_base: q/nKM+MSI0IAUUGTxn336uQDgDXbJxDu6GNI3vlL--I6DThmOJBJYK6SDZ--8wmyBE0O3tGtiZK8gw69Bg==
6+
aws:
7+
access_key_id: HEnbrD9fiNclsf2hFNAyPw==--hbJkPko9OV1QXxAq--zEkhplu33aZ9a5YCPs6mlg==

0 commit comments

Comments
 (0)