reedb 0.10.rc1 → 0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,129 @@
1
+ # ====================================================
2
+ # Copyright 2015 Lonely Robot (see @author)
3
+ # @author: Katharina Sabel | www.lonelyrobot.io
4
+ #
5
+ # Distributed under the GNU Lesser GPL Version 3
6
+ # (See accompanying LICENSE file or get a copy at
7
+ # https://www.gnu.org/licenses/lgpl.html)
8
+ # ====================================================
9
+
10
+ '' '
11
+ This file contains the debounce handler for the daemon.
12
+ That means that it is handed vault information and woken up every time there is an action
13
+ on a specified vault which makes it "debounce" back to the start of the counter.
14
+ ' ''
15
+
16
+ require_relative 'constants'
17
+
18
+ DRES = 0xEEE
19
+ VREM = 0xFFF
20
+ VINS = 0x000
21
+
22
+ module Reedb
23
+ class Debouncer
24
+
25
+ attr_accessor :running
26
+
27
+ #
28
+ # @param core [Object] the owning container instance to
29
+ # register the debounce close of a vault
30
+ # @return self
31
+ #
32
+ def initialize(core)
33
+ @reedb = core
34
+ @running = true
35
+
36
+ # Vault management
37
+ @delta_vaults = {}
38
+ @vaults = {}
39
+ @token_set = {}
40
+ @timeout = Reedb::KEY_CACHE_TIME
41
+ end
42
+
43
+ def set_custom_timeout(time)
44
+ @timeout = time
45
+ end
46
+
47
+ # The main loop to run in a thread
48
+ def main
49
+ last = Time.new
50
+ while @running
51
+ # Update the delta time
52
+ tmp = Time.new; r_delta = tmp - last
53
+
54
+ # Work through the delta_vaults file to check what info needs to change
55
+ @delta_vaults.each do |uuid, data|
56
+
57
+ # Make sure that the vault set is current
58
+ if data == VINS
59
+ @vaults[uuid] = @timeout
60
+ elsif data == VREM
61
+ @vaults.delete(uuid)
62
+ elsif data == DRES
63
+ @vaults[uuid] = @timeout
64
+ end
65
+ end
66
+
67
+ # Then reset it for the next delta
68
+ @delta_vaults = {}
69
+
70
+ # Now actually iterate through the vaults and subtract delta time
71
+ @vaults.each do |uuid, data|
72
+
73
+ # Subtract real delta time from timeset
74
+ @vaults[uuid] = data - r_delta
75
+
76
+ # Then check if that vault needs to be closed
77
+ if @vaults[uuid] <= 0
78
+ Reedb::Vault::close_vault(uuid, @token_set[uuid])
79
+ end
80
+ end
81
+
82
+ last = tmp # Update last time and then sleep
83
+ sleep(Reedb::DEBOUNCE_DELTA)
84
+ end
85
+ # puts 'I can feel my mind going, Dave'
86
+ end
87
+
88
+ # Updates the vault instances every time the vault set changes. Only changes values
89
+ # for vaults that change and attempts to leave old vaults unchanged.
90
+ #
91
+ # @param [String] uuid of a vault for identification
92
+ # @param [String] token as a Base64 encoded string
93
+ #
94
+ # @return Boolean to indicate whether there was already a token for this vault
95
+ #
96
+ def add_vault(uuid, token)
97
+ if @vaults.include?(uuid)
98
+
99
+ # Marks the vault to debounce because it was just interacted with but already in scope
100
+ @delta_vaults[uuid] = DRES
101
+ return false
102
+ else
103
+ @delta_vaults[uuid] = VINS
104
+ @token_set[uuid] = token
105
+ return true
106
+ end
107
+ end
108
+
109
+ def remove_vault(uuid)
110
+ @delta_vaults[uuid] = VREM
111
+ @token_set.delete(uuid)
112
+ end
113
+
114
+ # This is called every time an action is performed on a vault.
115
+ def debounce_vault(vault_id)
116
+ @delta_vaults[vault_id] = DRES
117
+ end
118
+
119
+ # Some utility and helper functions to plug into the Reedb main interface
120
+ def knows_vault(uuid)
121
+ return @vaults.include?(uuid)
122
+ end
123
+
124
+ def get_token(uuid)
125
+ return @token_set[uuid]
126
+ end
127
+
128
+ end
129
+ end
@@ -12,15 +12,18 @@
12
12
  class DaemonError < StandardError
13
13
  end
14
14
 
15
+ # These are scoping errors
15
16
  class VaultAlreadyScopedError < DaemonError
16
17
  end
17
18
 
18
19
  class VaultNotScopedError < DaemonError
19
20
  end
20
21
 
22
+ # Not knowing a vault
21
23
  class VaultNotAvailableError < DaemonError
22
24
  end
23
25
 
26
+ # Token errors
24
27
  class UnknownTokenError < DaemonError
25
28
  end
26
29
 
@@ -28,7 +31,4 @@ class UnautherisedTokenError < DaemonError
28
31
  end
29
32
 
30
33
  class MissingTokenError < DaemonError
31
- end
32
-
33
- class FunctionNotImplementedError < DaemonError
34
- end
34
+ end
@@ -0,0 +1,12 @@
1
+ module Reedb
2
+
3
+ # Exit codes to be used throughout the API
4
+ EXIT_STILL_LOCKED = 0x10
5
+ EXIT_OS_PARSE = 0x11
6
+
7
+ # Severe panic codes
8
+ EXIT_PANIC_INTERUPT = 0x31
9
+ EXIT_MISSING_USER_CODE = 0x32
10
+ EXIT_CORRUPT_FS = 0x33
11
+ EXIT_HTTP_MALFUNCT = 0x34
12
+ end
@@ -0,0 +1,21 @@
1
+ # ====================================================
2
+ # Copyright 2015 Random Robot Softworks (see @author)
3
+ # @author: Katharina Sabel | www.lonelyrobot.io
4
+ #
5
+ # Distributed under the GNU Lesser GPL Version 3
6
+ # (See accompanying LICENSE file or get a copy at
7
+ # https://www.gnu.org/licenses/lgpl.html)
8
+ # ====================================================
9
+
10
+ # Some errors code that are too generic to go into either of the categories.
11
+ # They just apply to EVERYTHING!
12
+
13
+ class ReedbError < StandardError
14
+ end
15
+
16
+ # General Error
17
+ class FunctionNotImplementedError < ReedbError
18
+ end
19
+
20
+ class UnknownOSError < ReedbError
21
+ end
@@ -19,21 +19,23 @@ end
19
19
  class VaultWritePermissionsError < VaultError
20
20
  end
21
21
 
22
+ # I/O error or fucked?
22
23
  class VaultMissingConfigurationError < VaultError
23
24
  end
24
25
 
25
- class VaultLoggerError < VaultError
26
+ class FileNotFoundError < VaultError
26
27
  end
27
28
 
28
- # This has been depreciated.
29
- class BadCacheError < VaultError
29
+ class FileBusyError < VaultError
30
30
  end
31
31
 
32
- class FileNotFoundError < VaultError
32
+ class MalformedSearchError < VaultError
33
33
  end
34
34
 
35
- class FileBusyError < VaultError
35
+ # This one is VERY hypothetical
36
+ class VaultLoggerError < VaultError
36
37
  end
37
38
 
38
- class MalformedSearchError < VaultError
39
+ # This has been depreciated.
40
+ class BadCacheError < VaultError
39
41
  end
@@ -54,9 +54,9 @@ module Reedb
54
54
  # Constructor for a vault with name, path and encryption enum.
55
55
  # Valid encryption parameters are :aes, :twofish, :multi and :auto_fill
56
56
  #
57
- def initialize(name, path, encprytion)
57
+ def initialize(name, path, encprytion, header_override = nil)
58
58
  @already_logging = false
59
-
59
+
60
60
  # Header maps
61
61
  @headers = {}
62
62
  @hgroups = {}
@@ -66,13 +66,16 @@ module Reedb
66
66
  @locks = []
67
67
 
68
68
  # Defines the default (and boring vanilla) header set
69
- @header_set = {
70
- 'urls'=>'list',
71
- 'tags'=>'list'
72
- }
69
+ # TODO: Get the header set via config and init that instead!
70
+ @header_set = header_override ? header_override : { 'urls' => 'list', 'tags' => 'list' }
73
71
 
72
+ # Make the path available as an object variable
74
73
  construct_path("#{name}", "#{path}")
75
- init_encryption(encprytion) # => Throws exceptions!
74
+
75
+ # Init ecnryption module. So @crypt must not be nil after this
76
+ init_encryption(encprytion)
77
+
78
+ # Setup the secure config to false by default. Change this?
76
79
  self.secure_config(false)
77
80
  return self
78
81
  end
@@ -114,7 +117,9 @@ module Reedb
114
117
  # a write cycle. Which would cause horrible crashes on other applications
115
118
  # and errors on the file system if things are moved around inside
116
119
  #
117
- def locked?() return @locked end
120
+ def locked?;
121
+ @locked
122
+ end
118
123
 
119
124
  def create(password = :failed)
120
125
  # If keygen was used to set a user password then fetch it
@@ -123,7 +128,7 @@ module Reedb
123
128
  return nil unless encryption?(password)
124
129
 
125
130
  # puts "This is the password: #{password}"
126
-
131
+
127
132
  # => Encryption now active and key available under @crypt.key
128
133
  @conf_path = "#{@path}/config"
129
134
 
@@ -131,22 +136,17 @@ module Reedb
131
136
 
132
137
  if self.includes?('config')
133
138
  raise VaultExistsAtLocationError.new, "Vault already exists at location #{@path}. Aborting operation..."
134
-
139
+
135
140
  # => This rules out lots of code to be run
136
141
  needs_creation = false
137
142
  else
138
- if Reedb::archos == :linux || Reedb::archos == :osx
139
- FileUtils::mkdir_p(File.expand_path("#{@path}/data")) # => Data dir
140
- FileUtils::mkdir(File.expand_path("#{@path}/shasums")) # => Checksum dir
141
- FileUtils::mkdir(File.expand_path("#{@path}/logs")) # => Logs dir
143
+ FileUtils::mkdir_p(File.expand_path("#{@path}/data")) # => Data dir
144
+ FileUtils::mkdir(File.expand_path("#{@path}/shasums")) # => Checksum dir
145
+ FileUtils::mkdir(File.expand_path("#{@path}/logs")) # => Logs dir
142
146
 
147
+ # On *nix devices change permissions.
148
+ if Reedb::archos == :linux || Reedb::archos == :osx || Reedb::archos == :vars
143
149
  FileUtils::chmod_R(0744, "#{@path}")
144
-
145
- # This is used for windows because windows fucking sucks!
146
- else
147
- FileUtils::mkdir_p(File.expand_path("#{@path}/data")) # => Data dir
148
- FileUtils::mkdir(File.expand_path("#{@path}/shasums")) # => Checksum dir
149
- FileUtils::mkdir(File.expand_path("#{@path}/logs")) # => Logs dir
150
150
  end
151
151
  end
152
152
 
@@ -167,15 +167,20 @@ module Reedb
167
167
  @config['updating_machine'] = "#{Socket.gethostname}"
168
168
  @config['creation_user'] = "#{Etc.getlogin}"
169
169
  @config['updating_user'] = "#{Etc.getlogin}"
170
- @config['header_set'] = "#{@header_set}"
170
+
171
+ # Convert the header set to JSON, then write it into the config
172
+ hset = JSON.dump(@header_set)
173
+ @config['header_set'] = "#{hset}"
174
+
175
+ # Add the Reedb version this vault was created with for upgradability
171
176
  @config['creation_version'] = "#{Reedb::VERSION}"
172
177
  save_config
173
-
178
+
174
179
  # Now writing encrypted key to file with ASCII armour
175
- update_secure_info("cey", @encrypted_key)
180
+ update_secure_info('cey', @encrypted_key)
176
181
  # remove_instance_variable(:@encrypted_key)
177
182
  end
178
- self.load("#{password}")
183
+ self.load(password)
179
184
  end
180
185
 
181
186
  def load(password)
@@ -192,10 +197,9 @@ module Reedb
192
197
  @config = YAML.load_file("#{@path}/config")
193
198
  end
194
199
 
195
-
196
200
 
197
201
  return nil unless unlock_vault("#{password}")
198
- VaultLogger.write("Finished loading vault", 'debug')
202
+ VaultLogger.write('Finished loading vault', 'debug')
199
203
  cache_headers
200
204
 
201
205
  return self
@@ -207,10 +211,10 @@ module Reedb
207
211
  def read_file(name, history = false)
208
212
 
209
213
  # Loads the file data into a local variable if it exists
210
- file_data = load_file_data(name)
214
+ file_data = load_file_data(name)
211
215
  if file_data == nil
212
216
  raise FileNotFoundError.new("#{name} could not be read: File not found!")
213
- return VAULT_FILE_NOT_FOUND_ERROR # If the exception isn't handled correctly
217
+ # return VAULT_FILE_NOT_FOUND_ERROR # If the exception isn't handled correctly
214
218
  else
215
219
  # This code is executed if the file was found (thus data is in file_data)
216
220
  compiled = {}
@@ -218,14 +222,14 @@ module Reedb
218
222
 
219
223
  # Removes the latest version from the header because it is insignificant.
220
224
  file_data['header'].each do |key, value|
221
- compiled['header']["#{key}"] = value unless key == "latest"
225
+ compiled['header']["#{key}"] = value unless key == 'latest'
222
226
  end
223
227
 
224
228
  if history
225
229
  compiled['body'] = file_data['body']
226
230
  else
227
231
  body_list = []
228
- file_data['body'].each do |key, value|
232
+ file_data['body'].each do |key, _|
229
233
  body_list << key
230
234
  end
231
235
 
@@ -233,14 +237,16 @@ module Reedb
233
237
 
234
238
  # Now sort the list of body versions
235
239
  body_list.heapsort!
240
+
241
+ # Then compile the data together into one data hash
236
242
  body_list.each do |version|
237
243
  file_data['body']["#{version}"].each do |key, value|
238
244
  compiled['body']["#{key}"] = value
239
245
  end
240
246
  end
241
247
  end
242
-
243
- # Then return that value
248
+
249
+ # Then return that hash. Huzza!
244
250
  return compiled
245
251
  end
246
252
  end
@@ -249,9 +255,12 @@ module Reedb
249
255
  # This function is also used to delete fields from header space.
250
256
  #
251
257
  def update(name, data)
252
- cache_headers # Cache headers first to be sure
253
258
 
254
- (raise FileBusyError.new, "File #{name} busy" ; return) if @locks.include?(name)
259
+ # Cache headers first to be sure we're up to date
260
+ cache_headers
261
+
262
+ # Raises exception and [returns] in case exception isn't properly being handled
263
+ (raise FileBusyError.new, "File #{name} busy"; return) if @locks.include?(name)
255
264
  @locks << name
256
265
 
257
266
  if @headers.key?(name)
@@ -278,11 +287,10 @@ module Reedb
278
287
  @locks.delete(name)
279
288
  end
280
289
 
281
- def remove_file name
290
+ def remove_file(name)
282
291
  path_to_file = load_file_hash(name)
283
292
  if path_to_file
284
293
  FileUtils.rm(path_to_file)
285
- puts "Successfullly removed file #{name}"
286
294
  VaultLogger.write("Removed file #{name} from vault.", 'debug')
287
295
  else
288
296
  raise FileNotFoundError.new("#{name} could not be removed: File not found!")
@@ -311,9 +319,10 @@ module Reedb
311
319
  slice = target.split('=')
312
320
  query["#{slice[0]}"] = slice[1..-1]
313
321
  end
314
- # puts query
322
+
323
+ # Rescue the query in case it was bad
315
324
  rescue
316
- raise MalformedSearchError.new, "Malformed search data"
325
+ raise MalformedSearchError.new, 'Malformed search data'
317
326
  end
318
327
 
319
328
  log_query = {}
@@ -322,7 +331,7 @@ module Reedb
322
331
  query.each do |cat, data|
323
332
  data.each do |val|
324
333
  log_query["#{cat}"] = @hgroups["#{cat}"]["#{val}"] if @hgroups["#{cat}"].include?(val)
325
- log_query["#{cat}"].each { |c| candidates << c unless candidates.include?(c) }
334
+ log_query["#{cat}"].each { |c| candidates << c unless candidates.include?(c) }
326
335
  end
327
336
  end
328
337
  return_buffer = candidates
@@ -337,16 +346,17 @@ module Reedb
337
346
 
338
347
  # Dump headers and files from memory in times of
339
348
  # inactivity for security reasons
340
- def unload
349
+ def unload(time)
341
350
  remove_instance_variable(:@headers)
342
351
  @headers = {}
343
352
 
344
- VaultLogger.write("It has been $TIME since the last interaction. Unloading vault contents for security reasons.", 'debug')
353
+ VaultLogger.write("It has been #{time*60} minutes since the last interaction. Unloading vault contents for security reasons.", 'debug')
345
354
  end
346
355
 
347
356
  def close
348
- VaultLogger.write("Scheduled closing of the vault.", 'debug')
349
- @crypt.stop_encryption if @crypt.init
357
+ VaultLogger.write('Force closing the vault. Check parent logs for details', 'debug')
358
+ # puts "Crypto module is: #{@crypt}"
359
+ @crypt.stop_encryption if @crypt && @crypt.init
350
360
 
351
361
  # Removing class variables for cleanup
352
362
  remove_instance_variable(:@crypt)
@@ -354,7 +364,7 @@ module Reedb
354
364
  end
355
365
 
356
366
  # Quickly returns if a file exists in the vault or it's children.
357
- def includes? file
367
+ def includes?(file)
358
368
  return File.exists?("#{@path}/#{file}")
359
369
  end
360
370
 
@@ -369,24 +379,25 @@ module Reedb
369
379
  def cache_headers
370
380
  @headers = {}
371
381
 
372
- VaultLogger.write("Starting a cache cycle.", 'debug')
382
+ VaultLogger.write('Starting a cache cycle.', 'debug')
373
383
 
374
384
  Dir.glob("#{@path}/data/*.ree") do |file|
375
385
  f = File.open(file, 'r')
376
386
  encrypted = Base64.decode64(f.read)
377
387
  decrypted = @crypt.decrypt(encrypted)
378
388
 
379
- data = JSON.parse(decrypted)
380
- df = DataFile.new(nil, self, data)
389
+ raw = JSON.parse(decrypted)
390
+ df = DataFile.new(nil, self, raw)
381
391
 
382
392
  tmp_head = df.cache(:header)
383
393
  tmp_name = df.name
384
394
 
385
395
  # Blank the df variable just in case.
386
- df = 0x111111111111111
387
-
388
- @headers[tmp_name] = tmp_head
389
-
396
+ df = 0xEFFFFFFFFFFFFFFF
397
+ # remove_instance_variable(df)
398
+
399
+ @headers[tmp_name] = tmp_head
400
+
390
401
  # Now work with the header set to determine sub-groups
391
402
  tmp_head.each do |category, data|
392
403
 
@@ -450,10 +461,10 @@ module Reedb
450
461
  if @secure_config
451
462
  update_secure_info('config', @config)
452
463
  par_path = "#{@path}/pom"
453
- msg = "Why are you reading this?"
454
- File.open("#{par_path}", "wb").write(Base64.encode64("#{msg}"))
464
+ msg = 'Polarbears are left handed. Spread the word!'
465
+ File.open("#{par_path}", 'wb').write(Base64.encode64("#{msg}"))
455
466
  else
456
- File.open("#{@conf_path}", "wb+"){ |f| YAML.dump(@config, f) }
467
+ File.open("#{@conf_path}", 'wb+') { |f| YAML.dump(@config, f) }
457
468
  end
458
469
  end
459
470
 
@@ -461,24 +472,26 @@ module Reedb
461
472
  # additional slashes from the end.
462
473
  #
463
474
  def construct_path(name, path)
464
- (@name = name ; @path = "")
465
- path.end_with?("/") ? @path = "#{path}#{name}.reevault" : @path = "#{path}/#{name}.reevault"
475
+ (@name = name; @path = '')
476
+ path.end_with?('/') ? @path = "#{path}#{name}.reevault" : @path = "#{path}/#{name}.reevault"
466
477
  end
467
478
 
468
479
  def update_secure_info(name, data = nil)
469
480
  path = "#{@path}/#{name}"
470
- File.open(path, "wb").write(Base64.encode64("#{data}"))
481
+ File.write(path, Base64.encode64(data))
482
+ # File.open(path, 'wb+').write(Base64.encode64(data))
471
483
  end
472
484
 
473
- def read_secure_info name
485
+ def read_secure_info(name)
474
486
  path = "#{@path}/#{name}"
475
- return Base64.decode64(File.open(path, "r").read())
487
+ return Base64.decode64(File.read(path))
488
+ # return Base64.decode64(File.open(path, 'r').read())
476
489
  end
477
490
 
478
- def init_logger bool
491
+ def init_logger(bool)
479
492
  begin
480
493
  unless logger?(bool)
481
- raise VaultLoggerError.new, "Logger failed to be initialised"
494
+ raise VaultLoggerError.new, 'Logger failed to be initialised'
482
495
  end
483
496
  rescue VaultError => e
484
497
  puts e.message
@@ -489,18 +502,16 @@ module Reedb
489
502
  (return false) if @already_logging && bool
490
503
 
491
504
  VaultLogger.setup("#{@path}")
492
- (@already_logging = true ; return true)
505
+ (@already_logging = true; return true)
493
506
  end
494
507
 
495
- def password? password
496
- raise MissingUserPasswordError.new, "Encryption error: Missing user password!" if password == nil
497
-
498
- raise InsecureUserPasswordError.new, "Encryption error: Password too short! See: https://xkcd.com/936/" if password.length < Reedb::passlength
499
-
508
+ def password?(password)
509
+ raise MissingUserPasswordError.new, 'Encryption error: Missing user password!' if password == nil
510
+ raise InsecureUserPasswordError.new, 'Encryption error: Password too short! See: https://xkcd.com/936/' if password.length < Reedb::passlength
500
511
  return true
501
512
  end
502
513
 
503
- def encryption? password
514
+ def encryption?(password)
504
515
  begin
505
516
  @encrypted_key = @crypt.start_encryption(password)
506
517
  rescue EncryptionError => e
@@ -513,13 +524,14 @@ module Reedb
513
524
  # Unlocks the vault by decrypting the key and loading it into memory
514
525
  # Enables the cryptographic module to decrypt and encrypt files.
515
526
  #
516
- def unlock_vault pw
527
+ def unlock_vault(pw)
517
528
  begin
518
529
  @encrypted_key = read_secure_info('cey') unless @encrypted_key
519
530
  @crypt.start_encryption(pw, @encrypted_key)
520
531
  remove_instance_variable(:@encrypted_key) if @encrypted_key
521
- rescue #TODO: Check exception type here.
522
- raise WrongUserPasswordError.new, "Incorrect user passphrase. Could not unlock!"
532
+ rescue Exception => e
533
+ puts e.class # TODO: This finds out the class of the exception next time it is encountered c:
534
+ raise WrongUserPasswordError.new, 'Incorrect user passphrase. Could not unlock!'
523
535
  end
524
536
 
525
537
  # Return values for the rest of the file.
@@ -542,6 +554,6 @@ module Reedb
542
554
  raise MissingEncryptionTypeError.new, "Encryption failed: Missing type. Aborting..."
543
555
  end
544
556
  end
545
-
557
+
546
558
  end # class close
547
559
  end # module close
@@ -42,11 +42,7 @@ module Reedb
42
42
  # Used to hash file-names in vaults
43
43
  #
44
44
  def self.tiger_hash(string)
45
- if Reedb::verbose?
46
- DaemonLogger.write("[FIX ME]: t_hash is a broken function!", "warn")
47
- end
48
- return self.sha512_hash("#{string}")
49
- # Digest::Tiger.hexdigest("#{string}")
45
+ return Digest::Tiger.hexdigest("#{string}")
50
46
  end
51
47
 
52
48
  # => Returns 64 byte sha hash.
@@ -0,0 +1,21 @@
1
+ # ====================================================
2
+ # Copyright 2015 Lonely Robot (see @author)
3
+ # @author: Katharina Sabel | www.2rsoftworks.de
4
+ #
5
+ # Distributed under the GNU Lesser GPL Version 3
6
+ # (See accompanying LICENSE file or get a copy at
7
+ # https://www.gnu.org/licenses/lgpl.html)
8
+ # ====================================================
9
+
10
+ module Reedb
11
+
12
+ # Class that can generate tokens for any occasion that are
13
+ # cryptographically more secure.
14
+ #
15
+ class TokenFactory
16
+
17
+ def initialize params
18
+ # Constructor stub
19
+ end
20
+ end
21
+ end
@@ -36,17 +36,17 @@ module Reedb
36
36
  # 'warn':: Logs a warning. Should be event that won't impact stability.
37
37
  # 'error':: Logs an error. Should be recoverable event.
38
38
  # 'fatal':: Logs a fatal crash. Should make the Reepass daemon crash!
39
- def self.write(message, level = "")
40
- if level == "warn"
39
+ def self.write(message, level = '')
40
+ if level == 'warn'
41
41
  @@logger.warn(message)
42
42
 
43
- elsif level == "debug"
43
+ elsif level == 'debug'
44
44
  @@logger.debug(message)
45
45
 
46
- elsif level == "error"
46
+ elsif level == 'error'
47
47
  @@logger.error(message)
48
48
 
49
- elsif level == "fatal"
49
+ elsif level == 'fatal'
50
50
  @@logger.fatal(message)
51
51
 
52
52
  else