Class: Keybox::Storage::Container
- Defined in:
- lib/keybox/storage/container.rb
Overview
The container of the Keybox records. The Container itself is a Keybox::Storage::Record with a few extra methods.
A instance of a Container is created with a assprhase and a path to a file. The passphrase can be anything that has a to_s method.
container = Keybox::Storage::Container.new("i love ruby", "/tmp/database.yml")
This will load from the given file with the given passphrase if the file exists, or it will initalize the container to accept records.
The records are held decrypted in memory, so keep that in mind if that is a concern.
Add Records
record = Keybox::Storage::Record.new
record.field1 = "data"
record.field1 = "some more data"
container << record
Delete Records
container.delete(record)
There is no ‘update’ record, just delete it and add it.
Find a record accepts a string and will look in all the records it contains for anything that matches it. It coerces strings into Regexp
so any regex can be used here too.
container.find("data")
Report if the container or any of its records have been modified:
container.modified?
Save the container to its default location:
container.save
Or to some other location
container.save("/some/other/path.yml")
Direct access to the decrypted records is also available through the records
accessor.
container.records #=> Array of Keybox::Storage::Record
Constant Summary collapse
- ITERATIONS =
2048
Constants inherited from Record
Instance Attribute Summary collapse
-
#records ⇒ Object
readonly
Returns the value of attribute records.
Attributes inherited from Record
#creation_time, #data_members, #last_access_time, #modification_time, #uuid
Instance Method Summary collapse
-
#<<(obj) ⇒ Object
Add a record to the system.
-
#calculated_key(passphrase = @passphrase) ⇒ Object
calculate the encryption key from the initial passphrase.
-
#calculated_key_digest(passphrase) ⇒ Object
calculate the key digest of the encryption key.
-
#delete(obj) ⇒ Object
Delete a record from the system, we force a modified flag here since the underlying Record wasn’t ‘assigned to’ we have to force modification notification.
-
#find(search_string, restricted_to = nil) ⇒ Object
Search all the records in the database finding any that match the search string passed in.
-
#find_by_url(url) ⇒ Object
Search only records that have a
url
field. -
#initialize(passphrase, path) ⇒ Container
constructor
A new instance of Container.
-
#length ⇒ Object
The number of Records in the Container.
-
#load_from_file ⇒ Object
load from file, if this is successful then replace the existing member fields on this instance with the data from the file.
-
#modified? ⇒ Boolean
See if we are modified, or if any of the records are modified.
-
#passphrase=(new_passphrase) ⇒ Object
Change the master password of the container.
-
#save(path = @path) ⇒ Object
save the current container to a file.
-
#size ⇒ Object
The number of Records in the Container.
Methods inherited from Record
#==, #eql?, #method_missing, #modified=, #to_yaml_properties
Constructor Details
#initialize(passphrase, path) ⇒ Container
Returns a new instance of Container.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/keybox/storage/container.rb', line 72 def initialize(passphrase,path) super() @path = path @passphrase = passphrase @records = [] if not load_from_file then self.version = Keybox::VERSION self.key_calc_iterations = ITERATIONS self.key_digest_salt = Keybox::RandomDevice.random_bytes(32) self.key_digest_algorithm = Keybox::Digest::DEFAULT_ALGORITHM self.key_digest = calculated_key_digest(passphrase) self.records_init_vector = Keybox::RandomDevice.random_bytes(16) self.records_cipher_algorithm = Keybox::Cipher::DEFAULT_ALGORITHM self.records_encrypted_data = "" self.records_digest_salt = Keybox::RandomDevice.random_bytes(32) self.records_digest_algorithm = Keybox::Digest::DEFAULT_ALGORITHM self.records_digest = "" end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Keybox::Storage::Record
Instance Attribute Details
#records ⇒ Object (readonly)
Returns the value of attribute records.
69 70 71 |
# File 'lib/keybox/storage/container.rb', line 69 def records @records end |
Instance Method Details
#<<(obj) ⇒ Object
Add a record to the system
167 168 169 170 171 172 |
# File 'lib/keybox/storage/container.rb', line 167 def <<(obj) if obj.respond_to?("needs_container_passphrase?") and obj.needs_container_passphrase? then obj.container_passphrase = @passphrase end @records << obj end |
#calculated_key(passphrase = @passphrase) ⇒ Object
calculate the encryption key from the initial passphrase
149 150 151 152 153 154 155 |
# File 'lib/keybox/storage/container.rb', line 149 def calculated_key(passphrase = @passphrase) key = self.key_digest_salt + passphrase self.key_calc_iterations.times do key = Keybox::Digest::CLASSES[self.key_digest_algorithm].digest(key) end return key end |
#calculated_key_digest(passphrase) ⇒ Object
calculate the key digest of the encryption key
160 161 162 |
# File 'lib/keybox/storage/container.rb', line 160 def calculated_key_digest(passphrase) Keybox::Digest::CLASSES[self.key_digest_algorithm].hexdigest(calculated_key(passphrase)) end |
#delete(obj) ⇒ Object
Delete a record from the system, we force a modified flag here since the underlying Record wasn’t ‘assigned to’ we have to force modification notification.
193 194 195 196 |
# File 'lib/keybox/storage/container.rb', line 193 def delete(obj) @records.delete(obj) @modified = true end |
#find(search_string, restricted_to = nil) ⇒ Object
Search all the records in the database finding any that match the search string passed in. The Search string is converted to a Regexp before beginning.
A list of restricted fields can also be passed in and the regexp will only be matched against those fields
213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/keybox/storage/container.rb', line 213 def find(search_string,restricted_to = nil) regex = Regexp.new(search_string) matches = [] @records.each do |record| restricted_to = restricted_to || ( record.fields - %w(password) ) record.data_members.each_pair do |k,v| if regex.match(v) and restricted_to.include?(k.to_s) then matches << record break end end end return matches end |
#find_by_url(url) ⇒ Object
Search only records that have a url
field
201 202 203 |
# File 'lib/keybox/storage/container.rb', line 201 def find_by_url(url) find(url,%w(url)) end |
#length ⇒ Object
The number of Records in the Container
177 178 179 |
# File 'lib/keybox/storage/container.rb', line 177 def length @records.size end |
#load_from_file ⇒ Object
load from file, if this is successful then replace the existing member fields on this instance with the data from the file
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/keybox/storage/container.rb', line 113 def load_from_file return false unless File.exists?(@path) return false unless tmp = YAML.load_file(@path) @creation_time = tmp.creation_time @modification_time = tmp.modification_time @last_access_time = tmp.last_access_time @data_members = tmp.data_members @uuid = tmp.uuid validate_passphrase decrypt_records validate_decryption load_records @modified = false true end |
#modified? ⇒ Boolean
See if we are modified, or if any of the records are modified
232 233 234 235 236 237 238 |
# File 'lib/keybox/storage/container.rb', line 232 def modified? return true if super @records.each do |record| return true if record.modified? end return false end |
#passphrase=(new_passphrase) ⇒ Object
Change the master password of the container
100 101 102 103 104 105 106 |
# File 'lib/keybox/storage/container.rb', line 100 def passphrase=(new_passphrase) @passphrase = new_passphrase self.key_digest_salt = Keybox::RandomDevice.random_bytes(32) self.key_digest = calculated_key_digest(new_passphrase) self.records_init_vector = Keybox::RandomDevice.random_bytes(16) self.records_digest_salt = Keybox::RandomDevice.random_bytes(32) end |
#save(path = @path) ⇒ Object
save the current container to a file
132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/keybox/storage/container.rb', line 132 def save(path = @path) calculate_records_digest encrypt_records File.open(path,"w") do |f| f.write(self.to_yaml) end # mark everything as not modified @records.each do |record| record.modified = false end @modified = false end |
#size ⇒ Object
The number of Records in the Container
184 185 186 |
# File 'lib/keybox/storage/container.rb', line 184 def size @records.size end |