Class: Nvoi::Utils::CredentialStore
- Inherits:
-
Object
- Object
- Nvoi::Utils::CredentialStore
- Defined in:
- lib/nvoi/utils/credential_store.rb
Overview
CredentialStore handles encrypted credentials file operations
Instance Attribute Summary collapse
-
#encrypted_path ⇒ Object
readonly
Returns the value of attribute encrypted_path.
-
#key_path ⇒ Object
readonly
Returns the value of attribute key_path.
Class Method Summary collapse
-
.for_init(working_dir) ⇒ Object
Create a store for initial setup (no existing files required).
Instance Method Summary collapse
-
#exists? ⇒ Boolean
Check if the encrypted credentials file exists.
-
#has_key? ⇒ Boolean
Check if the store has a master key loaded.
-
#initialize(working_dir, encrypted_path = nil, key_path = nil) ⇒ CredentialStore
constructor
Create a new credentials store working_dir: base directory to search for files encrypted_path: explicit path to encrypted file (optional, nil = auto-discover) key_path: explicit path to key file (optional, nil = auto-discover).
-
#initialize_credentials(template) ⇒ Object
Initialize creates a new encrypted credentials file with a generated key Returns the generated key.
-
#read ⇒ Object
Decrypt and return the credentials content.
-
#set_master_key_for_testing(key) ⇒ Object
For testing purposes.
-
#update_gitignore ⇒ Object
Add deploy.key to .gitignore if not already present.
-
#write(plaintext) ⇒ Object
Encrypt and save the credentials content.
Constructor Details
#initialize(working_dir, encrypted_path = nil, key_path = nil) ⇒ CredentialStore
Create a new credentials store working_dir: base directory to search for files encrypted_path: explicit path to encrypted file (optional, nil = auto-discover) key_path: explicit path to key file (optional, nil = auto-discover)
18 19 20 21 22 23 24 25 |
# File 'lib/nvoi/utils/credential_store.rb', line 18 def initialize(working_dir, encrypted_path = nil, key_path = nil) @working_dir = working_dir @encrypted_path = encrypted_path.blank? ? find_encrypted_file : encrypted_path @key_path = nil @master_key = nil resolve_key(key_path) end |
Instance Attribute Details
#encrypted_path ⇒ Object (readonly)
Returns the value of attribute encrypted_path.
12 13 14 |
# File 'lib/nvoi/utils/credential_store.rb', line 12 def encrypted_path @encrypted_path end |
#key_path ⇒ Object (readonly)
Returns the value of attribute key_path.
12 13 14 |
# File 'lib/nvoi/utils/credential_store.rb', line 12 def key_path @key_path end |
Class Method Details
.for_init(working_dir) ⇒ Object
Create a store for initial setup (no existing files required)
28 29 30 31 32 33 34 35 |
# File 'lib/nvoi/utils/credential_store.rb', line 28 def self.for_init(working_dir) store = allocate store.instance_variable_set(:@working_dir, working_dir) store.instance_variable_set(:@encrypted_path, File.join(working_dir, DEFAULT_ENCRYPTED_FILE)) store.instance_variable_set(:@key_path, nil) store.instance_variable_set(:@master_key, nil) store end |
Instance Method Details
#exists? ⇒ Boolean
Check if the encrypted credentials file exists
38 39 40 |
# File 'lib/nvoi/utils/credential_store.rb', line 38 def exists? File.exist?(@encrypted_path) end |
#has_key? ⇒ Boolean
Check if the store has a master key loaded
43 44 45 |
# File 'lib/nvoi/utils/credential_store.rb', line 43 def has_key? !@master_key.blank? end |
#initialize_credentials(template) ⇒ Object
Initialize creates a new encrypted credentials file with a generated key Returns the generated key
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/nvoi/utils/credential_store.rb', line 75 def initialize_credentials(template) # Generate new key @master_key = Crypto.generate_key # Write key file @key_path = File.join(File.dirname(@encrypted_path), DEFAULT_KEY_FILE) File.write(@key_path, "#{@master_key}\n", perm: 0o600) begin write(template) rescue StandardError => e File.delete(@key_path) if File.exist?(@key_path) raise e end @master_key end |
#read ⇒ Object
Decrypt and return the credentials content
48 49 50 51 52 53 |
# File 'lib/nvoi/utils/credential_store.rb', line 48 def read raise Errors::CredentialError, "master key not loaded" unless has_key? ciphertext = File.binread(@encrypted_path) Crypto.decrypt(ciphertext, @master_key) end |
#set_master_key_for_testing(key) ⇒ Object
For testing purposes
112 113 114 |
# File 'lib/nvoi/utils/credential_store.rb', line 112 def set_master_key_for_testing(key) @master_key = key end |
#update_gitignore ⇒ Object
Add deploy.key to .gitignore if not already present
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/nvoi/utils/credential_store.rb', line 94 def update_gitignore gitignore_path = File.join(@working_dir, ".gitignore") content = File.exist?(gitignore_path) ? File.read(gitignore_path) : "" # Check if already present return if content.lines.any? { |line| line.strip == DEFAULT_KEY_FILE } File.open(gitignore_path, "a") do |f| # Add newline if file doesn't end with one f.write("\n") if !content.empty? && !content.end_with?("\n") # Add comment and entry f.write("\n# NVOI master key (do not commit)\n#{DEFAULT_KEY_FILE}\n") end end |
#write(plaintext) ⇒ Object
Encrypt and save the credentials content
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/nvoi/utils/credential_store.rb', line 56 def write(plaintext) raise Errors::CredentialError, "master key not loaded" unless has_key? ciphertext = Crypto.encrypt(plaintext, @master_key) # Write atomically: write to temp file, then rename tmp_path = "#{@encrypted_path}.tmp" File.binwrite(tmp_path, ciphertext, perm: 0o600) begin File.rename(tmp_path, @encrypted_path) rescue StandardError => e File.delete(tmp_path) if File.exist?(tmp_path) raise Errors::CredentialError, "failed to rename temp file: #{e.}" end end |