safedb 0.01.0001

Sign up to get free protection for your applications and to get access to all the features.
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