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