Class: SecretKeys
- Inherits:
-
Hash
- Object
- Hash
- SecretKeys
- Defined in:
- lib/secret_keys.rb,
lib/secret_keys/version.rb
Overview
Load a JSON file with encrypted values. This value can be used as a hash.
Defined Under Namespace
Modules: CLI Classes: EncryptionKeyError, Encryptor, VersionError
Constant Summary collapse
- VERSION =
File.read(File.join(__dir__, "..", "..", "VERSION")).chomp.freeze
- CRYPTO_VERSION =
1
Instance Method Summary collapse
-
#decrypt!(key) ⇒ void
Mark the key as no longer being decrypted when the JSON is saved.
-
#encrypt!(key) ⇒ void
Mark the key as being encrypted when the JSON is saved.
-
#encrypted?(key) ⇒ Boolean
Return true if the key is encrypted.
-
#encrypted_hash ⇒ Hash
Output the keys as a hash that matches the structure that can be loaded by the initalizer.
-
#encryption_key=(new_encryption_key) ⇒ void
Change the encryption key in the document.
-
#initialize(path_or_stream, encryption_key = nil) ⇒ SecretKeys
constructor
Parse a JSON or YAML stream or file with encrypted values.
-
#input_format ⇒ String
Return the data format (:json or :yaml) for the original data.
-
#save(path, format: nil) ⇒ void
Save the encrypted hash to a file at the specified path.
-
#to_h ⇒ Hash
(also: #to_hash)
Convert into an actual Hash object.
Constructor Details
#initialize(path_or_stream, encryption_key = nil) ⇒ SecretKeys
If no encryption key is passed, this will defautl to env var SECRET_KEYS_ENCRYPTION_KEY
Parse a JSON or YAML stream or file with encrypted values. Any values in the “.encrypted” key in the document will be decrypted with the provided encryption key. If values were put into the “.encrypted” key manually and are not yet encrypted, they will be used as is without any decryption.
or (if that is empty) the value read from the file path in SECRET_KEYS_ENCRYPTION_KEY_FILE.
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/secret_keys.rb', line 28 def initialize(path_or_stream, encryption_key = nil) @encryption_key = nil @salt = nil @format = :json encryption_key = read_encryption_key(encryption_key) update_secret(key: encryption_key) path_or_stream = Pathname.new(path_or_stream) if path_or_stream.is_a?(String) load_secrets!(path_or_stream) super(@values) end |
Instance Method Details
#decrypt!(key) ⇒ void
This method returns an undefined value.
Mark the key as no longer being decrypted when the JSON is saved.
62 63 64 65 |
# File 'lib/secret_keys.rb', line 62 def decrypt!(key) @secret_keys.delete(key) nil end |
#encrypt!(key) ⇒ void
This method returns an undefined value.
Mark the key as being encrypted when the JSON is saved.
53 54 55 56 |
# File 'lib/secret_keys.rb', line 53 def encrypt!(key) @secret_keys << key nil end |
#encrypted?(key) ⇒ Boolean
Return true if the key is encrypted.
71 72 73 |
# File 'lib/secret_keys.rb', line 71 def encrypted?(key) @secret_keys.include?(key) end |
#encrypted_hash ⇒ Hash
Output the keys as a hash that matches the structure that can be loaded by the initalizer. Values that have not changed will not be re-salted so the encrypted values will remain the same.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/secret_keys.rb', line 107 def encrypted_hash raise EncryptionKeyError.new("Encryption key not specified") if @encryption_key.nil? || @encryption_key.empty? hash = {} encrypted = {} @values.each do |key, value| if @secret_keys.include?(key) encrypted[key] = value else hash[key] = value end end unless encryption_key_matches?(@original_encrypted[ENCRYPTION_KEY]) @original_encrypted = {} end encrypted.merge!(encrypt_values(encrypted, @original_encrypted)) encrypted[SALT] = @salt encrypted[ENCRYPTION_KEY] = (@original_encrypted[ENCRYPTION_KEY] || encrypted_known_value) encrypted[VERSION_KEY] = CRYPTO_VERSION hash[ENCRYPTED] = encrypted hash end |
#encryption_key=(new_encryption_key) ⇒ void
This method returns an undefined value.
Change the encryption key in the document. When saving later, this key will be used.
136 137 138 139 |
# File 'lib/secret_keys.rb', line 136 def encryption_key=(new_encryption_key) @original_encrypted = {} update_secret(key: new_encryption_key) end |
#input_format ⇒ String
Return the data format (:json or :yaml) for the original data. Defaults to :json.
144 145 146 |
# File 'lib/secret_keys.rb', line 144 def input_format @format end |
#save(path, format: nil) ⇒ void
This method returns an undefined value.
Save the encrypted hash to a file at the specified path. Encrypted values in an existing file will not be updated if the values have not changed (since each call uses a different initialization vector). This can be helpful if you have your secrets in source control so that only changed keys will actually be changed in the file when it is updated.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/secret_keys.rb', line 83 def save(path, format: nil) # create a copy of the encrypted hash for working on encrypted = encrypted_hash if format.nil? if yaml_file?(path) format = :yaml elsif json_file?(path) format = :json end end format ||= @format format = format.to_s.downcase output = ((format == "yaml") ? YAML.dump(encrypted) : JSON.pretty_generate(encrypted)) output << $/ unless output.end_with?($/) # ensure file ends with system dependent new line File.write(path, output) nil end |
#to_h ⇒ Hash Also known as: to_hash
Convert into an actual Hash object.
44 45 46 |
# File 'lib/secret_keys.rb', line 44 def to_h @values end |