safedb 0.3.1011 → 0.4.1002

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +56 -19
  3. data/README.md +15 -15
  4. data/Rakefile +7 -0
  5. data/bin/safe +2 -2
  6. data/lib/{interprete.rb → cli.rb} +168 -121
  7. data/lib/controller/admin/README.md +47 -0
  8. data/lib/controller/admin/access.rb +47 -0
  9. data/lib/controller/admin/checkin.rb +83 -0
  10. data/lib/controller/admin/checkout.rb +57 -0
  11. data/lib/controller/admin/diff.rb +75 -0
  12. data/lib/{usecase → controller/admin}/export.rb +15 -14
  13. data/lib/controller/admin/goto.rb +52 -0
  14. data/lib/controller/admin/import.rb +54 -0
  15. data/lib/controller/admin/init.rb +113 -0
  16. data/lib/controller/admin/login.rb +88 -0
  17. data/lib/{usecase → controller/admin}/logout.rb +0 -0
  18. data/lib/controller/admin/open.rb +39 -0
  19. data/lib/{usecase → controller/admin}/token.rb +2 -2
  20. data/lib/controller/admin/tree.md +54 -0
  21. data/lib/{usecase → controller/admin}/use.rb +0 -0
  22. data/lib/controller/admin/view.rb +61 -0
  23. data/lib/{usecase → controller/api}/docker/README.md +0 -0
  24. data/lib/{usecase → controller/api}/docker/docker.rb +1 -1
  25. data/lib/{usecase → controller/api}/jenkins/README.md +0 -0
  26. data/lib/{usecase → controller/api}/jenkins/jenkins.rb +1 -1
  27. data/lib/{usecase → controller/api}/terraform/README.md +1 -1
  28. data/lib/{usecase → controller/api}/terraform/terraform.rb +1 -1
  29. data/lib/{usecase → controller/api}/vpn/README.md +1 -1
  30. data/lib/{usecase → controller/api}/vpn/vpn.ini +0 -0
  31. data/lib/{usecase → controller/api}/vpn/vpn.rb +0 -0
  32. data/lib/{usecase → controller}/config/README.md +0 -0
  33. data/lib/{usecase → controller}/edit/README.md +0 -0
  34. data/lib/controller/edit/editverse.rb +48 -0
  35. data/lib/controller/edit/put.rb +35 -0
  36. data/lib/controller/edit/remove.rb +29 -0
  37. data/lib/{usecase/update/README.md → controller/edit/rename.md} +0 -0
  38. data/lib/{usecase → controller}/files/README.md +1 -1
  39. data/lib/controller/files/read.rb +36 -0
  40. data/lib/{usecase/files/eject.rb → controller/files/write.rb} +15 -20
  41. data/lib/{usecase → controller}/id.rb +0 -0
  42. data/lib/controller/query/print.rb +26 -0
  43. data/lib/controller/query/queryverse.rb +39 -0
  44. data/lib/controller/query/show.rb +50 -0
  45. data/lib/{session/require.gem.rb → controller/requirer.rb} +13 -9
  46. data/lib/{usecase → controller}/set.rb +4 -4
  47. data/lib/controller/usecase.rb +244 -0
  48. data/lib/{usecase → controller}/verse.rb +0 -0
  49. data/lib/{usecase → controller}/visit/README.md +0 -0
  50. data/lib/{usecase → controller}/visit/visit.rb +0 -0
  51. data/lib/factbase/facts.safedb.net.ini +7 -7
  52. data/lib/{keytools/key.docs.rb → model/README.md} +102 -66
  53. data/lib/model/book.rb +484 -0
  54. data/lib/model/branch.rb +48 -0
  55. data/lib/model/checkin.feature +33 -0
  56. data/lib/{configs/README.md → model/configs.md} +4 -4
  57. data/lib/model/content.rb +214 -0
  58. data/lib/model/indices.rb +132 -0
  59. data/lib/model/safe_tree.rb +51 -0
  60. data/lib/model/state.inspect.rb +221 -0
  61. data/lib/model/state.migrate.rb +334 -0
  62. data/lib/model/text_chunk.rb +68 -0
  63. data/lib/{extension → utils/extend}/array.rb +0 -0
  64. data/lib/{extension → utils/extend}/dir.rb +0 -0
  65. data/lib/{extension → utils/extend}/file.rb +0 -0
  66. data/lib/utils/extend/hash.rb +76 -0
  67. data/lib/{extension → utils/extend}/string.rb +6 -6
  68. data/lib/{session/fact.finder.rb → utils/facts/fact.rb} +0 -0
  69. data/lib/utils/identity/identifier.rb +356 -0
  70. data/lib/{keytools/key.ident.rb → utils/identity/machine.id.rb} +67 -4
  71. data/lib/utils/inspect/inspector.rb +81 -0
  72. data/lib/{keytools/kdf.bcrypt.rb → utils/kdfs/bcrypt.rb} +0 -0
  73. data/lib/{keytools → utils/kdfs}/kdf.api.rb +16 -16
  74. data/lib/{keytools/key.local.rb → utils/kdfs/kdfs.rb} +40 -40
  75. data/lib/{keytools/kdf.pbkdf2.rb → utils/kdfs/pbkdf2.rb} +0 -0
  76. data/lib/{keytools/kdf.scrypt.rb → utils/kdfs/scrypt.rb} +0 -0
  77. data/lib/{keytools → utils}/key.error.rb +2 -2
  78. data/lib/{keytools → utils}/key.pass.rb +2 -2
  79. data/lib/{keytools → utils/keys}/key.64.rb +0 -0
  80. data/lib/{keytools → utils/keys}/key.rb +6 -2
  81. data/lib/{keytools/key.iv.rb → utils/keys/random.iv.rb} +0 -0
  82. data/lib/{logging/gem.logging.rb → utils/logs/logger.rb} +6 -5
  83. data/lib/{keytools/key.pair.rb → utils/store/datamap.rb} +48 -30
  84. data/lib/{keytools/key.db.rb → utils/store/datastore.rb} +38 -104
  85. data/lib/utils/store/merge-boys-school.json +40 -0
  86. data/lib/utils/store/merge-girls-school.json +48 -0
  87. data/lib/utils/store/merge-merged-data.json +56 -0
  88. data/lib/utils/store/struct.rb +75 -0
  89. data/lib/utils/store/test-commands.sh +24 -0
  90. data/lib/{keytools/key.now.rb → utils/time/timestamp.rb} +32 -21
  91. data/lib/version.rb +1 -1
  92. metadata +86 -73
  93. data/lib/extension/hash.rb +0 -33
  94. data/lib/keytools/key.algo.rb +0 -109
  95. data/lib/keytools/key.api.rb +0 -1326
  96. data/lib/keytools/key.id.rb +0 -322
  97. data/lib/modules/cryptology/amalgam.rb +0 -70
  98. data/lib/modules/cryptology/engineer.rb +0 -99
  99. data/lib/modules/mappers/dictionary.rb +0 -288
  100. data/lib/session/time.stamp.rb +0 -340
  101. data/lib/session/user.home.rb +0 -49
  102. data/lib/usecase/cmd.rb +0 -471
  103. data/lib/usecase/edit/delete.rb +0 -46
  104. data/lib/usecase/files/file_me.rb +0 -78
  105. data/lib/usecase/files/read.rb +0 -169
  106. data/lib/usecase/files/write.rb +0 -89
  107. data/lib/usecase/goto.rb +0 -57
  108. data/lib/usecase/import.rb +0 -157
  109. data/lib/usecase/init.rb +0 -61
  110. data/lib/usecase/login.rb +0 -72
  111. data/lib/usecase/open.rb +0 -71
  112. data/lib/usecase/print.rb +0 -40
  113. data/lib/usecase/put.rb +0 -81
  114. data/lib/usecase/show.rb +0 -138
  115. data/lib/usecase/update/rename.rb +0 -180
  116. data/lib/usecase/view.rb +0 -71
File without changes
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # Any {UseCase} class wishing to edit a safe verse can make use of the functionality
6
+ # in this parent by exposing an edit_verse() method.
7
+ #
8
+ # Classes extending this class will have access to
9
+ #
10
+ # - a <tt>@chapther_data</tt> **data** structure
11
+ # - a <tt>@chapther_id</tt> **string** index
12
+ # - a <tt>@has_chapter</tt> **boolean** indicator
13
+ # - a <tt>@verse_data</tt> **data** structure
14
+ # - a <tt>@verse_id</tt> **string** index
15
+ # - a <tt>@has_verse</tt> **boolean** indicator
16
+ #
17
+ # After the edit method completes the amended chapter data structure will be encrypted
18
+ # and streamed to a ciphertext file.
19
+ class EditVerse < UseCase
20
+
21
+ # This parental behaviour sets up common ubiquitous chapter and verse data structures
22
+ # and indices. It then calls the child's query_verse() behaviour and once that is complete
23
+ # it encrypts and persists an (updated) Book and the amended chapter.
24
+ #
25
+ # The streaming process also deletes the current (old) Book and chapter crypts.
26
+ def execute
27
+
28
+ # Before calling the edit_verse() method we perform some
29
+ # preparatory activities that check, validate and setup.
30
+ read_verse()
31
+
32
+ # This is the expected edit() method that will do and deliver
33
+ # the intented core contracted value proposition.
34
+ edit_verse()
35
+
36
+ # Now encrypt the changed verse and then write it out to a
37
+ # chapter crypt file whilst garbage collecting the now spurious
38
+ # and superceded script.
39
+ update_verse()
40
+
41
+
42
+ end
43
+
44
+
45
+ end
46
+
47
+
48
+ end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # The <b>put use case</b> follows <b>open</b> and it adds secrets into an
6
+ # <em>(encrypted at rest)</em> <b>envelope</b>. Put can be called many times
7
+ # and when done, the <b>lock use case</b> can be called to commit all opened
8
+ # secrets into the configured storage engines.
9
+ #
10
+ # Calling <em>put</em> <b>before</b> calling open or <b>after</b> calling lock
11
+ # is not allowed and will result in an error.
12
+ #
13
+ # == Put Pre-Conditions
14
+ #
15
+ # At the point of calling the put use case
16
+ #
17
+ # - the safe must be <b>logged in</b> and a chapter and verse opened
18
+ # - the key / value pair being put must pass minimum standards
19
+ class Put < EditVerse
20
+
21
+ attr_writer :credential_id, :credential_value
22
+
23
+ # Execute the act of validating and then putting the credential key and
24
+ # its value into the chapter and verse location, overwriting if need be.
25
+ def edit_verse()
26
+
27
+ @verse.store( @credential_id, @credential_value )
28
+
29
+ end
30
+
31
+
32
+ end
33
+
34
+
35
+ end
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # The <tt>remove</tt> use case takes away one or more of the safe's core entities.
6
+ #
7
+ # - at <tt>verse</tt> level - it can delete one or more lines
8
+ # - at <tt>chapter</tt> level - it can delete one or more verses
9
+ # - at <tt>book</tt> level - it can delete one or more chapters
10
+ # - at <tt>safe</tt> level - it can delete one book
11
+ #
12
+ class Remove < EditVerse
13
+
14
+ attr_writer :line_id
15
+
16
+ # Deletion that currently expects an open chapter and verse and always
17
+ # wants to delete only one line (key/value pair).
18
+ def edit_verse()
19
+
20
+ @verse.delete( @line_id )
21
+ @verse.delete( "#{Indices::INGESTED_FILE_LINE_NAME_KEY}#{@line_id}" )
22
+
23
+ end
24
+
25
+
26
+ end
27
+
28
+
29
+ end
@@ -1,5 +1,5 @@
1
1
 
2
- # safe file | ingest and eject files
2
+ # safe read | safe write | reading and writing files
3
3
 
4
4
  You ingest a file with **safe file** and then **safe eject** will output that file into the present working directory.
5
5
 
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # The <b>read use case</b> pulls a file in from either an accessible filesystem.
6
+ #
7
+ # This use case expects a @file_url parameter.
8
+ class Read < EditVerse
9
+
10
+ attr_writer :file_key, :file_url
11
+
12
+ # The <b>read use case</b> pulls a file in from an accessible filesystem.
13
+ def edit_verse()
14
+
15
+ file_full_path = ::File.absolute_path( @file_url )
16
+ file_base_name = ::File.basename( file_full_path )
17
+ file_content64 = Base64.urlsafe_encode64( ::File.read( file_full_path ) )
18
+
19
+ log.info(x) { "Key name of the file to ingest => #{@file_key}" }
20
+ log.info(x) { "Ingesting file at path => #{file_full_path}" }
21
+ log.info(x) { "The name of the file to ingest is => #{file_base_name}" }
22
+ log.info(x) { "Size of base64 file content => [#{file_content64.length}]" }
23
+
24
+ filedata_map = {}
25
+ filedata_map.store( Indices::INGESTED_FILE_BASE_NAME_KEY, file_base_name )
26
+ filedata_map.store( Indices::INGESTED_FILE_CONTENT64_KEY, file_content64 )
27
+
28
+ @verse.store( Indices::INGESTED_FILE_LINE_NAME_KEY + @file_key, filedata_map )
29
+
30
+ end
31
+
32
+
33
+ end
34
+
35
+
36
+ end
@@ -2,33 +2,29 @@
2
2
 
3
3
  module SafeDb
4
4
 
5
- # The <b>eject use case</b> writes (or overwrites) a file or files.
5
+ # The <b>write use case</b> writes (or overwrites) a file or files.
6
6
  # Files are always ejected into the present working directory. If an
7
7
  # overwrite is detected a backup is taken of the about to be clobbered
8
8
  # file.
9
9
  #
10
10
  # If a keyname is provided then only the file against that key is ejected.
11
11
  # No keyname will eject every file in the opened chapter and verse.
12
- class Eject < UseCase
12
+ class Write < QueryVerse
13
13
 
14
14
  attr_writer :file_key, :to_dir
15
15
 
16
- # Files are always ejected into the present working directory and any
17
- # about to be clobbered files are backed up with a timestamp.
18
- #
19
- # If a keyname is provided then only the file against that key is ejected.
20
- # No keyname will eject every file in the opened chapter and verse.
21
- def execute
16
+ # Use the chapter and verse setup to read the parameter {@key_name}
17
+ # and print its corresponding value without a line feed or return.
18
+ def query_verse()
22
19
 
23
- return unless ops_key_exists?
24
- master_db = get_master_database()
25
- return if unopened_envelope?( master_db )
26
- chapter_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
27
- verse_id = master_db[ KEY_PATH ]
28
- chapter_data = KeyDb.from_json( KeyApi.content_unlock( master_db[ chapter_id ] ) )
20
+ bcv_name = "#{@book.book_name()}/#{@book.get_open_chapter_name()}/#{@book.get_open_verse_name()}"
29
21
 
30
- base64_content = chapter_data[ verse_id ][ "#{FILE_KEY_PREFIX}#{@file_key}" ][ FILE_CONTENT_KEY ]
31
- simple_filename = chapter_data[ verse_id ][ "#{FILE_KEY_PREFIX}#{@file_key}" ][ FILE_NAME_KEY ]
22
+ puts ""
23
+ puts "book/chapter/verse\n"
24
+ puts "#{bcv_name} (#{@verse.length()})\n"
25
+
26
+ base64_content = @verse[ Indices::INGESTED_FILE_LINE_NAME_KEY + @file_key ][ Indices::INGESTED_FILE_CONTENT64_KEY ]
27
+ simple_filename = @verse[ Indices::INGESTED_FILE_LINE_NAME_KEY + @file_key ][ Indices::INGESTED_FILE_BASE_NAME_KEY ]
32
28
 
33
29
  # Do a mkdir_p if @to_dir has some valid non-whitespace text
34
30
  # If so check that we have permissions to write to the specified folder
@@ -44,12 +40,11 @@ module SafeDb
44
40
  puts "Clobbered File = #{backup_filename}" if will_clobber
45
41
  puts "Prescribed Directory = #{@to_dir}" unless @to_dir.nil?
46
42
  puts "Present Directory = #{Dir.pwd}" if @to_dir.nil?
47
- puts "Ejected Filename = #{simple_filename}"
43
+ puts "Written Out Filename = #{simple_filename}"
48
44
  puts "The Full Filepath = #{file_full_path}"
49
- puts "Chapter and Verse = #{master_db[ENV_PATH]}::#{verse_id}"
50
- puts "Ejected File Key = #{@file_key}"
45
+ puts "Written File Key = #{@file_key}"
51
46
  puts ""
52
- puts "File successfully ejected from the safe."
47
+ puts "File successfully written from safe to filesystem."
53
48
  puts ""
54
49
 
55
50
  File.write( backup_file_path, File.read( file_full_path ) ) if will_clobber
File without changes
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # The print use case prints out a credential value without a line
6
+ # feed or any other contextual information.
7
+ #
8
+ # Print is perfect for reading values from scripts or using unix
9
+ # like pipe behaviour to pass credentials to other commands.
10
+ class Print < QueryVerse
11
+
12
+ attr_writer :key_name
13
+
14
+ # Use the chapter and verse setup to read the parameter {@key_name}
15
+ # and print its corresponding value without a line feed or return.
16
+ def query_verse()
17
+
18
+ print @verse[ @key_name ]
19
+
20
+ end
21
+
22
+
23
+ end
24
+
25
+
26
+ end
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # Any {UseCase} class wishing to query a safe verse can make use of the functionality
6
+ # in this parent by exposing an query_verse() method.
7
+ #
8
+ # Classes extending this class will have access to
9
+ #
10
+ # - a <tt>@chapther_data</tt> **data** structure
11
+ # - a <tt>@chapther_id</tt> **string** index
12
+ # - a <tt>@has_chapter</tt> **boolean** indicator
13
+ # - a <tt>@verse_data</tt> **data** structure
14
+ # - a <tt>@verse_id</tt> **string** index
15
+ # - a <tt>@has_verse</tt> **boolean** indicator
16
+ #
17
+ # The query_verse() method is not succeeded by any behaviour in the parent. Chilc classes
18
+ # must do their own output management.
19
+ class QueryVerse < UseCase
20
+
21
+ # This parental behaviour sets up common ubiquitous chapter and verse data structures
22
+ # and indices.
23
+ def execute
24
+
25
+ # Before calling the edit_verse() method we perform some
26
+ # preparatory activities that check, validate and setup.
27
+ read_verse()
28
+
29
+ # The query verse behaviour implemented by the child classes will read and
30
+ # perhaps display credentials without changing state.
31
+ query_verse()
32
+
33
+ end
34
+
35
+
36
+ end
37
+
38
+
39
+ end
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # Show the mini dictionary of key-value pairs within the logged in book
6
+ # at the opened chapter and verse.
7
+ #
8
+ # If no dictionary exists at the opened chapter and verse a suitable
9
+ # message is pushed out to the console.
10
+ class Show < QueryVerse
11
+
12
+ # We expect the book to be opened at a given chapter and verse location. This
13
+ # use case simply (sensitively) shows the pertinent data lines contained within
14
+ # the opened verse.
15
+ def query_verse()
16
+
17
+ @book.print_book_mark()
18
+ if @verse.empty?()
19
+
20
+ puts JSON.pretty_generate( {} )
21
+ puts ""
22
+ return
23
+
24
+ end
25
+
26
+ show_map = {}
27
+ @verse.each do | key_str, value |
28
+
29
+ is_file = key_str.start_with? Indices::INGESTED_FILE_LINE_NAME_KEY
30
+ value.store( Indices::INGESTED_FILE_CONTENT64_KEY, Indices::SECRET_MASK_STRING ) if is_file
31
+ show_map.store( key_str[ Indices::INGESTED_FILE_LINE_NAME_KEY.length() .. -1 ], value ) if is_file
32
+ next if is_file
33
+
34
+ is_secret = key_str.start_with? "@"
35
+ showable_val = Indices::SECRET_MASK_STRING if is_secret
36
+ showable_val = value unless is_secret
37
+ show_map.store( key_str, showable_val )
38
+
39
+ end
40
+
41
+ puts JSON.pretty_generate( show_map )
42
+ puts ""
43
+
44
+ end
45
+
46
+
47
+ end
48
+
49
+
50
+ end
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/ruby
2
2
  # coding: utf-8
3
3
 
4
- module OpenSession
4
+ module SafeDb
5
5
 
6
6
 
7
7
  # Require every file with a dot rb extension that is
@@ -50,7 +50,7 @@ module OpenSession
50
50
  # In the plugins hierarchy, you'll notice that the child classes
51
51
  # are always below the parents. This strategy works if the +inheritors+
52
52
  # are in the same gem as the +inherited+.
53
- class RecursivelyRequire
53
+ class Require
54
54
 
55
55
  # Require every file with a dot rb extension that is
56
56
  # +either in or recursively below+ the file path given
@@ -83,24 +83,28 @@ module OpenSession
83
83
  # their extension classes in the lower subdirectories.
84
84
  #
85
85
  # @param gem_filepath [String] path to callling gem (use <tt>__FILE</tt>)
86
- def self.now gem_filepath
86
+ def self.gems( gem_filepath )
87
87
 
88
- require_relative "../usecase/cmd"
88
+ require_relative "../version"
89
+ require_relative "../controller/usecase"
90
+ require_relative "../controller/admin/access"
91
+ require_relative "../controller/edit/editverse"
92
+ require_relative "../controller/query/queryverse"
89
93
 
90
94
  gem_basepath = File.expand_path "..", gem_filepath
91
95
 
92
- log.info(x) { "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" }
93
- log.info(x) { "@@@@ Require Gems In or Under [#{gem_basepath}]" }
94
- log.info(x) { "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" }
96
+ log.debug(x) { "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" }
97
+ log.debug(x) { "@@@@ Require Gems In or Under [#{gem_basepath}]" }
98
+ log.debug(x) { "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" }
95
99
 
96
100
  Dir["#{gem_basepath}/**/*.rb"].each do |gem_path|
97
101
 
98
- log.info(x) { "@@@@ => #{gem_path}" }
102
+ log.debug(x) { "@@@@ => #{gem_path}" }
99
103
  require gem_path
100
104
 
101
105
  end
102
106
 
103
- log.info(x) { "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" }
107
+ log.debug(x) { "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" }
104
108
 
105
109
  end
106
110
 
@@ -4,7 +4,7 @@ module SafeDb
4
4
 
5
5
  # The <b>set <em>use case</em></b> is the generic tool for setting book scoped
6
6
  # configuration directives. These directives can only be read, written, updated
7
- # or removed during a logged in session.
7
+ # or removed during a logged in branch.
8
8
  #
9
9
  # The mirror of this use case is <b><em>unset</em></b>.
10
10
  #
@@ -19,11 +19,11 @@ module SafeDb
19
19
 
20
20
  # The <b>set <em>use case</em></b> is the generic tool for setting book scoped
21
21
  # configuration directives. These directives can only be read, written, updated
22
- # or removed during a logged in session.
22
+ # or removed during a logged in branch.
23
23
  def execute
24
24
 
25
25
  return unless ops_key_exists?
26
- master_db = KeyApi.read_master_db()
26
+ master_db = Book.read()
27
27
 
28
28
  master_db[ @directive_name ] = @directive_value
29
29
 
@@ -31,7 +31,7 @@ module SafeDb
31
31
  puts JSON.pretty_generate( master_db )
32
32
  puts ""
33
33
 
34
- KeyApi.write_master_db( create_header(), master_db )
34
+ Book.write( create_header(), master_db )
35
35
 
36
36
  end
37
37
 
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/ruby
2
+ # coding: utf-8
3
+
4
+ module SafeDb
5
+
6
+ # The parent SafeDb use case is designed to be extended by the cli
7
+ # (command line) use cases like {SafeDb::Open}, {SafeDb::Put} and
8
+ # {SafeDb::Lock} because it describes behaviour common to at least two
9
+ # (but usually more) of the use cases.
10
+ #
11
+ # == Common Use Case Behaviour
12
+ #
13
+ # This {SafeDb::UseCase} use case is designed to be extended and does preparatory
14
+ # work to create favourable and useful conditions to make use cases readable,
15
+ # less repetitive, simpler and concise.
16
+ #
17
+ # == Machine (Workstation) Configuration File
18
+ #
19
+ # The global configuration filepath is found off the home directory using {Dir.home}.
20
+ #
21
+ # ~/.safedb.net/safedb.net.configuration.ini
22
+ #
23
+ # The global configuration file in INI format is managed through the methods
24
+ #
25
+ # - {grab} read the value at key_name from the default section
26
+ # - {stash} put directive key/value pair in default section
27
+ # - {read} read the value at key_name from the parameter section
28
+ # - {write} put directive key/value pair in parameter section
29
+ class UseCase
30
+
31
+ # All controllers are initialized here meaning that there will be automatic
32
+ # execution of very frequently used setup behaviour. This includes
33
+ # - checking for (and reporting a lack of) the safe token environment variable
34
+ # - asimilating a fact file if employed by the specific use case (controller)
35
+ def initialize
36
+
37
+ class_name = self.class.name.split(":").last.downcase
38
+ is_no_token_uc = [ "token", "init", "id" ].include? class_name
39
+ return if is_no_token_uc
40
+
41
+ exit(100) unless ops_key_exists?
42
+
43
+ # Chop off all fact work for now. May need to resurrect for VPN functionality.
44
+ return
45
+
46
+ fact_filepath = File.sister_filepath( self, "ini", :execute )
47
+ log.info(x) { "Search location for INI factfile is [#{fact_filepath}]" }
48
+ return unless File.exists?( fact_filepath )
49
+
50
+ @facts = FactFind.new()
51
+ add_secret_facts @facts
52
+ @facts.assimilate_ini_file( fact_filepath )
53
+ @dictionary = @facts.f[ @facts.to_symbol( class_name ) ]
54
+
55
+ end
56
+
57
+
58
+ # This parental behaviour decrypts and reads the ubiquitous chapter and verse
59
+ # data structures and indices.
60
+ def read_verse()
61
+
62
+ # @todo => consider doing the book index opening with initializer UNLESS token/admin use case
63
+
64
+ @book = Book.new()
65
+ return if @book.unopened_chapter_verse()
66
+ @verse = @book.get_open_verse_data()
67
+
68
+ end
69
+
70
+
71
+ # This parental behaviour encrypts and writes out the in-play chapter
72
+ # and verse data. This behaviour also deletes the crypt file belonging
73
+ # to the now superceeded chapter state.
74
+ def update_verse()
75
+
76
+ @book.write_open_chapter()
77
+ Show.new.flow()
78
+
79
+ end
80
+
81
+
82
+ # Execute the use cases's flow from beginning when
83
+ # you validate the input and parameters through the
84
+ # memorize and execute.
85
+ def flow()
86
+
87
+ check_pre_conditions
88
+ execute
89
+ check_post_conditions
90
+
91
+ end
92
+
93
+
94
+ # Validate the input parameters and check that the current
95
+ # state is perfect for executing the use case.
96
+ #
97
+ # If either of the above fail - the validation function should
98
+ # set a human readable string and then throw an exception.
99
+ def check_pre_conditions
100
+
101
+ begin
102
+ pre_validation
103
+ rescue OpenError::CliError => e
104
+
105
+ puts ""
106
+ puts "Your command did not complete successfully."
107
+ puts "Pre validation checks failed."
108
+ puts ""
109
+ puts " => #{e.message}"
110
+ puts ""
111
+ abort e.message
112
+ end
113
+
114
+ end
115
+
116
+
117
+ # Override me if you need to
118
+ def pre_validation
119
+
120
+ end
121
+
122
+
123
+ # After the main flow of events certain state conditions
124
+ # must hold true thus demonstrating that the observable
125
+ # value has indeed ben delivered.
126
+ #
127
+ # Child classes should subclass this method and place any
128
+ # post execution (post condition) checks in it and then
129
+ # make a call to this method through the "super" keyword.
130
+ def check_post_conditions
131
+
132
+ begin
133
+ post_validation
134
+ rescue OpenError::CliError => e
135
+
136
+ puts ""
137
+ puts "Your command did not complete successfully."
138
+ puts "Post validation checks failed."
139
+ puts ""
140
+ puts " => #{e.message}"
141
+ #### puts " => #{e.culprit}"
142
+ puts ""
143
+ abort e.message
144
+ end
145
+
146
+ end
147
+
148
+
149
+ # Child classes should subclass this method and place any
150
+ # post execution (post condition) checks in it and then
151
+ # make a call to this method through the "super" keyword if
152
+ # this method gets any global behaviour in it worth calling.
153
+ def post_validation
154
+
155
+ end
156
+
157
+
158
+ # Execute the main flow of events of the use case. Any
159
+ # exceptions thrown are captured and if the instance
160
+ # variale [@human_readable_message] is set - tell the
161
+ # user about it. Without any message - just tell the
162
+ # user something went wrong and tell them where the logs
163
+ # are that might carry more information.
164
+ def execute
165
+
166
+ end
167
+
168
+
169
+ private
170
+
171
+
172
+ ENV_VAR_PREFIX_A = "evar."
173
+ ENV_VAR_PREFIX_B = "@evar."
174
+ COMMANDMENT = "safe"
175
+ ENV_VAR_KEY_NAME = "SAFE_TTY_TOKEN"
176
+ ENV_PATH = "env.path"
177
+ KEY_PATH = "key.path"
178
+ ENVELOPE_KEY_PREFIX = "envelope@"
179
+
180
+
181
+ # --> def add_secret_facts fact_db
182
+
183
+ # --> master_db = Book.read()
184
+ # --> raise ArgumentError.new "There is no open chapter here." if unopened_envelope?( master_db )
185
+ # --> chapter_id = ENVELOPE_KEY_PREFIX + master_db[ ENV_PATH ]
186
+ # --> verse_id = master_db[ KEY_PATH ]
187
+ # --> chapter_data = DataStore.from_json( Lock.content_unlock( master_db[ chapter_id ] ) )
188
+ # --> mini_dictionary = chapter_data[ master_db[ KEY_PATH ] ]
189
+
190
+ # --> mini_dictionary.each do | key_str, value_str|
191
+ # --> fact_db.assimilate_fact( "secrets", key_str, value_str )
192
+ # --> end
193
+
194
+ # --> end
195
+
196
+
197
+ def ops_key_exists?
198
+
199
+ log_env()
200
+
201
+ if ( ENV.has_key? ENV_VAR_KEY_NAME )
202
+ return true
203
+ end
204
+
205
+ puts ""
206
+ puts "safe needs you to create a branch key."
207
+ puts "To automate this step see the documentation."
208
+ puts "To create the key run the below command."
209
+ puts ""
210
+ puts " export #{ENV_VAR_KEY_NAME}=`#{COMMANDMENT} token`"
211
+ puts ""
212
+ puts "Those are backticks surrounding `#{COMMANDMENT} token`"
213
+ puts "Not apostrophes."
214
+ puts ""
215
+
216
+ return false
217
+
218
+ end
219
+
220
+
221
+ def log_env()
222
+
223
+ log.debug(x) { "Gem Root Folder => #{Gem.dir()}" }
224
+ log.debug(x) { "Gem Config File => #{Gem.config_file()}" }
225
+ log.debug(x) { "Gem Binary Path => #{Gem.default_bindir()}" }
226
+ log.debug(x) { "Gem Host Path => #{Gem.host()}" }
227
+ log.debug(x) { "Gem Caller Folder => #{Gem.location_of_caller()}" }
228
+ log.debug(x) { "Gem Paths List => #{Gem.path()}" }
229
+ log.debug(x) { "Gem Platforms => #{Gem.platforms()}" }
230
+ log.debug(x) { "Gem Ruby Version X => #{Gem.ruby()}" }
231
+ log.debug(x) { "Gem Ruby Version Y => #{Gem::VERSION}" }
232
+ log.debug(x) { "Gem Ruby Version Z => #{Gem.latest_rubygems_version()}" }
233
+ log.debug(x) { "Gem User Folder => #{Gem.user_dir()}" }
234
+ log.debug(x) { "Gem User Home => #{Gem.user_home()}" }
235
+
236
+ return
237
+
238
+ end
239
+
240
+
241
+ end
242
+
243
+
244
+ end