safedb 0.01.0001

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.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.yardopts +3 -0
  4. data/Gemfile +10 -0
  5. data/LICENSE +21 -0
  6. data/README.md +793 -0
  7. data/Rakefile +16 -0
  8. data/bin/safe +5 -0
  9. data/lib/configs/README.md +58 -0
  10. data/lib/extension/array.rb +162 -0
  11. data/lib/extension/dir.rb +35 -0
  12. data/lib/extension/file.rb +123 -0
  13. data/lib/extension/hash.rb +33 -0
  14. data/lib/extension/string.rb +572 -0
  15. data/lib/factbase/facts.safedb.net.ini +38 -0
  16. data/lib/interprete.rb +462 -0
  17. data/lib/keytools/PRODUCE_RAND_SEQ_USING_DEV_URANDOM.txt +0 -0
  18. data/lib/keytools/kdf.api.rb +243 -0
  19. data/lib/keytools/kdf.bcrypt.rb +265 -0
  20. data/lib/keytools/kdf.pbkdf2.rb +262 -0
  21. data/lib/keytools/kdf.scrypt.rb +190 -0
  22. data/lib/keytools/key.64.rb +326 -0
  23. data/lib/keytools/key.algo.rb +109 -0
  24. data/lib/keytools/key.api.rb +1391 -0
  25. data/lib/keytools/key.db.rb +330 -0
  26. data/lib/keytools/key.docs.rb +195 -0
  27. data/lib/keytools/key.error.rb +110 -0
  28. data/lib/keytools/key.id.rb +271 -0
  29. data/lib/keytools/key.ident.rb +243 -0
  30. data/lib/keytools/key.iv.rb +107 -0
  31. data/lib/keytools/key.local.rb +259 -0
  32. data/lib/keytools/key.now.rb +402 -0
  33. data/lib/keytools/key.pair.rb +259 -0
  34. data/lib/keytools/key.pass.rb +120 -0
  35. data/lib/keytools/key.rb +585 -0
  36. data/lib/logging/gem.logging.rb +132 -0
  37. data/lib/modules/README.md +43 -0
  38. data/lib/modules/cryptology/aes-256.rb +154 -0
  39. data/lib/modules/cryptology/amalgam.rb +70 -0
  40. data/lib/modules/cryptology/blowfish.rb +130 -0
  41. data/lib/modules/cryptology/cipher.rb +207 -0
  42. data/lib/modules/cryptology/collect.rb +138 -0
  43. data/lib/modules/cryptology/crypt.io.rb +225 -0
  44. data/lib/modules/cryptology/engineer.rb +99 -0
  45. data/lib/modules/mappers/dictionary.rb +288 -0
  46. data/lib/modules/storage/coldstore.rb +186 -0
  47. data/lib/modules/storage/git.store.rb +399 -0
  48. data/lib/session/fact.finder.rb +334 -0
  49. data/lib/session/require.gem.rb +112 -0
  50. data/lib/session/time.stamp.rb +340 -0
  51. data/lib/session/user.home.rb +49 -0
  52. data/lib/usecase/cmd.rb +487 -0
  53. data/lib/usecase/config/README.md +57 -0
  54. data/lib/usecase/docker/README.md +146 -0
  55. data/lib/usecase/docker/docker.rb +49 -0
  56. data/lib/usecase/edit/README.md +43 -0
  57. data/lib/usecase/edit/delete.rb +46 -0
  58. data/lib/usecase/export.rb +40 -0
  59. data/lib/usecase/files/README.md +37 -0
  60. data/lib/usecase/files/eject.rb +56 -0
  61. data/lib/usecase/files/file_me.rb +78 -0
  62. data/lib/usecase/files/read.rb +169 -0
  63. data/lib/usecase/files/write.rb +89 -0
  64. data/lib/usecase/goto.rb +57 -0
  65. data/lib/usecase/id.rb +36 -0
  66. data/lib/usecase/import.rb +157 -0
  67. data/lib/usecase/init.rb +63 -0
  68. data/lib/usecase/jenkins/README.md +146 -0
  69. data/lib/usecase/jenkins/jenkins.rb +208 -0
  70. data/lib/usecase/login.rb +71 -0
  71. data/lib/usecase/logout.rb +28 -0
  72. data/lib/usecase/open.rb +71 -0
  73. data/lib/usecase/print.rb +40 -0
  74. data/lib/usecase/put.rb +81 -0
  75. data/lib/usecase/set.rb +44 -0
  76. data/lib/usecase/show.rb +138 -0
  77. data/lib/usecase/terraform/README.md +91 -0
  78. data/lib/usecase/terraform/terraform.rb +121 -0
  79. data/lib/usecase/token.rb +35 -0
  80. data/lib/usecase/update/README.md +55 -0
  81. data/lib/usecase/update/rename.rb +180 -0
  82. data/lib/usecase/use.rb +41 -0
  83. data/lib/usecase/verse.rb +20 -0
  84. data/lib/usecase/view.rb +71 -0
  85. data/lib/usecase/vpn/README.md +150 -0
  86. data/lib/usecase/vpn/vpn.ini +31 -0
  87. data/lib/usecase/vpn/vpn.rb +54 -0
  88. data/lib/version.rb +3 -0
  89. data/safedb.gemspec +34 -0
  90. metadata +193 -0
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ # -
5
+ # - This configuration allows us to run "rake test"
6
+ # - and invoke minitest to execute all files in the
7
+ # - test directory with names ending in "_test.rb".
8
+ # -
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << "test"
11
+ t.libs << "lib"
12
+ t.test_files = FileList["test/**/*_test.rb"]
13
+ end
14
+
15
+ task :default => :test
16
+
data/bin/safe ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'interprete'
4
+
5
+ Interprete.start(ARGV)
@@ -0,0 +1,58 @@
1
+
2
+ # Modifying Safe's Behaviour | 4 Configuration Scopes
3
+
4
+ Safe's behaviour can (by default) be modified in a manner that is scoped in 4 ways. Configuration directives can alter behaviour within
5
+
6
+ 1. a **book global** scope
7
+ 2. a **machine local** scope
8
+ 3. a **shell session** scope and
9
+ 4. a **machine global** scope
10
+
11
+ The scoping concept is similar to Git's --local and --global but it works in a different way.
12
+
13
+
14
+ ## 1. Book Global Scope
15
+
16
+ Directives issued against a safe book **"feel local"** but are global in that the behaviour persists on every machine that works with the book.
17
+
18
+ Git's --local is different because cloning the repository on another machine wipe's out the directives. With safe the directives continue to alter behaviour even when the book is cloned and/or used on another machine.
19
+
20
+
21
+ ## 2. Machine Local Scope
22
+
23
+ This is similar to Git's --global directive which affects all repositories owned by a user on a given machine.
24
+
25
+ Directives with a machine local scope **can influence the behaviour** of every Safe book one logs into on a machine. Move to another machine and the behaviour becomes unstuck.
26
+
27
+ == Configuration Directive Precedence
28
+
29
+ Note the sentence **can influence behaviour** as opposed to **will influence behaviour**.
30
+
31
+ If a directive with a book global scope says "Yes" and the same directive exists but says "No" with machine local scope the "Yes" wins out.
32
+
33
+ A book global directive overrides its machine local twin.
34
+
35
+
36
+ ## 3. Shell Session Scope
37
+
38
+ The self explanatory **shell session scoped** directives override their siblings be they book global or machine local.
39
+
40
+ Alas, their elevated privileges are countered by relatively short lifespans. Shell session directives only last until either a logout is issued or the shell session comes to an end.
41
+
42
+
43
+ ## 4. Default | Machine Global Scope
44
+
45
+ Did you notice only **one (1) user** is affected by directives with a machine local scope as long as it isn't overriden.
46
+
47
+ Directives with a **machine global scope** are the **default** and are set during an install or upgrade.
48
+
49
+ They can potentially affect **every user and every safe book**. Even though their longevity is undisputed, their precedence is the lowest when going head to head with their 3 siblings.
50
+
51
+ ## The Naked Eye
52
+
53
+ Directives with a book global scope **aren't visible to the naked eye**. They are encrypted within the master safe database and thus protected from prying eyes.
54
+
55
+ The other 3 directive types exist in plain text
56
+
57
+ - either where the gem is **installed** (machine global scope)
58
+ - or in the INI file in **.safe** off the user's home directory
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/ruby
2
+
3
+ #
4
+ # Reopen the core ruby Array class and add the below methods to it.
5
+ #
6
+ # Case Sensitivity rules for [ALL] the below methods that are
7
+ # added to the core Ruby string class.
8
+ #
9
+ # For case insensitive behaviour make sure you downcase both the
10
+ # string object and the parameter strings (or strings within
11
+ # other parameter objects, like arrays and hashes).
12
+ class Array
13
+
14
+
15
+ # The returned string is a result of a union (join) of all the
16
+ # (expected) string array elements followed by the <b>deletion</b>
17
+ # of <b>all <em>non</em> alphanumeric characters</b>.
18
+ #
19
+ # <b>Disambiguating the String for Cross Platform Use</b>
20
+ #
21
+ # This behaviour is typically used for transforming text that is
22
+ # about to be signed or digested (hashed). Removing all the non
23
+ # alpha-numeric characters disambiguates the string.
24
+ #
25
+ # An example is the exclusion of line ending characters which in
26
+ # Windows are different from Linux.
27
+ #
28
+ # This disambiguation means that signing functions will return the
29
+ # same result on widely variant platfoms like Windows vs CoreOS.
30
+ #
31
+ # @return [String]
32
+ # Returns the alphanumeric union of the strings within this array.
33
+ #
34
+ # @raise [ArgumentError]
35
+ # if the array is nil or empty. Also an error will be thrown if
36
+ # the array contains objects that cannot be naturally converted
37
+ # to a string.
38
+ def alphanumeric_union
39
+ raise ArgumentError, "Cannot do alphanumeric union on an empty array." if self.empty?
40
+ return self.join.to_alphanumeric
41
+ end
42
+
43
+
44
+ # Log the array using our logging mixin by printing every array
45
+ # item into its own log line. In most cases we (the array) are
46
+ # a list of strings, however if not, each item's to_string method
47
+ # is invoked and the result printed using one log line.
48
+ #
49
+ # The INFO log level is used to log the lines - if this is not
50
+ # appropriate create a (level) parameterized log lines method.
51
+ def log_lines
52
+
53
+ self.each do |line|
54
+ clean_line = line.to_s.chomp.gsub("\\n","")
55
+ log.info(x) { line } if clean_line.length > 0
56
+ end
57
+
58
+ end
59
+
60
+
61
+ # Get the text [in between] this and that delimeter [exclusively].
62
+ # Exclusively means the returned text [does not] include either of
63
+ # the matched delimeters (although an unmatched instance of [this]
64
+ # delimeter may appear in the in-between text).
65
+ #
66
+ # --------------------
67
+ # Multiple Delimiters
68
+ # --------------------
69
+ #
70
+ # When multiple delimiters exist, the text returned is in between the
71
+ #
72
+ # [a] - first occurrence of [this] delimeter AND the
73
+ # [b] - 1st occurrence of [that] delimeter [AFTER] the 1st delimiter
74
+ #
75
+ # Instances of [that] delimiter occurring before [this] are ignored.
76
+ # The text could contain [this] delimeter instances but is guaranteed
77
+ # not to contain a [that] delimeter.
78
+ #
79
+ # -----------
80
+ # Parameters
81
+ # -----------
82
+ #
83
+ # this_delimiter : begin delimeter (not included in returned string)
84
+ # that_delimiter : end delimeter (not included in returned string)
85
+ #
86
+ # -----------
87
+ # Exceptions
88
+ # -----------
89
+ #
90
+ # An exception (error) will be thrown if
91
+ #
92
+ # => any nil (or empties) exist in the input parameters
93
+ # => [this] delimeter does not appear in the in_string
94
+ # => [that] delimeter does not appear after [this] one
95
+ #
96
+ def before_and_after begin_delimeter, end_delimeter
97
+
98
+ Throw.if_nil_or_empty_strings [ self, begin_delimeter, end_delimeter ]
99
+
100
+ before_after_lines = []
101
+ in_middle_bit = false
102
+
103
+ self.each do |candidate_line|
104
+
105
+ is_middle_boundary = !in_middle_bit && candidate_line.downcase.include?(begin_delimeter.downcase)
106
+ if is_middle_boundary
107
+ in_middle_bit = true
108
+ next
109
+ end
110
+
111
+ unless in_middle_bit
112
+ before_after_lines.push candidate_line
113
+ next
114
+ end
115
+
116
+ #--
117
+ #-- Now we are definitely in the middle bit.
118
+ #-- Let's check for the middle end delimeter
119
+ #--
120
+ if candidate_line.downcase.include? end_delimeter.downcase
121
+ in_middle_bit = false
122
+ end
123
+
124
+ end
125
+
126
+ return before_after_lines
127
+
128
+ end
129
+
130
+
131
+ def middlle_bit begin_delimeter, end_delimeter
132
+
133
+ Throw.if_nil_or_empty_strings [ self, begin_delimeter, end_delimeter ]
134
+
135
+ middle_lines = []
136
+ in_middle_bit = false
137
+
138
+ self.each do |candidate_line|
139
+
140
+ is_middle_boundary = !in_middle_bit && candidate_line.downcase.include?(begin_delimeter.downcase)
141
+ if is_middle_boundary
142
+ in_middle_bit = true
143
+ next
144
+ end
145
+
146
+ end_of_middle = in_middle_bit && candidate_line.downcase.include?(end_delimeter.downcase)
147
+ return middle_lines if end_of_middle
148
+
149
+ #--
150
+ #-- We are definitely in the middle bit.
151
+ #--
152
+ middle_lines.push(candidate_line) if in_middle_bit
153
+
154
+ end
155
+
156
+ unreachable_str = "This point should be unreachable unless facts are ended."
157
+ raise RuntimeError.new unreachable_str
158
+
159
+ end
160
+
161
+
162
+ end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # --
4
+ # -- Reopen the core ruby Dirctory class and add the below methods to it.
5
+ # --
6
+ class Dir
7
+
8
+ # --
9
+ # -- Put all the files starting with the given string in
10
+ # -- alphabetical ascending order and then return the file
11
+ # -- that comes last.
12
+ # --
13
+ # -- Throw an exception if no file in this folder starts
14
+ # -- with the given string
15
+ # --
16
+ def ascii_order_file_starting_with starts_with_string
17
+
18
+ recently_added_file = nil
19
+ filepath_leadstr = File.join self.path, starts_with_string
20
+ Dir.glob("#{filepath_leadstr}*").sort.each do |candidate_file|
21
+
22
+ next if File.directory? candidate_file
23
+ recently_added_file = candidate_file
24
+
25
+ end
26
+
27
+ Throw.if_nil recently_added_file
28
+ Throw.if_not_exists recently_added_file
29
+ return recently_added_file
30
+
31
+ end
32
+
33
+
34
+
35
+ end
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # Reopen the core ruby File class and add the below methods to it.
4
+ class File
5
+
6
+ # Get the full filepath of a sister file that potentially lives
7
+ # in the same directory that the leaf class is executing from and
8
+ # has the same name as the leaf class but a different extension.
9
+ #
10
+ # == Usage
11
+ #
12
+ # If class OpenFoo:Bar extends class OpenFoo:Baz and we are looking
13
+ # for an INI file in the folder that OpenFoo:Bar lives in we can
14
+ # call this method within OpenFoo:Baz like this.
15
+ #
16
+ # ini_filepath = sister_filepath( "ini", :execute )
17
+ # # => /var/lib/gems/2.5.0/gems/fooey-0.2.99/lib/barry/bazzy/bar.ini
18
+ #
19
+ # == Common Implementation
20
+ #
21
+ # Object orientation scuppers the commonly used technique which
22
+ # derives the path from __FILE__
23
+ #
24
+ # class_directory = File.dirname( __FILE__ )
25
+ # leaf_class_name = self.class.name.split(":").last.downcase
26
+ # sister_filepath = File.join ( class_directory, "#{leaf_class_name}.#{extension}" )
27
+ #
28
+ # With object orientation - running the above code within the
29
+ # abstracted (parent) class would produce a resultant filepath
30
+ # based on the folder the parent class is in rather than the
31
+ # extended "concrete" class.
32
+ #
33
+ # == Value Proposition
34
+ #
35
+ # You can call this method from the parent (abstract) class and it
36
+ # will still correctly return the path to the potential sister file
37
+ # living in the directory that the leaf class sits in.
38
+ #
39
+ # Put differently - this extension method allows code executing in
40
+ # the parent class to correctly pinpoint a file in the directory of
41
+ # the leaf class be it in the same or a different folder.
42
+ #
43
+ # @param caller
44
+ # the calling class object usually passed in using <tt>self</tt>
45
+ #
46
+ # @param extension
47
+ # the extension of a sister file that carries the same simple
48
+ # (downcased) name of the leaf class of this method's caller.
49
+ #
50
+ # Omit the (segregating) period character when providing this
51
+ # extension parameter.
52
+ #
53
+ # @param method_symbol
54
+ # the method name in symbolic form of any method defined in
55
+ # the leaf class even if the method overrides one of the same
56
+ # name in the parent class.
57
+ #
58
+ # @return the filepath of a potential sister file living in the same
59
+ # directory as the class, bearing the same (downcased) name
60
+ # as the class with the specified extension.
61
+ def self.sister_filepath caller, extension, method_symbol
62
+
63
+ leaf_classname = caller.class.name.split(":").last.downcase
64
+ execute_method = caller.method( method_symbol )
65
+ leaf_classpath = execute_method.source_location.first
66
+ leaf_directory = File.dirname( leaf_classpath )
67
+ lower_filename = "#{leaf_classname}.#{extension}"
68
+ return File.join( leaf_directory, lower_filename )
69
+
70
+ end
71
+
72
+
73
+ # This method adds (logging its own contents) behaviour to
74
+ # the standard library {File} class. If this File points to
75
+ # a directory - that folder's single level content files are
76
+ # listed inside the logs.
77
+ #
78
+ # The <tt>DEBUG</tt> log level is used for logging. To change this
79
+ # create a new parameterized method.
80
+ #
81
+ # @param file_context [String] context denotes the whys and wherefores of this file.
82
+ def log_contents file_context
83
+
84
+ ## This will fail - add physical raise statement.
85
+ Throw.if_not_exists self
86
+
87
+ log.debug(x) { "# -- ------------------------------------------------------------------------ #" }
88
+ log.debug(x) { "# -- ------------------------------------------------------------------------ #" }
89
+ log.debug(x) { "# -- The File Path to Log => #{self}" }
90
+
91
+ hr_file_size = PrettyPrint.byte_size( File.size(self) )
92
+ dotless_extension = File.extname( self )[1..-1]
93
+ parent_dir_name = File.basename( File.dirname( self ) )
94
+ file_name = File.basename self
95
+ is_zip = dotless_extension.eql? "zip"
96
+
97
+ log.debug(x) { "# -- ------------------------------------------------------------------------ #" }
98
+ log.debug(x) { "# -- File Name => #{file_name}" }
99
+ log.debug(x) { "# -- File Size => #{hr_file_size}" }
100
+ log.debug(x) { "# -- File Type => #{file_context}" }
101
+ log.debug(x) { "# -- In Folder => #{parent_dir_name}" }
102
+ log.debug(x) { "# -- ------------------------------------------------------------------------ #" }
103
+
104
+ log.debug(x) { "File #{file_name} is a zip (binary) file." } if is_zip
105
+ return if is_zip
106
+
107
+ File.open( self, "r") do | file_obj |
108
+ line_no = 1
109
+ file_obj.each_line do | file_line |
110
+ line_num = sprintf '%03d', line_no
111
+ clean_line = file_line.chomp.strip
112
+ log.debug(x) { "# -- [#{line_num}] - #{clean_line}" }
113
+ line_no += 1
114
+ end
115
+ end
116
+
117
+ log.debug(x) { "# -- ------------------------------------------------------------------------ #" }
118
+ log.debug(x) { "# -- [#{file_context}] End of File [ #{File.basename(self)} ]" }
119
+ log.debug(x) { "# -- ------------------------------------------------------------------------ #" }
120
+
121
+ end
122
+
123
+ end
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # Reopen the core ruby Hash class and add the below methods to it.
4
+ class Hash
5
+
6
+ # This method adds (logging its own contents) behaviour to
7
+ # the standard library {Hash} class.
8
+ #
9
+ # @note This behaviour does not consider that SECRETS may be inside
10
+ # the key value maps - it logs itself without a care in the world.
11
+ # This functionality must be included if this behaviourr is used by
12
+ # any cryptography classes.
13
+ #
14
+ # The <tt>DEBUG</tt> log level is used for logging. To change this
15
+ # create a new parameterized method.
16
+ def log_contents
17
+
18
+ log.debug(x) { "# --- ----------------------------------------------" }
19
+ log.debug(x) { "# --- Map has [#{self.length}] key/value pairs." }
20
+ log.debug(x) { "# --- ----------------------------------------------" }
21
+
22
+ self.each do |the_key, the_value|
23
+
24
+ padded_key = sprintf '%-33s', the_key
25
+ log.debug(x) { "# --- #{padded_key} => #{the_value}" }
26
+
27
+ end
28
+
29
+ log.debug(x) { "# --- ----------------------------------------------" }
30
+
31
+ end
32
+
33
+ end