reedb 0.10.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 11820940b0e80cda5ea4e0ab59fb2dd4b5a06189
4
+ data.tar.gz: f6ed0c7e514bfebb4b25750e7583dbb2fdc2c0c9
5
+ SHA512:
6
+ metadata.gz: 1c960ebf6cf718de201067246c8eb13fecd43c40f23482d2e6d594ae5229ed42ec2fc2f3642ef4c26f89d8d26401d570d31bbc1388fc8138395f0b4c044a7d7f
7
+ data.tar.gz: 2f0ecd887ad56e8bc3a04c84b2a8e5bf97ba37d4cb69980a573e19d5c33c595867a58c3146a1d61b81fd61f624a208cb851956ad08d3072bbb3cb6cee8628f31
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ reedb
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.1.5
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in reedb.gemspec
4
+ gemspec
5
+
6
+ # Security!
7
+ gem 'aes', '>=0.5.0'
8
+ gem 'twofish', '>=1.0.5'
9
+ gem 'digest-tiger', '~> 1.0.2'
10
+
11
+ # Other stuff that's important
12
+ gem 'json', '~> 1.8.2'
13
+ gem 'daemons', '~> 1.2.2'
14
+ gem 'sinatra', '~> 1.4.6'
15
+ gem 'hashids', '~> 1.0.2'
data/Gemfile.lock ADDED
@@ -0,0 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ reedb (0.9.9.pre.RC1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ aes (0.5.0)
10
+ daemons (1.2.2)
11
+ digest-tiger (1.0.2)
12
+ hashids (1.0.2)
13
+ json (1.8.2)
14
+ rack (1.6.1)
15
+ rack-protection (1.5.3)
16
+ rack
17
+ rake (10.4.2)
18
+ sinatra (1.4.6)
19
+ rack (~> 1.4)
20
+ rack-protection (~> 1.4)
21
+ tilt (>= 1.3, < 3)
22
+ tilt (2.0.1)
23
+ twofish (1.0.5)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ aes (>= 0.5.0)
30
+ bundler (~> 1.7)
31
+ daemons (~> 1.2.2)
32
+ digest-tiger (~> 1.0.2)
33
+ hashids (~> 1.0.2)
34
+ json (~> 1.8.2)
35
+ rake (~> 10.0)
36
+ reedb!
37
+ sinatra (~> 1.4.6)
38
+ twofish (>= 1.0.5)
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/reedbd ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # ====================================================
4
+ # Copyright 2015 Lonely Robot (see @author)
5
+ # @author: Katharina Sabel | www.2rsoftworks.de
6
+ #
7
+ # Distributed under the GNU Lesser GPL Version 3
8
+ # (See accompanying LICENSE file or get a copy at
9
+ # https://www.gnu.org/licenses/lgpl.html)
10
+ # ====================================================
11
+
12
+
13
+ # Very simple wrapper script to start the Reedb daemon.
14
+ require 'reedb/constants'
15
+
16
+ NAME = 'reedbd'
17
+
18
+ if File.basename(__FILE__) == NAME
19
+ if ARGV.include? '--version'
20
+ puts Reedb::VERSION
21
+ exit
22
+ end
23
+
24
+ if ARGV == []
25
+ puts "[ERROR]: Invalid application arguments!"
26
+ puts "Usage: reedb [daemon options] -- [reedb options]
27
+
28
+ Available [reedb options]:
29
+ -l, --pw-length INTEGER Define minimal passphrase length (Default: 12)
30
+ -p, --port INTEGER Change the listener port. May break your setup!
31
+ -a, --app-path STRING Change the path for the reedb config files/ logs. (default in ~)
32
+ -v, --verbose Enable verbose logging about the Reedb daemon.
33
+ -d, --no-daemon Don't run Reedb as a background daemon. Log to STOUT instead of log file.
34
+
35
+ Available [daemon options]:
36
+ start Start an instance of the #{NAME} daemon
37
+ stop Stop all instances of the #{NAME} daemon
38
+ restart Stop all and restart a new instance of #{NAME} afterwards
39
+ status Show status (PID) of #{NAME} daemon instance
40
+
41
+ Common options:
42
+ --version Show #{NAME} version"
43
+
44
+ # Then exits the application
45
+ exit
46
+ end
47
+
48
+ options = {
49
+ :app_name => "reedb",
50
+ :backtrace => true,
51
+ # :monitor => true,
52
+ # :ontop => true
53
+ }
54
+
55
+ spec = Gem::Specification.find_by_name("reedb")
56
+ (puts "Error: reedb not installed!" ; exit) unless spec
57
+ path = (spec.gem_dir) + "/lib/reedb"
58
+
59
+ require 'daemons'
60
+ require 'reedb'
61
+ Daemons.run(File.join(path, 'daemon_wrapper.rb'), options)
62
+ end
data/lib/reedb.rb ADDED
@@ -0,0 +1,739 @@
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
+ # Internal requirements
11
+ require_relative 'reedb/errors/daemon_errors'
12
+
13
+ require_relative 'reedb/utils/meta_vault'
14
+ require_relative 'reedb/utils/utilities'
15
+ require_relative 'reedb/utils/logger'
16
+ require_relative 'reedb/utils/uuids'
17
+
18
+ require_relative 'reedb/constants'
19
+ require_relative 'reedb/reevault'
20
+
21
+
22
+ # System requirements
23
+ require 'securerandom'
24
+
25
+ module Reedb
26
+ class << self
27
+ # Returns the platform/ architecture of the daemon and vault handler
28
+
29
+ def archos() (return @@archos) end
30
+
31
+ # Returns whether or not this is a daemon
32
+ def daemon?() (return @@daemon) end
33
+
34
+ # Returns the minimum passphrase length is
35
+ def passlength() (return @@pw_length) end
36
+
37
+ # Returns whether verbose mode is enabled
38
+ def verbose?() (return @@verbose) end
39
+ end
40
+
41
+
42
+ def self.included(api)
43
+ class << api
44
+
45
+ @@counter = 0
46
+ @@started = false
47
+
48
+ # Some more runtime variables
49
+ @@path = Reedb::DEF_MASTER_PATH
50
+ @@config_path = Reedb::DEF_MASTER_PATH
51
+ @@no_token = false
52
+ @@verbose = false
53
+ @@pw_length = -1
54
+ @@cleanup = true
55
+ @@daemon = true
56
+ @@archos = nil
57
+
58
+ # Stores the active vaults
59
+ @@active_vaults = {}
60
+
61
+ # Stores the active tokens
62
+ @@tokens = {}
63
+
64
+ # Stores the master configuration
65
+ @@config = nil
66
+
67
+ # PRIVATE FUNCTIONS BELOW
68
+ private
69
+
70
+ # Generates an authentication token for vault access.
71
+ # The function also adds the token, bound to the vault name, to the
72
+ # @@tokens set.
73
+ #
74
+ # Params: 'name' of the vault
75
+ # 'path' of the vault
76
+ #
77
+ # => Base64 encoded token
78
+ #
79
+ def generate_token(uuid, path)
80
+ # Concatinates the token together and base64 encodes it
81
+ token = Base64.encode64("#{SecureRandom.base64(Reedb::TOKEN_BYTE_SIZE)}--#{uuid}--#{SecureRandom.base64(Reedb::TOKEN_BYTE_SIZE)}--#{path}--#{SecureRandom.base64(Reedb::TOKEN_BYTE_SIZE)}")
82
+ token.delete!("\n")
83
+ @@tokens[token] = [] unless @@tokens.include?(token)
84
+ @@tokens[token] << uuid
85
+ update_tracked_vault("#{uuid}", nil, nil, nil, token)
86
+ return token
87
+ end
88
+
89
+ # Writes a vault into a tracking file for the user
90
+ # That means that the vault will be tracked next time
91
+ # Reedb starts
92
+ #
93
+ # Params: name => Public vault name
94
+ # path => Location on the system
95
+ # tokens => Authentication token for applications
96
+ #
97
+ def track_vault(name, path, size, uuid)
98
+ @@config[:vaults]["#{uuid}"] = {} unless @@config[:vaults].include?(uuid)
99
+
100
+ # Adds actual size as soon as the vault gets unlocked by an application
101
+ @@config[:vaults]["#{uuid}"][:meta] = MetaVault.new("#{name}", "#{path}", size, "#{uuid}")
102
+ @@config[:vaults]["#{uuid}"][:tokens] = [] unless @@config[:vaults]["#{uuid}"][:tokens]
103
+ @@config[:vaults]["#{uuid}"][:tokens] = []
104
+
105
+ write_config
106
+ end
107
+
108
+ def untrack_vault uuid
109
+ @@config[:vaults]["#{uuid}"] = nil if @@config[:vaults].include?(uuid)
110
+ end
111
+
112
+ def update_tracked_vault(uuid, name, path, size, token)
113
+ token.delete!("\n")
114
+ return nil unless @@config[:vaults].include?(uuid)
115
+
116
+ @@config[:vaults]["#{uuid}"][:meta].name = name if name
117
+ @@config[:vaults]["#{uuid}"][:meta].path = path if path
118
+ @@config[:vaults]["#{uuid}"][:meta].size = size if size
119
+
120
+ @@config[:vaults]["#{uuid}"][:tokens] = [] unless @@config[:vaults]["#{uuid}"][:tokens]
121
+ @@config[:vaults]["#{uuid}"][:tokens] << token if token
122
+
123
+ write_config
124
+ end
125
+
126
+ # Removes a token from a vault config thus removing any access that token had.
127
+ #
128
+ def remove_token(uuid, token)
129
+ token.delete!("\n")
130
+ return nil unless @@config[:vaults].include?(uuid)
131
+ return nil unless @@config[:vaults]["#{uuid}"][:tokens].include?(token)
132
+
133
+ @@config[:vaults]["#{uuid}"][:tokens].delete(token)
134
+ write_config
135
+ end
136
+
137
+ # Caches the config file to @@config
138
+ #
139
+ #
140
+ def cache_config
141
+ # Now read vault information and put it into @@active_vaults field
142
+ if File.exist?("#{@@config_path}")
143
+ read_config
144
+ else
145
+ # Creates some dummy info
146
+ @@config = {}
147
+ @@config[:global] = {}
148
+ @@config[:global][:logs] = :default
149
+ @@config[:vaults] = {}
150
+
151
+ # Writes the config to file with Base64 encoding
152
+ write_config
153
+ FileUtils::chmod_R(0744, "#{@@config_path}")
154
+ end
155
+
156
+ check_vault_integreties if @@cleanup
157
+
158
+ # At this point @@config has been loaded
159
+ vault_count = @@config[:vaults].size
160
+ DaemonLogger.write("Found #{vault_count} vault(s) on the system.", "debug")
161
+ end
162
+
163
+ # Check vault integreties here!
164
+ # Will try every vault in the config and remove the ones that are no longer
165
+ # available to avoid errors and access corruptions
166
+ #
167
+ def check_vault_integreties
168
+ # Vaults that will be marked for removal
169
+ marked = []
170
+ @@config[:vaults].each do |uuid, data|
171
+ unless ReeVault.new(data[:meta].name, data[:meta].path, :auto).try?
172
+ marked << uuid
173
+ end
174
+ end
175
+
176
+ marked.each do |uuid|
177
+ # puts "Removing: #{uuid}"
178
+ DaemonLogger.write("Removing corrupted vault #{uuid}", 'warn')
179
+ @@config[:vaults].delete(uuid)
180
+ end
181
+ write_config
182
+ end
183
+
184
+ def write_config
185
+ data = Marshal.dump(@@config)
186
+ File.open(@@config_path, 'wb+') { |file| file.write(data) }
187
+ read_config
188
+ end
189
+
190
+ def read_config
191
+ data = File.open(@@config_path, "rb").read()
192
+ @@config = Marshal.load(data)
193
+ end
194
+ end
195
+ end
196
+
197
+ # Core submodule of the Interface stack
198
+ module Core
199
+ include Reedb
200
+
201
+ class << self
202
+
203
+ def init(options)
204
+ @@daemon = if options.include?(:daemon) then options[:daemon] else true end
205
+ @@archos = options[:os]
206
+ @@pw_length = options[:pw_length]
207
+ @@verbose = if options.include?(:verbose) then options[:verbose] else false end
208
+ @@no_token = if options.include?(:no_token) then options[:no_token] else false end
209
+
210
+ if @@no_token
211
+ puts "NO_TOKEN mode has not been implemented yet! Please just use token authentication mode."
212
+ @@no_token = false
213
+ end
214
+
215
+ @@path = if options.include?(:path) then options[:path] else "&&HOME&&" end
216
+
217
+ # Enable cleanup mode
218
+ # This means that the config will be cleaned and unused tokens removed
219
+ # instead of leaving them in the file and configurations.
220
+ # It is recommended to use cleanup mode.
221
+ #
222
+ @@cleanup = if options.include?(:cleanup) then options[:cleanup] else true end
223
+
224
+ # Set of vaults that map a VaultBuffer to the vault itself.
225
+ # Never exposed outside the API
226
+ #
227
+ @@active_vaults = {}
228
+
229
+ # List of tokens authorised for this daemon. Maps tokens to vault names.
230
+ # This is used for authentication and never exposed to the outside API
231
+ # NOTE! This is not used when the :no_token option is enabled
232
+ #
233
+ @@tokens = {} unless @@no_token
234
+
235
+ if @@archos == :linux
236
+ master_path = File.expand_path('~/.config/reedb/')
237
+
238
+ # Puts the folder in /etc if running as root
239
+ master_path = "/etc/reedb" if Utilities::parse_user == 'root'
240
+
241
+ log_path = File.expand_path('~/.config/reedb/logs/')
242
+ @@config_path = File.join("#{master_path}", "master.cfg")
243
+
244
+ elsif @@archos == :osx
245
+ master_path = File.expand_path('~/Library/Application\ Support/reedb/')
246
+ log_path = File.expand_path('~/Library/Application\ Support/reedb/logs/')
247
+ @@config_path = File.join("#{master_path}", "master.cfg")
248
+ else
249
+ # Windows crap
250
+ end
251
+
252
+ # Changing file permissions. Does this do ANYTHING on windows?
253
+ FileUtils::mkdir_p("#{log_path}") # 744 (owned by $USER)
254
+ FileUtils::chmod_R(0744, "#{log_path}")
255
+ FileUtils::chmod_R(0744, "#{master_path}")
256
+
257
+ Reedb::DaemonLogger.setup("#{log_path}")
258
+ @@started = true
259
+ Reedb::DaemonLogger.write("Reedb was started successfully. Reading vault information now...", 'debug')
260
+
261
+ # Now cache the config
262
+ cache_config
263
+
264
+ # Open debounce tread and mirror current vault information onto it.
265
+ # debounce_handler
266
+ end
267
+
268
+
269
+ def terminate(reason = nil)
270
+ puts "Must start process first" unless @@started
271
+
272
+ new_reason = "unknown reason"
273
+ new_reason = "a user request" if reason == "user"
274
+ new_reason = "a system request" if reason == "root"
275
+
276
+ # My first easter-egg. Yay! :)
277
+ new_reason = "the illuminati" if reason == "aliens"
278
+
279
+ DaemonLogger.write("[TERMINATION]: Scheduling termination because of #{new_reason}.")
280
+
281
+ # TODO: Close the debounce thread here.
282
+
283
+ @@started = false
284
+ # Closing open vaults here
285
+ counter = 0 ; @@active_vaults.each { |k, v| v.close; counter += 1 }
286
+ DaemonLogger.write("[TERMINATION]: Closed #{counter} vaults. Done!")
287
+ end
288
+ end
289
+ end
290
+
291
+ # Config submodule of the Interface stack
292
+ module Config
293
+ module Master
294
+ include Reedb
295
+ class << self
296
+
297
+ def dump_config
298
+ return @@config
299
+ end
300
+
301
+ # Set a global timeout time to all vaults. Determine when a vault will
302
+ # be unloaded or the daemon will lock itself.
303
+ # Time provided in seconds
304
+ #
305
+ def global_timeout dt
306
+ end
307
+
308
+ # Set the log state of the daemon. That determines what error calls will
309
+ # be logged and what will be ommited.
310
+ #
311
+ def logging_state state
312
+ end
313
+
314
+ # Define a minimal passphrase length for vaults to have. This can
315
+ # break access to vaults if they were created on a different system
316
+ # so be careful with this!
317
+ #
318
+ def passphrase_length length
319
+ end
320
+
321
+ # Cleans the config file of broken vaults and config items. This is
322
+ # being done by default when operating in cleanup mode.
323
+ #
324
+ def clean_config
325
+
326
+ end
327
+ end
328
+ end
329
+
330
+ module Vault
331
+ include Reedb
332
+ class << self
333
+ def set_vault_timeout dt
334
+ end
335
+
336
+ def add_header_field(field, type)
337
+ end
338
+
339
+ def change_passphrase(old_phrase, new_phrase)
340
+ end
341
+
342
+ def read_config
343
+ end
344
+ end
345
+ end
346
+ end
347
+
348
+ # Vault submodule of the Interface stack
349
+ module Vault
350
+ include Reedb
351
+
352
+ class << self
353
+
354
+ # Returns a list of all vaults tracked by Reedb (by the current user).
355
+ # Vaults are ordered in a dictionary under their UUID that's used by the
356
+ # Reedb daemon.
357
+ #
358
+ # => A compiled JSON of vaults with uuid, name, path and size
359
+ #
360
+ def available_vaults
361
+ available = {}
362
+
363
+ @@config[:vaults].each do |uuid, value|
364
+ # puts @@config[:vaults]["#{uuid}"]
365
+ available["#{uuid}"] = {}
366
+ available["#{uuid}"][:name] = value[:meta].name
367
+ available["#{uuid}"][:path] = value[:meta].path
368
+ available["#{uuid}"][:size] = value[:meta].size
369
+ end
370
+ return available
371
+ end
372
+
373
+ # Creates a new vault on the current system. Returns nil if vault already existed at
374
+ # location. Returns a token if the creation and authentication was successful on the
375
+ # user side.
376
+ # Also adds that token to the @@tokens list
377
+ #
378
+ # THROWS A LOT OF EXCEPTIONS!
379
+ #
380
+ #
381
+ # Params:
382
+ # 'name' of the vault
383
+ # 'path' of the vault
384
+ # user 'passphrase'
385
+ # 'encryption' method (:aes, :twofish, :auto)
386
+ #
387
+ # => Base64 encoded token | nil if errors occured.
388
+ #
389
+ def create_vault(name, path, passphrase, encryption = :auto)
390
+ # Creates new UUIDs until one is found that doesn't already exist in the scope
391
+ uuid = nil
392
+ loop do
393
+ uuid = UUID::create_v1
394
+ (break) unless @@config[:vaults].include?(uuid)
395
+ end
396
+
397
+ # Create actual Vault object
398
+ # This throws errors!
399
+ tmp_vault = ReeVault.new("#{name}", "#{path}", encryption).create("#{passphrase}")
400
+
401
+ # Creates a metavault with name, path, size and uuid to be tracked on the system
402
+ # metavault = MetaVault.new("#{name}", "#{path}", 0, "#{uuid}")
403
+
404
+ # Adds vault to the active set of vaults
405
+ @@active_vaults[uuid] = tmp_vault
406
+
407
+ # Generates a token
408
+ unless @@no_token
409
+ token = generate_token(uuid, path)
410
+ track_vault(name, path, 0, uuid)
411
+ return token.delete!("\n")
412
+ end
413
+
414
+ # In case token authentication was disabled
415
+ track_vault(uuid, nil)
416
+ return nil
417
+ end
418
+
419
+
420
+ # ONLY PERMITTED WHEN IN NO_TOKEN MODE! WILL BE DISABLED AUTOMATICALLY WHEN
421
+ # USING THE HTTP MODULE!
422
+ #
423
+ # Loads a vault with a UUID and passphrase into the current vault set.
424
+ # Ignores the token set (as not applicable when in token mode) and simply
425
+ # returns a confirmation that vault access was granted.
426
+ #
427
+ def access_vault(uuid, passphrase)
428
+ raise FunctionNotImplementedError.new, "This has not been implemented yet! Use token authentication via the DAEMON module."
429
+ return false
430
+ end
431
+
432
+
433
+ # Removes a vault from the file system. This requires special privileges
434
+ # to do via this interface to prevent deleting vaults without the users
435
+ # permission. Will also fire a user interrupt to alert them of this
436
+ # behaviour depending on platform.
437
+ #
438
+ # Params:
439
+ # 'uuid' of the vault
440
+ # 'passphrase' of the vault
441
+ # 'token' of an application that needs to be authorised
442
+ #
443
+ # => Returns boolean describing success
444
+ #
445
+ def remove_vault(uuid, passphrase, token)
446
+ token.delete!("\n")
447
+ # Returns false if that token isn't authorised
448
+ return false unless @@tokens[token].include?(uuid)
449
+
450
+ # Return false if vault has never been scoped before
451
+ return false unless @@config[:vaults].include?(uuid)
452
+
453
+ # Return false if vault is currently locked
454
+ return false if @@active_vaults[uuid].locked?
455
+
456
+ # Mark a vault for removal and only actually
457
+ raise FunctionNotImplementedError.new, "This has not been implemented yet! Don't do this."
458
+ return false
459
+ end
460
+
461
+ # Adds a new vault to the tracking scope of this Reedb daemon. Does not grant access
462
+ # or generate a new token for application interaction.
463
+ # On a new install usually called just before requesting a token
464
+ #
465
+ # Params: 'name' of the vault
466
+ # 'path' on the systen
467
+ #
468
+ def scope_vault(name, path)
469
+ # Checks if that specific vault was already scoped
470
+ @@config[:vaults].each do |key, value|
471
+ if value[:meta].name == "#{name}" && value[:meta].path == "#{path}"
472
+ DaemonLogger.write("Vault already scoped at #{path}", 'info')
473
+ raise VaultAlreadyScopedError.new, "Vault #{name} already scoped!"
474
+ return false
475
+ end
476
+ end
477
+ vault = ReeVault.new("#{name}", "#{path}", :auto)
478
+ # If it hasn't, proceed here
479
+ if vault.try?
480
+ uuid = nil
481
+ loop do
482
+ uuid = UUID::create_v1
483
+ (break) unless @@config[:vaults].include?(uuid)
484
+ end
485
+
486
+ # At this point a vault has been confirmed and a UUID generated
487
+ track_vault(name, path, vault.count, "#{uuid}")
488
+ DaemonLogger.write("Vault successfully scoped at #{path}", 'info')
489
+ cache_config
490
+ return true
491
+ else
492
+ DaemonLogger.write("Tried to scope empty target at #{path}", 'warn')
493
+ raise VaultDoesNotExistError.new, "Tried to scope empty target at #{path}"
494
+ return false
495
+ end
496
+ end
497
+
498
+ # Removes a vault from the application scope with a uuid.
499
+ # Closes the vault from the active vault set.
500
+ #
501
+ # Returns nil if no such vault was scoped before.
502
+ #
503
+ def unscope_vault(uuid)
504
+ unless @@config[:vaults]["#{uuid}"]
505
+ raise VaultNotScopedError.new, "Vault #{name} not scoped!"
506
+ return nilp
507
+ end
508
+
509
+ path = @@config[:vaults]["#{uuid}"][:path]
510
+ DaemonLogger.write("Unscoping vault #{uuid} at #{path}")
511
+ @@active_vaults["#{uuid}"].close if @@active_vaults["#{uuid}"]
512
+ @@config[:vaults].delete("#{uuid}")
513
+ cache_config
514
+ end
515
+
516
+ # Request token for a vault permanently.
517
+ # Only used if @@no_token == false. Unlocks a vault as well
518
+ # with the user passphrase
519
+ #
520
+ # Params: 'uuid' of the vault
521
+ # 'search' search queury as described in the wiki
522
+ #
523
+ # => Returns list of headers present in the vault
524
+ # according to the search queury
525
+ #
526
+ def access_headers(uuid, token, search = nil)
527
+ token.delete!("\n")
528
+ raise VaultNotAvailableError.new, "The vault you have requested data from is not currently active on this system." unless @@active_vaults["#{uuid}"]
529
+
530
+ raise UnknownTokenError.new, "The token you provided is unknown to this system. Access denied!" unless @@tokens[token]
531
+
532
+ raise UnautherisedTokenError.new, "The token you provided currently has no access to the desired vault. Access denied!" unless @@tokens[token].include?(uuid)
533
+
534
+
535
+ return @@active_vaults["#{uuid}"].list_headers(search)
536
+ end
537
+
538
+
539
+ # Request token for a vault permanently.
540
+ # Only used if @@no_token == false. Unlocks a vault as well
541
+ # with the user passphrase
542
+ #
543
+ # Params: 'uuid' of the vault
544
+ # 'file_name' file identifier to access
545
+ #
546
+ # => Returns contents (including headers) of a file either
547
+ # as it's current version or it's edit history.
548
+ #
549
+ def access_file(uuid, token, file_name, history = false)
550
+ token.delete!("\n")
551
+ raise VaultNotAvailableError.new, "The vault you have requested data from is not currently active on this system." unless @@active_vaults["#{uuid}"]
552
+
553
+ raise UnknownTokenError.new, "The token you provided is unknown to this system. Access denied!" unless @@tokens[token]
554
+
555
+ raise UnautherisedTokenError.new, "The token you provided currently has no access to the desired vault. Access denied!" unless @@tokens[token].include?(uuid)
556
+ return @@active_vaults["#{uuid}"].read_file(file_name, history)
557
+ end
558
+
559
+ # Request token for a vault permanently.
560
+ # Only used if @@no_token == false. Unlocks a vault as well
561
+ # with the user passphrase
562
+ #
563
+ # Params: 'uuid' of the vault
564
+ # 'file_name' file identifier to access
565
+ #
566
+ # => Returns contents of a file either as it's current
567
+ # version or it's edit history
568
+ #
569
+ def insert(uuid, token, file_name, data)
570
+ token.delete!("\n")
571
+ raise VaultNotAvailableError.new, "The vault you wish to insert data to is not currently active on this system." unless @@active_vaults["#{uuid}"]
572
+
573
+ raise UnknownTokenError.new, "The token you provided is unknown to this system. Access denied!" unless @@tokens[token]
574
+
575
+ raise UnautherisedTokenError.new, "The token you provided currently has no access to the desired vault. Access denied!" unless @@tokens[token].include?(uuid)
576
+
577
+ DaemonLogger.write("Writing data to #{uuid}", 'debug')
578
+
579
+ @@active_vaults["#{uuid}"].update(file_name, data)
580
+ end
581
+
582
+ # Request token for a vault permanently.
583
+ # Only used if @@no_token == false. Unlocks a vault as well
584
+ # with the user passphrase
585
+ #
586
+ # Params: 'uuid' of the vault
587
+ # 'file_name' file identifier to access
588
+ #
589
+ # => Returns contents of a file either as it's current
590
+ # version or it's edit history
591
+ #
592
+ def remove(uuid, token, file_name)
593
+ token.delete!("\n")
594
+ raise VaultNotAvailableError.new, "The vault you wish to insert data to is not currently active on this system." unless @@active_vaults["#{uuid}"]
595
+
596
+ raise UnknownTokenError.new, "The token you provided is unknown to this system. Access denied!" unless @@tokens[token]
597
+
598
+ raise UnautherisedTokenError.new, "The token you provided currently has no access to the desired vault. Access denied!" unless @@tokens[token].include?(uuid)
599
+
600
+ DaemonLogger.write("Writing data to #{uuid}", 'debug')
601
+
602
+ @@active_vaults["#{uuid}"].remove_file(file_name)
603
+ end
604
+
605
+
606
+ # Ends the exchange with a vault. Removes token from active vault record
607
+ #
608
+ def close_vault(uuid, token)
609
+ token.delete!("\n")
610
+ raise VaultNotAvailableError.new, "The vault you have requested data from is not currently active on this system." unless @@active_vaults["#{uuid}"]
611
+
612
+ raise UnknownTokenError.new, "The token you provided is unknown to this system. Access denied!" unless @@tokens[token]
613
+
614
+ raise UnautherisedTokenError.new, "The token you provided currently has no access to the desired vault. Access denied!" unless @@tokens[token].include?(uuid)
615
+
616
+ DaemonLogger.write("Closing vault with #{uuid}.", "debug")
617
+
618
+ # Close the vault
619
+ @@active_vaults["#{uuid}"].close
620
+
621
+ # Delete the vault from the active_vault record with UUID
622
+ @@active_vaults.delete("#{uuid}")
623
+
624
+ # TODO: Alert other applications
625
+ # TODO: Don't delete the token if it is being used to access
626
+ # other vaults on the system!
627
+ @@tokens.delete(token)
628
+
629
+ # Removes token from config
630
+ # TODO: FIX ME?!
631
+ @@config[:vaults]["#{uuid}"][:tokens].delete(token)
632
+ write_config
633
+ end
634
+ end
635
+ end
636
+
637
+ module Daemon
638
+ include Reedb
639
+
640
+ class << self
641
+ # Request token for a vault permanently.
642
+ # Only used if @@no_token == false. Unlocks a vault as well
643
+ # with the user passphrase
644
+ #
645
+ # Params: 'name' of the vault
646
+ # 'passphrase' to unlock
647
+ #
648
+ # => Returns token for vault
649
+ #
650
+ def request_token(uuid, passphrase, parmanent = false)
651
+ # If the vault is not currently open
652
+ unless @@active_vaults.include?(uuid)
653
+ unless @@config[:vaults][uuid]
654
+ DaemonLogger.write("The requested vault is unknown to this system. Aborting operation!", 'error')
655
+ raise VaultNotScopedError.new, "Requested vault #{uuid} is unknown to reedb. Has it been scoped before?"
656
+ end
657
+ # Continue
658
+ name = @@config[:vaults][uuid][:meta].name
659
+ path = @@config[:vaults][uuid][:meta].path
660
+ @@active_vaults[uuid] = ReeVault.new("#{name}", "#{path}", :auto).load(passphrase)
661
+ end
662
+ token = generate_token(uuid, path)
663
+ return token
664
+ end
665
+
666
+ # This function should be used by recurring applications that already own
667
+ # an authentication token for a vault.
668
+ #
669
+ def access_with_token(uuid, token, passphrase)
670
+ token.delete!("\n")
671
+ end
672
+ # Call this function to free a token and remove it from the access
673
+ # tree. This means that the vault it used to access are not removed or
674
+ # unloaded for other applications to use. But the token can no longer
675
+ # be used for file access.
676
+ #
677
+ def free_token(token)
678
+ token.delete!("\n")
679
+
680
+ # Throw a warning if the token isn't valid in the first place.
681
+ raise UnknownTokenError.new, "The token you provided is unknown to this system" unless @@tokens.include?(token)
682
+
683
+ @@tokens[token].each do |uuid|
684
+ @@config[:vaults]["#{uuid}"][:tokens].delete(token)
685
+ end
686
+
687
+ write_config
688
+ end
689
+ end #self class end
690
+ end # module Daemon end
691
+ end # Module Reedb end
692
+
693
+ passphrase = "1234567890123"
694
+ name = "default"
695
+ path = "/home/spacekookie/Desktop"
696
+
697
+
698
+
699
+ # name = "mega2"
700
+ # path = "/home/spacekookie"
701
+ # passphrase = "omg_awesome_sauce"
702
+
703
+ # Reedb::Core::init({:os=>:linux, :pw_length=>12})
704
+ #token = Reedb::Vault::create_vault(name, path, passphrase, :auto)
705
+ #puts token
706
+ # puts Reedb::generate_token("something", "blob")
707
+
708
+ # Reedb::Vault::scope_vault(name, path)
709
+
710
+ # puts Reedb::Vault::available_vaults
711
+ # Reedb::Vault::create_vault(name, path, user_pw)
712
+
713
+ # available = Reedb::Vault::available_vaults
714
+ # # puts "Available vaults: #{available}\n"
715
+
716
+ # puts Reedb::Config::Master::dump_config
717
+ # puts ""
718
+ # target = nil ; available.each { |uuid, meta| (target = uuid) if meta[:name] == "default" }
719
+
720
+ # puts "Target: #{target}"
721
+
722
+ # my_token = Reedb::Daemon::request_token(target, passphrase)
723
+ # puts "#{my_token}\n"
724
+ # search_qeuery = "tags=awsome#urls=www.lonelyrobot.io"
725
+
726
+ # headers = Reedb::Vault::access_headers(target, my_token, nil)
727
+ # print "#{headers}\n"
728
+
729
+ # Reedb::Vault::insert(target, my_token, "Lonely Robot", data1)
730
+ # Reedb::Vault::insert(target, my_token, "Lonely Robot", data2)
731
+ # Reedb::Vault::insert(target, my_token, "Lonely Robot", data3)
732
+
733
+ # puts Reedb::Vault::access_file(target, my_token, "Lonely Robot", true)
734
+
735
+ #headers = Reedb::Vault::access_headers(target, my_token)
736
+ #puts "Vault headers: #{headers}\n\n"
737
+
738
+ # Reedb::Vault::close_vault(target, my_token)
739
+ # Reedb::Core::terminate("aliens")