opensecret 0.0.913 → 0.0.941
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 +4 -4
- data/.yardopts +3 -0
- data/README.md +129 -19
- data/Rakefile +0 -9
- data/bin/opensecret +1 -1
- data/lib/{opensecret/plugins.io/cipher/crypto.rb → crypto/amalgam.rb} +6 -8
- data/lib/crypto/collect.rb +139 -0
- data/lib/crypto/engineer.rb +201 -0
- data/lib/crypto/verify.rb +33 -0
- data/lib/extension/array.rb +133 -0
- data/lib/{opensecret/additions → extension}/dir.rb +0 -0
- data/lib/extension/file.rb +56 -0
- data/lib/extension/hash.rb +33 -0
- data/lib/extension/string.rb +349 -0
- data/lib/factbase/facts.opensecret.io.ini +28 -0
- data/lib/logging/gem.logging.rb +133 -0
- data/lib/opensecret.rb +102 -45
- data/lib/opensecret/executors/crypt.keys/crypt.keys.ini +0 -53
- data/lib/session/{session.rb → attributes.rb} +60 -5
- data/lib/session/exceptions.rb +53 -0
- data/lib/session/fact.finder.rb +684 -0
- data/lib/session/user.home.rb +49 -0
- data/lib/usecase/usecase.rb +245 -0
- data/lib/usecase/usecases/init.rb +190 -0
- data/lib/usecase/usecases/on.rb +33 -0
- data/lib/usecase/usecases/safe.rb +95 -0
- data/lib/version.rb +1 -1
- metadata +22 -17
- data/lib/opensecret/additions/array.rb +0 -117
- data/lib/opensecret/additions/string.rb +0 -312
- data/lib/opensecret/commons/eco.cmdline.rb +0 -446
- data/lib/opensecret/eco.do.rb +0 -46
- data/lib/opensecret/plugins.io/error/eco.exceptions.rb +0 -24
- data/lib/opensecret/plugins.io/facts/fact.chars.rb +0 -66
- data/lib/opensecret/plugins.io/facts/fact.factor.rb +0 -156
- data/lib/opensecret/plugins.io/facts/fact.locator.rb +0 -105
- data/lib/opensecret/plugins.io/facts/fact.reader.rb +0 -137
- data/lib/opensecret/plugins.io/facts/fact.tree.rb +0 -661
- data/lib/opensecret/plugins.io/logs/log.object.rb +0 -89
- data/lib/opensecret/plugins.io/logs/logging.rb +0 -203
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# coding: utf-8
|
4
|
+
|
5
|
+
# opensession contains basic behaviour for managing a client only
|
6
|
+
# (serverless) session. Configuration directives are read and written
|
7
|
+
# from an INI off the home directory that is created when the session
|
8
|
+
# is first initiated.
|
9
|
+
module OpenSession
|
10
|
+
|
11
|
+
# This singleton class ascertains the users home folder in a manner
|
12
|
+
# agnositic to whether the software is running on Linux or Windows.
|
13
|
+
class Home
|
14
|
+
include Singleton
|
15
|
+
|
16
|
+
# This static behaviour reads the [home folder] just once.
|
17
|
+
def self.dir
|
18
|
+
return Home.instance.folder
|
19
|
+
end
|
20
|
+
|
21
|
+
# This static behaviour reads the [username] just once.
|
22
|
+
def self.usr
|
23
|
+
return Home.instance.username
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :folder
|
27
|
+
attr_reader :username
|
28
|
+
|
29
|
+
# Ascertain the home folder location.
|
30
|
+
def initialize
|
31
|
+
|
32
|
+
# On Windows the home folder may end with [AppData/Roaming].
|
33
|
+
extraneous_path = "/AppData/Roaming"
|
34
|
+
|
35
|
+
@folder = Dir.home
|
36
|
+
@username = @folder.split("/").last
|
37
|
+
return unless Dir.home.end_with? extraneous_path
|
38
|
+
|
39
|
+
# Remove the tail [AppData/Roaming] from the home path.
|
40
|
+
@folder = Dir.home.gsub extraneous_path, ""
|
41
|
+
@username = @folder.split("/").last
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
# opensession contains basic behaviour for managing a client only
|
5
|
+
# (serverless) session. Configuration directives are read and written
|
6
|
+
# from an INI off the home directory that is created when the session
|
7
|
+
# is first initiated.
|
8
|
+
#
|
9
|
+
# The session is expected to be formally closed down and that is
|
10
|
+
# reflected by explicitly deleting the configuration file. If this
|
11
|
+
# "session over" command is not issued a reasonable time limit is
|
12
|
+
# then invoked when the next session command is issued.
|
13
|
+
#
|
14
|
+
# This "session awakening" wipes the slate clean and starts afresh
|
15
|
+
# with regard to the two dimensional array of configuration directive
|
16
|
+
# pointers.
|
17
|
+
module OpenSession
|
18
|
+
|
19
|
+
|
20
|
+
require "session/exceptions"
|
21
|
+
require "session/fact.finder"
|
22
|
+
|
23
|
+
require "extension/array"
|
24
|
+
require "extension/dir"
|
25
|
+
require "extension/string"
|
26
|
+
|
27
|
+
|
28
|
+
# An opensession use case is designed to be extended and does preparatory
|
29
|
+
# work to create favourable and useful conditions to make use cases readable,
|
30
|
+
# less repetitive, simpler and concise.
|
31
|
+
class UseCase
|
32
|
+
|
33
|
+
|
34
|
+
# Execute the use cases's flow from beginning when
|
35
|
+
# you validate the input and parameters through the
|
36
|
+
# memorize, execute and the final cleanup.
|
37
|
+
def flow_of_events
|
38
|
+
|
39
|
+
check_pre_conditions
|
40
|
+
pre_memorize
|
41
|
+
execute
|
42
|
+
post_memorize
|
43
|
+
cleanup
|
44
|
+
check_post_conditions
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
# Validate the input parameters and check that the current
|
51
|
+
# state is perfect for executing the use case.
|
52
|
+
#
|
53
|
+
# If either of the above fail - the validation function should
|
54
|
+
# set a human readable string and then throw an exception.
|
55
|
+
def check_pre_conditions
|
56
|
+
|
57
|
+
|
58
|
+
begin
|
59
|
+
|
60
|
+
pre_validation
|
61
|
+
|
62
|
+
rescue OpenSessionError => e
|
63
|
+
|
64
|
+
puts ""
|
65
|
+
puts "Your command did not complete successfully."
|
66
|
+
puts "Pre validation checks failed."
|
67
|
+
puts ""
|
68
|
+
puts " => #{e.message}"
|
69
|
+
#### puts " => #{e.culprit}"
|
70
|
+
puts ""
|
71
|
+
abort e.message
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# After the main flow of events certain state conditions
|
79
|
+
# must hold true thus demonstrating that the observable
|
80
|
+
# value has indeed ben delivered.
|
81
|
+
#
|
82
|
+
# Child classes should subclass this method and place any
|
83
|
+
# post execution (post condition) checks in it and then
|
84
|
+
# make a call to this method through the "super" keyword.
|
85
|
+
def check_post_conditions
|
86
|
+
begin
|
87
|
+
|
88
|
+
post_validation
|
89
|
+
|
90
|
+
rescue OpenSessionError => e
|
91
|
+
|
92
|
+
puts ""
|
93
|
+
puts "Your command did not complete successfully."
|
94
|
+
puts "Post validation checks failed."
|
95
|
+
puts ""
|
96
|
+
puts " => #{e.message}"
|
97
|
+
#### puts " => #{e.culprit}"
|
98
|
+
puts ""
|
99
|
+
abort e.message
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
# Child classes should subclass this method and place any
|
108
|
+
# post execution (post condition) checks in it and then
|
109
|
+
# make a call to this method through the "super" keyword if
|
110
|
+
# this method gets any global behaviour in it worth calling.
|
111
|
+
def post_validation
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
# (Pre) memorize adds to permanent storage a configuration
|
118
|
+
# directive and its value <tt>provided by the user</tt>
|
119
|
+
# primarily because it avoids repitition in subsequent
|
120
|
+
# use case commands.
|
121
|
+
def pre_memorize
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
# Execute the main flow of events of the use case. Any
|
128
|
+
# exceptions thrown are captured and if the instance
|
129
|
+
# variale [@human_readable_message] is set - tell the
|
130
|
+
# user about it. Without any message - just tell the
|
131
|
+
# user something went wrong and tell them where the logs
|
132
|
+
# are that might carry more information.
|
133
|
+
def execute
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
# (Post) memorize will add to permanent storage) any
|
140
|
+
# key/values that have been derived or looked up during
|
141
|
+
# use case execution. This allows subsequent use case
|
142
|
+
# commands to
|
143
|
+
#
|
144
|
+
# - capitalize on
|
145
|
+
# - take direction from
|
146
|
+
# - and/or simply use
|
147
|
+
#
|
148
|
+
# the value in later use cases or processing.
|
149
|
+
def post_memorize
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
# If the use case validation went well, the memorization
|
156
|
+
# went well the
|
157
|
+
def cleanup
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
# Resolve +two attached fact files+ with the first being general and
|
164
|
+
# relevant to every use case in the parameter specified domain, and
|
165
|
+
# the second being specific to this use case.
|
166
|
+
#
|
167
|
+
# The <b><em>general factfile</em></b> is expected to be on the class (load) path
|
168
|
+
# and below are paths for a generic domain name and for an example domain
|
169
|
+
# name of *openpost.io*
|
170
|
+
#
|
171
|
+
# - <tt>factbase/facts.<<domain>>.ini</tt>
|
172
|
+
# - <tt>factbase/facts.openpost.io.ini</tt>
|
173
|
+
#
|
174
|
+
# The <b><em>use case specific factfile</em></b> is also _expected_ to be on the class
|
175
|
+
# (load) path and below is a generic and a use case specific path using
|
176
|
+
# the example <tt>deliver</tt> use case.
|
177
|
+
#
|
178
|
+
# - <tt>factbase/facts.<<uc-name>>.usecase.ini</tt>
|
179
|
+
# - <tt>factbase/facts.deliver.usecase.ini</tt>
|
180
|
+
#
|
181
|
+
# The domain name is delivered in the parameter whilst the use case
|
182
|
+
# name is derived from the (extension) class name.
|
183
|
+
#
|
184
|
+
# @param fact_domain [String] domain of the general attached factfile
|
185
|
+
# @return [Hash] a 2d (two-dimensional) hash of keys and their corresponding values
|
186
|
+
def attached_facts fact_domain
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
### def path_to_resources
|
194
|
+
### File.join(File.dirname(File.expand_path(__FILE__)), '../path/to/resources')
|
195
|
+
### end
|
196
|
+
|
197
|
+
# This use case is initialized primary by resolving the configured
|
198
|
+
# +general and use case specific facts+. To access the general facts,
|
199
|
+
# a domain name is expected in the parameter delegated by the extension
|
200
|
+
# use case classes.
|
201
|
+
def initialize
|
202
|
+
|
203
|
+
|
204
|
+
class_name = self.class.name.downcase.split(":").last
|
205
|
+
is_pre_init_usecase = [ "safe", "store", "email" ].include? class_name
|
206
|
+
return if is_pre_init_usecase
|
207
|
+
|
208
|
+
@ucid_str = self.class.name.do_flatten
|
209
|
+
@ucid_sym = @ucid_str.gsub(".", "_").to_sym
|
210
|
+
|
211
|
+
OpenSession::FactFind.instance.instantiate @ucid_str
|
212
|
+
OpenSession::FactFind.instance.assimilate "facts.opensecret.io.ini"
|
213
|
+
|
214
|
+
@c = OpenSession::FactFind.instance.f
|
215
|
+
@i = OpenSession::FactFind.instance.i
|
216
|
+
@p = OpenSession::FactFind.instance.f[@ucid_str]
|
217
|
+
|
218
|
+
@time_stamp = OpenSession::Stamp.instance
|
219
|
+
=begin
|
220
|
+
@eco_id_str = SnapFlat.do self.class.name
|
221
|
+
@eco_id_sym = @eco_id_str.gsub(".", "_").to_sym
|
222
|
+
@plugin_path = plugin_src_dir
|
223
|
+
|
224
|
+
FactTree.instance.instantiate @eco_id_str, @plugin_path
|
225
|
+
FactTree.instance.assimilate_instance_facts
|
226
|
+
|
227
|
+
instantiate_runtime FactTree.instance.f
|
228
|
+
|
229
|
+
FactTree.instance.identify_my_workstation
|
230
|
+
FactTree.instance.assimilate_station_facts
|
231
|
+
FactTree.instance.assimilate_plugin_facts
|
232
|
+
FactTree.instance.assimilate_general_facts
|
233
|
+
|
234
|
+
@c = FactTree.instance.f
|
235
|
+
@i = FactTree.instance.i
|
236
|
+
@p = FactTree.instance.f[@eco_id_sym]
|
237
|
+
=end
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
|
245
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
module OpenSecret
|
4
|
+
|
5
|
+
require 'openssl'
|
6
|
+
|
7
|
+
# --> require 'filesize'
|
8
|
+
# --> require 'tmpdir'
|
9
|
+
# --> require 'base64'
|
10
|
+
# --> require 'etc'
|
11
|
+
# --> require 'securerandom'
|
12
|
+
# --> require 'digest'
|
13
|
+
# --> require 'net/http'
|
14
|
+
# --> require 'net/ssh'
|
15
|
+
# --> require 'net/scp'
|
16
|
+
# --> require 'aws-sdk'
|
17
|
+
# --> require 'aws-sdk-resources'
|
18
|
+
# --> require 'nokogiri'
|
19
|
+
# --> require 'io/console'
|
20
|
+
|
21
|
+
require "session/exceptions"
|
22
|
+
require "crypto/collect"
|
23
|
+
|
24
|
+
# Throw this error if the configured safe directory points to a file.
|
25
|
+
class SafeDirectoryIsFile < OpenSession::OpenSessionError; end;
|
26
|
+
# Throw this error if safe directory path is either nil or empty.
|
27
|
+
class SafeDirNotConfigured < OpenSession::OpenSessionError; end;
|
28
|
+
# Throw this error if the email address is nil, empty or less than 5 characters.
|
29
|
+
class EmailAddrNotConfigured < OpenSession::OpenSessionError; end;
|
30
|
+
# Throw this error if the store url is either nil or empty.
|
31
|
+
class StoreUrlNotConfigured < OpenSession::OpenSessionError; end;
|
32
|
+
# Throw if "prime folder" name occurs 2 or more times in the path.
|
33
|
+
class SafePrimeNameRepeated < OpenSession::OpenSessionError; end;
|
34
|
+
# Throw if "prime folder" name occurs 2 or more times in the path.
|
35
|
+
class SafePrimeNameNotAtEnd < OpenSession::OpenSessionError; end;
|
36
|
+
|
37
|
+
|
38
|
+
# The <tt>init use case</tt> initializes +opensecret+ thus preparing it
|
39
|
+
# for the ability to lock secrets, unlock them, transport their keys and
|
40
|
+
# much more.
|
41
|
+
#
|
42
|
+
# Like all use cases, {self} validates to ensure that the pre-conditions
|
43
|
+
# have been met and then proceeds to execute its core offering and deliver
|
44
|
+
# observable value.
|
45
|
+
#
|
46
|
+
# == Observable Value
|
47
|
+
#
|
48
|
+
# The observable value delivered by init boils down to
|
49
|
+
#
|
50
|
+
# - <tt>4 crypted keys</tt> on USB (or phone) in the +master.keys+ folder.
|
51
|
+
# - <tt>1 crypted workstation key</tt> under the workstation's home directory
|
52
|
+
# - one human password stashed deep inside your brain
|
53
|
+
#
|
54
|
+
# +No cloud or other external access+ occurs as per the opensecret policy.
|
55
|
+
class Init < OpenSession::UseCase
|
56
|
+
|
57
|
+
|
58
|
+
attr_writer :safe_path, :email_addr, :store_url
|
59
|
+
@@context_name = "opensecret"
|
60
|
+
|
61
|
+
# The init use case initializes [opensecret] making it ready to lock and
|
62
|
+
# unlock secrets.
|
63
|
+
#
|
64
|
+
# == Main Flow of Events
|
65
|
+
#
|
66
|
+
# So in preparation to execute its modus operandi encryption,
|
67
|
+
# decryption and (if required) transportation use cases opensecret will
|
68
|
+
#
|
69
|
+
# - +collect the human password+ (twice), verify robustness (and throw away asap)
|
70
|
+
# - +manufacture workstation key+ that will be encrypted b4 it rests on machine
|
71
|
+
# - +create amalgamated human/workstation password+ for locking the private key
|
72
|
+
# - +create a long cryptographically strong symmetric encryption key+
|
73
|
+
# - +encrypt workstation key+ into <tt>.opensecret/<email>/machine.password.cipher.txt</tt>
|
74
|
+
# - +encrypt workstation encryption key+ with human password and email address
|
75
|
+
# - then write into <tt>safe</tt> under <tt>machine.password.key.cipher.txt</tt>
|
76
|
+
# - +create a super 8,192 bit private/public key pair+
|
77
|
+
# - use +amalgamated password to encrypt the private key+
|
78
|
+
# - write to <tt><SAFE>/<email>/master.keys/master.private.key.crypt.txt</tt>
|
79
|
+
# - +create robust salt+ for hashing the path to the (crypted) keys and ciphers
|
80
|
+
# - use +public key to encrypt the salt+
|
81
|
+
# - write crypted salt to <tt><SAFE>/<email>/master.keys/master.path.salt.crypt.txt</tt>
|
82
|
+
# - now +use the public key to encrypt itself+
|
83
|
+
# - write public key crypt to <tt><SAFE>/<email>/master.keys/master.public.key.crypt.txt</tt>
|
84
|
+
# - +create the cryptographic keystore+ inside the safe
|
85
|
+
#
|
86
|
+
# Variables should be first zeroed and then deleted immediately after their last use.
|
87
|
+
# +We need to avoid sensitive keys hanging around waiting for the garbage collector.+
|
88
|
+
# If necessary - sensitive areas such as these could be implemented in Go or C which
|
89
|
+
# deliver control of exactly where, when and how memory is allocaed, and zeroed out.
|
90
|
+
#
|
91
|
+
# == Observable Value
|
92
|
+
#
|
93
|
+
# The <tt>init use case</tt> observable value post-conditions are
|
94
|
+
#
|
95
|
+
# - <tt>4 crypted keys</tt> on USB (or phone) in the +master.keys+ folder.
|
96
|
+
# - <tt>1 crypted workstation key</tt> under the workstation's home directory
|
97
|
+
# - one human password stashed deep inside your brain
|
98
|
+
#
|
99
|
+
# == New Feature | Prevent Public Key Switch Attacks
|
100
|
+
#
|
101
|
+
# +Public Key switch attacks+ try to access <tt>future secrets</tt> - not the ones
|
102
|
+
# already encrypted.
|
103
|
+
#
|
104
|
+
# Their goal is <tt>unwitting encryption using a public key they control.</tt>
|
105
|
+
#
|
106
|
+
# A new feature should tie down the signatures of the 5 encrypted files (4 on
|
107
|
+
# usb/phone store and 1 on the machine) within a second workstation file and use
|
108
|
+
# first the human password and then the public key to lock it down.
|
109
|
+
#
|
110
|
+
# This action thwarts (usb key) switch attacks where the attacker knows the human
|
111
|
+
# password and has access to the USB key for a time.
|
112
|
+
#
|
113
|
+
def execute
|
114
|
+
|
115
|
+
natural_password = Collect.secret_text @c[:global][:min_passwd_len], @c[:global][:prompt_1], @c[:global][:prompt_2]
|
116
|
+
|
117
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
118
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
119
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
120
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
121
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
122
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
123
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
124
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
125
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
126
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
127
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
128
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
129
|
+
##########------------> START FROM HERE (aside from prompt bug (check facts) all good.
|
130
|
+
machine_password = Crypto.get_machine_password natural_password.length, @p[:ratio]
|
131
|
+
amalgam_password = Crypto.get_amalgam_password natural_password, machine_password, @p[:ratio]
|
132
|
+
|
133
|
+
asymmetric_keys = OpenSSL::PKey::RSA.new @p[:bit_key_size]
|
134
|
+
secured_keytext = asymmetric_keys.export @p[:key_cipher], amalgam_password
|
135
|
+
public_key_text = asymmetric_keys.public_key.to_pem
|
136
|
+
|
137
|
+
Dir.mkdir @p[:secret_keydir] unless File.exists? @p[:secret_keydir]
|
138
|
+
File.write @p[:secret_keypath], secured_keytext
|
139
|
+
|
140
|
+
Crypto.print_secret_env_var @p[:env_var_name], machine_password
|
141
|
+
|
142
|
+
GitFlow.do_clone_repo @p[:public_gitrepo], @p[:local_gitrepo]
|
143
|
+
FileUtils.mkdir_p @p[:public_keydir]
|
144
|
+
File.write @p[:public_keypath], public_key_text
|
145
|
+
GitFlow.push @p[:local_gitrepo], @p[:public_keyname], @c[:time][:stamp]
|
146
|
+
|
147
|
+
# exit
|
148
|
+
# key4_pem = File.read 'private.secure.pem'
|
149
|
+
# pass_phrase = 'superduperpasswordistoBeENTEREDRIGHT1234HereandRightNOW'
|
150
|
+
# key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
|
151
|
+
# decrypted_text = key4.private_decrypt(Base64.decode64(encrypted_string))
|
152
|
+
|
153
|
+
# print "\nHey we have done the decryption.\n", "\n"
|
154
|
+
# print decrypted_text, "\n"
|
155
|
+
|
156
|
+
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
# Perform pre-conditional validations in preparation to executing the main flow
|
162
|
+
# of events for this use case. This method may throw the below exceptions.
|
163
|
+
#
|
164
|
+
# @raise [SafeDirNotConfigured] if the safe's url has not been configured
|
165
|
+
# @raise [EmailAddrNotConfigured] if the email address has not been configured
|
166
|
+
# @raise [StoreUrlNotConfigured] if the crypt store url is not configured
|
167
|
+
def pre_validation
|
168
|
+
|
169
|
+
@safe_path = OpenSession::Attributes.instance.get_value @@context_name, "safe"
|
170
|
+
safe_configured = File.exists?( @safe_path ) && File.directory?( @safe_path )
|
171
|
+
@err_msg = "[safe] storage not yet configured. Try =>] opensecret safe /folder/path"
|
172
|
+
raise SafeDirNotConfigured.new @err_msg, @safe_path unless safe_configured
|
173
|
+
|
174
|
+
@email_addr = OpenSession::Attributes.instance.get_value @@context_name, "email"
|
175
|
+
email_configured = !@email_addr.nil? && !@email_addr.empty? && @email_addr.length > 4
|
176
|
+
@err_msg = "viable [email address] not configured. Try =>] opensecret email joe@example.com"
|
177
|
+
raise EmailAddrNotConfigured.new @err_msg, @email_addr unless email_configured
|
178
|
+
|
179
|
+
@store_url = OpenSession::Attributes.instance.get_value @@context_name, "store"
|
180
|
+
store_configured = !@store_url.nil? && !@store_url.empty? && @store_url.length > 0
|
181
|
+
@err_msg = "crypt [store url] not configured. Try =>] opensecret store /path/to/crypt"
|
182
|
+
raise StoreUrlNotConfigured.new @err_msg, @store_url unless store_configured
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
end
|