Class: Reedb::ReeVault
- Inherits:
-
Object
- Object
- Reedb::ReeVault
- Defined in:
- lib/reedb/reevault.rb
Instance Attribute Summary collapse
-
#crypt ⇒ Object
readonly
Encryption handler to be used by the vault files.
-
#header_set ⇒ Object
readonly
Holds a hash of possible values that header files in this vault can have.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
-
#size ⇒ Object
readonly
Indicates the size of the vault as per data file entries.
Instance Method Summary collapse
-
#add_header_field(name, type) ⇒ Object
Fields can be added to a vault header BUT NOT REMOVED AGAIN! So be careful what you put in your header.
- #close ⇒ Object
-
#count ⇒ Object
Counts the vault contents and returns an Integer WITHOUT HAVING TO UNLOCK THE VAULT!.
- #create(password = :failed) ⇒ Object
-
#includes?(file) ⇒ Boolean
Quickly returns if a file exists in the vault or it’s children.
-
#initialize(name, path, encprytion, header_override = nil) ⇒ ReeVault
constructor
Constructor for a vault with name, path and encryption enum.
-
#list_headers(search) ⇒ Object
Returns headers according to a search queury.
- #load(password) ⇒ Object
-
#locked? ⇒ Boolean
Little helper method to determine if a vault is in the middle of a write cycle.
-
#read_file(name, history = false) ⇒ Object
Read a single file from the vault in secure mode Returns the entire file or only it’s current set in hashes.
- #remove_file(name) ⇒ Object
- #secure_config(boolean = true) ⇒ Object
- #to_s ⇒ Object
-
#try? ⇒ Boolean
Pokes if a vault exists.
-
#unload(time) ⇒ Object
Dump headers and files from memory in times of inactivity for security reasons.
-
#update(name, data) ⇒ Object
Check the file API or the wiki to learn how this function works.
Constructor Details
#initialize(name, path, encprytion, header_override = nil) ⇒ ReeVault
Constructor for a vault with name, path and encryption enum. Valid encryption parameters are :aes, :twofish, :multi and :auto_fill
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/reedb/reevault.rb', line 57 def initialize(name, path, encprytion, header_override = nil) @already_logging = false # Header maps @headers = {} @hgroups = {} # Fileset @locked = false @locks = [] # Defines the default (and boring vanilla) header set # TODO: Get the header set via config and init that instead! @header_set = header_override ? header_override : { 'urls' => 'list', 'tags' => 'list' } # Make the path available as an object variable construct_path("#{name}", "#{path}") # Init ecnryption module. So @crypt must not be nil after this init_encryption(encprytion) # Setup the secure config to false by default. Change this? self.secure_config(false) return self end |
Instance Attribute Details
#crypt ⇒ Object (readonly)
Encryption handler to be used by the vault files
41 42 43 |
# File 'lib/reedb/reevault.rb', line 41 def crypt @crypt end |
#header_set ⇒ Object (readonly)
Holds a hash of possible values that header files in this vault can have. Fields need to be specified by name and a type. To choose from ‘single’, ‘list’ and ‘tree’ (var, list, dict)
52 53 54 |
# File 'lib/reedb/reevault.rb', line 52 def header_set @header_set end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
37 38 39 |
# File 'lib/reedb/reevault.rb', line 37 def path @path end |
#size ⇒ Object (readonly)
Indicates the size of the vault as per data file entries. Is updated with every header cache and write cycle.
46 47 48 |
# File 'lib/reedb/reevault.rb', line 46 def size @size end |
Instance Method Details
#add_header_field(name, type) ⇒ Object
Fields can be added to a vault header BUT NOT REMOVED AGAIN! So be careful what you put in your header. (aka upgrade yes, downgrade noooo)
Unused fields can remain blank but need to stay in a vaults header list for backwards compatiblity
95 96 97 |
# File 'lib/reedb/reevault.rb', line 95 def add_header_field(name, type) @header_set[name] = type unless @header_set[name] end |
#close ⇒ Object
356 357 358 359 360 361 362 363 364 |
# File 'lib/reedb/reevault.rb', line 356 def close VaultLogger.write('Force closing the vault. Check parent logs for details', 'debug') # puts "Crypto module is: #{@crypt}" @crypt.stop_encryption if @crypt && @crypt.init # Removing class variables for cleanup remove_instance_variable(:@crypt) remove_instance_variable(:@headers) end |
#count ⇒ Object
Counts the vault contents and returns an Integer WITHOUT HAVING TO UNLOCK THE VAULT!
108 109 110 111 112 113 114 |
# File 'lib/reedb/reevault.rb', line 108 def count counter = 0 Dir.glob("#{@path}/data/*.ree") do |f| counter += 1 end return counter end |
#create(password = :failed) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/reedb/reevault.rb', line 124 def create(password = :failed) # If keygen was used to set a user password then fetch it # and remove the variable from memory! return nil unless password?(password) return nil unless encryption?(password) # puts "This is the password: #{password}" # => Encryption now active and key available under @crypt.key @conf_path = "#{@path}/config" needs_creation = true if self.includes?('config') raise VaultExistsAtLocationError.new, "Vault already exists at location #{@path}. Aborting operation..." # => This rules out lots of code to be run needs_creation = false else FileUtils::mkdir_p(File.("#{@path}/data")) # => Data dir FileUtils::mkdir(File.("#{@path}/shasums")) # => Checksum dir FileUtils::mkdir(File.("#{@path}/logs")) # => Logs dir # On *nix devices change permissions. if Reedb::archos == :linux || Reedb::archos == :osx || Reedb::archos == :vars FileUtils::chmod_R(0744, "#{@path}") end end # Now that the vault directory exists logs can be opened. init_logger(true) if needs_creation # Code that will only be run if the vault was just created on the system time = Reedb::Utilities.get_time(false) VaultLogger.write("Vault created on #{time}. All directories created successfully!") # => Now creating configuration file @config = {} @config['vault_name'] = "#{@name}" @config['creation_date'] = "#{Utilities.get_time}" @config['last_updated'] = "#{Utilities.get_time}" @config['creation_machine'] = "#{Socket.gethostname}" @config['updating_machine'] = "#{Socket.gethostname}" @config['creation_user'] = "#{Etc.getlogin}" @config['updating_user'] = "#{Etc.getlogin}" # Convert the header set to JSON, then write it into the config hset = JSON.dump(@header_set) @config['header_set'] = "#{hset}" # Add the Reedb version this vault was created with for upgradability @config['creation_version'] = "#{Reedb::VERSION}" save_config # Now writing encrypted key to file with ASCII armour update_secure_info('cey', @encrypted_key) # remove_instance_variable(:@encrypted_key) end self.load(password) end |
#includes?(file) ⇒ Boolean
Quickly returns if a file exists in the vault or it’s children.
367 368 369 |
# File 'lib/reedb/reevault.rb', line 367 def includes?(file) return File.exists?("#{@path}/#{file}") end |
#list_headers(search) ⇒ Object
Returns headers according to a search queury
{ ‘name’ => ‘__name__’, ‘url’ => ‘__url__’, ‘tags’ => ‘__tags__’, ‘generic_field’ => ‘generic_information’ }
‘tags=search engines, internet#urls=www.poodle.com’
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/reedb/reevault.rb', line 310 def list_headers search query = {} cache_headers # => This fills @headers and @hfields return @headers unless search begin splat = search.split('#') splat.each do |target| slice = target.split('=') query["#{slice[0]}"] = slice[1..-1] end # Rescue the query in case it was bad rescue raise MalformedSearchError.new, 'Malformed search data' end log_query = {} candidates = [] query.each do |cat, data| data.each do |val| log_query["#{cat}"] = @hgroups["#{cat}"]["#{val}"] if @hgroups["#{cat}"].include?(val) log_query["#{cat}"].each { |c| candidates << c unless candidates.include?(c) } end end return_buffer = candidates candidates.each do |can| log_query.each do |cat, data| return_buffer.delete(can) unless log_query["#{cat}"].include?(can) end end return return_buffer end |
#load(password) ⇒ Object
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/reedb/reevault.rb', line 186 def load(password) unless self.includes?('config') raise VaultDoesNotExistError.new("Loading vault failed because it couldn't be found at the specified path!") end init_logger(false) # Check if the config needs to be read via ASCII64 or YAML if self.includes?('pom') # Config is stored with ASCII Armour @config = read_secure_info('config') else @config = YAML.load_file("#{@path}/config") end return nil unless unlock_vault("#{password}") VaultLogger.write('Finished loading vault', 'debug') cache_headers return self end |
#locked? ⇒ Boolean
Little helper method to determine if a vault is in the middle of a write cycle. Which would cause horrible crashes on other applications and errors on the file system if things are moved around inside
120 121 122 |
# File 'lib/reedb/reevault.rb', line 120 def locked?; @locked end |
#read_file(name, history = false) ⇒ Object
Read a single file from the vault in secure mode Returns the entire file or only it’s current set in hashes.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/reedb/reevault.rb', line 211 def read_file(name, history = false) # Loads the file data into a local variable if it exists file_data = load_file_data(name) if file_data == nil raise FileNotFoundError.new("#{name} could not be read: File not found!") # return VAULT_FILE_NOT_FOUND_ERROR # If the exception isn't handled correctly else # This code is executed if the file was found (thus data is in file_data) compiled = {} compiled['header'] = {} # Removes the latest version from the header because it is insignificant. file_data['header'].each do |key, value| compiled['header']["#{key}"] = value unless key == 'latest' end if history compiled['body'] = file_data['body'] else body_list = [] file_data['body'].each do |key, _| body_list << key end compiled['body'] = {} # Now sort the list of body versions body_list.heapsort! # Then compile the data together into one data hash body_list.each do |version| file_data['body']["#{version}"].each do |key, value| compiled['body']["#{key}"] = value end end end # Then return that hash. Huzza! return compiled end end |
#remove_file(name) ⇒ Object
290 291 292 293 294 295 296 297 298 |
# File 'lib/reedb/reevault.rb', line 290 def remove_file(name) path_to_file = load_file_hash(name) if path_to_file FileUtils.rm(path_to_file) VaultLogger.write("Removed file #{name} from vault.", 'debug') else raise FileNotFoundError.new("#{name} could not be removed: File not found!") end end |
#secure_config(boolean = true) ⇒ Object
83 84 85 86 |
# File 'lib/reedb/reevault.rb', line 83 def secure_config(boolean = true) @secure_config = boolean return self end |
#to_s ⇒ Object
371 372 373 |
# File 'lib/reedb/reevault.rb', line 371 def to_s return "Vault: #{@name}, Path: #{@path}, File count: #{@headers.length}" end |
#try? ⇒ Boolean
Pokes if a vault exists
101 102 103 |
# File 'lib/reedb/reevault.rb', line 101 def try? return self.includes?('config') end |
#unload(time) ⇒ Object
Dump headers and files from memory in times of inactivity for security reasons
349 350 351 352 353 354 |
# File 'lib/reedb/reevault.rb', line 349 def unload(time) remove_instance_variable(:@headers) @headers = {} VaultLogger.write("It has been #{time*60} minutes since the last interaction. Unloading vault contents for security reasons.", 'debug') end |
#update(name, data) ⇒ Object
Check the file API or the wiki to learn how this function works. This function is also used to delete fields from header space.
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/reedb/reevault.rb', line 257 def update(name, data) # Cache headers first to be sure we're up to date cache_headers # Raises exception and [returns] in case exception isn't properly being handled (raise FileBusyError.new, "File #{name} busy"; return) if @locks.include?(name) @locks << name if @headers.key?(name) # Creates file object from existing file object. df = DataFile.new(name, self, load_file_data(name, :secure)) df.insertv2(data, :hard) # Default cache mode else df = DataFile.new(name, self) df.insertv2(data, :hard) # Default cache mode end # => Make sure that everything is up to date. cache_headers @config['updating_user'] = "#{Etc.getlogin}" @config['updating_machine'] = "#{Socket.gethostname}" @config['last_updated'] = "#{Utilities.get_time}" @config['last_version'] = "#{Reedb::VERSION}" save_config # Sync and close the file. df.sync.close # Unlocks the file again for other processes to edit. @locks.delete(name) end |