Class: Diffcrypt::Encryptor

Inherits:
Object
  • Object
show all
Defined in:
lib/diffcrypt/encryptor.rb

Constant Summary collapse

DEFAULT_CIPHER =
'aes-256-gcm'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key, cipher: DEFAULT_CIPHER) ⇒ Encryptor

Returns a new instance of Encryptor.



22
23
24
25
26
# File 'lib/diffcrypt/encryptor.rb', line 22

def initialize(key, cipher: DEFAULT_CIPHER)
  @key = key
  @cipher = cipher
  @encryptor ||= ActiveSupport::MessageEncryptor.new([key].pack('H*'), cipher: cipher)
end

Class Method Details

.generate_key(cipher = DEFAULT_CIPHER) ⇒ Object



18
19
20
# File 'lib/diffcrypt/encryptor.rb', line 18

def self.generate_key(cipher = DEFAULT_CIPHER)
  SecureRandom.hex(ActiveSupport::MessageEncryptor.key_len(cipher))
end

Instance Method Details

#decrypt(contents) ⇒ Object

Parameters:

  • contents (String)

    The raw YAML string to be encrypted



29
30
31
32
33
# File 'lib/diffcrypt/encryptor.rb', line 29

def decrypt(contents)
  yaml = YAML.safe_load contents
  decrypted = decrypt_hash yaml['data']
  YAML.dump decrypted
end

#decrypt_hash(data) ⇒ Hash

Parameters:

  • data (Hash)

Returns:

  • (Hash)


37
38
39
40
41
42
43
44
45
46
# File 'lib/diffcrypt/encryptor.rb', line 37

def decrypt_hash(data)
  data.each do |key, value|
    data[key] = if value.is_a?(Hash) || value.is_a?(Array)
                  decrypt_hash(value)
                else
                  decrypt_string value
                end
  end
  data
end

#decrypt_string(value) ⇒ String

Parameters:

  • value (String)

    The encrypted value that needs decrypting

Returns:

  • (String)


96
97
98
# File 'lib/diffcrypt/encryptor.rb', line 96

def decrypt_string(value)
  @encryptor.decrypt_and_verify value
end

#encrypt(contents, original_encrypted_contents = nil, cipher: nil) ⇒ String

Parameters:

  • contents (String)

    The raw YAML string to be encrypted

  • original_encrypted_contents (String, nil) (defaults to: nil)

    The original (encrypted) content to determine which keys have changed

Returns:

  • (String)


51
52
53
54
55
56
57
58
# File 'lib/diffcrypt/encryptor.rb', line 51

def encrypt(contents, original_encrypted_contents = nil, cipher: nil)
  data = encrypt_data contents, original_encrypted_contents
  YAML.dump(
    'client' => "diffcrypt-#{Diffcrypt::VERSION}",
    'cipher' => cipher || @cipher,
    'data' => data,
  )
end

#encrypt_data(contents, original_encrypted_contents = nil) ⇒ Hash

Returns Encrypted hash containing the data.

Parameters:

  • contents (String)

    The raw YAML string to be encrypted

  • original_encrypted_contents (String, nil) (defaults to: nil)

    The original (encrypted) content to determine which keys have changed

Returns:

  • (Hash)

    Encrypted hash containing the data



63
64
65
66
67
# File 'lib/diffcrypt/encryptor.rb', line 63

def encrypt_data(contents, original_encrypted_contents = nil)
  yaml = YAML.safe_load contents
  original_yaml = original_encrypted_contents ? YAML.safe_load(original_encrypted_contents)['data'] : nil
  encrypt_values yaml, original_yaml
end

#encrypt_string(value) ⇒ String

Parameters:

  • value (String)

    Plain text string that needs encrypting

Returns:

  • (String)


71
72
73
# File 'lib/diffcrypt/encryptor.rb', line 71

def encrypt_string(value)
  @encryptor.encrypt_and_sign value
end

#encrypt_values(data, original_data = nil) ⇒ Hash

TODO: Fix the complexity of this method rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/CyclomaticComplexity

Parameters:

  • keys (Hash)

Returns:

  • (Hash)


79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/diffcrypt/encryptor.rb', line 79

def encrypt_values(data, original_data = nil)
  data.each do |key, value|
    original_encrypted_value = original_data ? original_data[key] : nil
    data[key] = if value.is_a?(Hash) || value.is_a?(Array)
                  encrypt_values(value, original_encrypted_value)
                else
                  original_decrypted_value = original_encrypted_value ? decrypt_string(original_encrypted_value) : nil
                  key_changed = original_decrypted_value.nil? || original_decrypted_value != value
                  key_changed ? encrypt_string(value) : original_encrypted_value
                end
  end
  data.sort.to_h
end