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,28 @@
|
|
1
|
+
|
2
|
+
[global]
|
3
|
+
|
4
|
+
min.passwd.len = rb>> 16
|
5
|
+
nickname = godzilla
|
6
|
+
root.domain = devopswiki.co.uk
|
7
|
+
env.var.name = SECRET_MATERIAL
|
8
|
+
ratio = rb>> 3
|
9
|
+
bit.key.size = rb>> 8192
|
10
|
+
key.cipher = rb>> OpenSSL::Cipher.new 'AES-256-CBC'
|
11
|
+
secret.keyname = master.private.key.crypt.txt
|
12
|
+
secret.keydir = rb>> OpenSession::Attributes.instance.get_value "opensecret", "safe"
|
13
|
+
secret.keypath = rb>> File.join @s[:secret_keydir], @s[:secret_keyname]
|
14
|
+
|
15
|
+
repo.name = material_data
|
16
|
+
|
17
|
+
## local.gitrepo = rb>> File.join @i[:dir], @s[:repo_name]
|
18
|
+
|
19
|
+
## public.gitrepo = https://www.eco-platform.co.uk/content/material.data.git
|
20
|
+
## public.dirname = public_keys
|
21
|
+
## public.keyroute = rb>> File.join @s[:root_domain], @s[:public_dirname]
|
22
|
+
## public.keydir = rb>> File.join @s[:local_gitrepo], @s[:public_keyroute]
|
23
|
+
## public.keyname = rb>> "public_key." + @s[:nickname] + dot + @s[:root_domain] + ".txt"
|
24
|
+
## public.keypath = rb>> File.join @s[:public_keydir], @s[:public_keyname]
|
25
|
+
|
26
|
+
prompt.1 = Enter a Robust Password
|
27
|
+
prompt.2 = Re-enter that Password
|
28
|
+
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require "logger"
|
2
|
+
require "session/user.home"
|
3
|
+
|
4
|
+
# [MIXIN] magic is deployed to hand out DevOps quality logging
|
5
|
+
# features to any class that includes the logging module.
|
6
|
+
#
|
7
|
+
# When logging facilities are not ready we need to log just to
|
8
|
+
# stdout but when they are we need to use them.
|
9
|
+
#
|
10
|
+
# mixin power enables one class to give the logfile path and all
|
11
|
+
# classes will suddenly retrieve a another logger and use that.
|
12
|
+
#
|
13
|
+
# include Logging
|
14
|
+
# def doImportant
|
15
|
+
# log.warn(ere) "unhappy about doing this"
|
16
|
+
# do_anyway
|
17
|
+
# log.debug(ere) "all good it was okay"
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# So what are Mixins?
|
21
|
+
#
|
22
|
+
# Refer to the below link for excellent coverage of mixins.
|
23
|
+
# @see http://ruby-doc.com/docs/ProgrammingRuby/html/tut_modules.html
|
24
|
+
#
|
25
|
+
module OpenLogger
|
26
|
+
|
27
|
+
@@gem_name = "opensecret"
|
28
|
+
@@gem_base = File.join OpenSession::Home.dir, ".#{@@gem_name}"
|
29
|
+
FileUtils.mkdir_p @@gem_base unless File.exists? @@gem_base
|
30
|
+
@@log_path = File.join @@gem_base, "opensecret-cli-activity.log"
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
# Classes that include (MIXIN) this logging module will
|
35
|
+
# have access to this logger method.
|
36
|
+
#
|
37
|
+
# [memoization] is implemented here for performance and
|
38
|
+
# will only initiate a logger under 2 circumstances
|
39
|
+
#
|
40
|
+
# [1] - the first call (returns a STDOUT logger)
|
41
|
+
# [2] - the call after the logfile path is set
|
42
|
+
# (returns a more sophisticated logger)
|
43
|
+
def log
|
44
|
+
|
45
|
+
@@log_class ||= get_logger
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# This Ruby behavioural snippet allows the logger to print 3 crucial
|
51
|
+
# pieces of information for the troubleshooter (detective) so that they
|
52
|
+
# may ascertain
|
53
|
+
#
|
54
|
+
# - the [module] the logging call came from
|
55
|
+
# - the [method] the logging call came from
|
56
|
+
# - the [line number] the logging call is at
|
57
|
+
#
|
58
|
+
# To use this method you can make calls like this
|
59
|
+
#
|
60
|
+
# - log.info(x) { "Log many things about where I am now." }
|
61
|
+
# - log.warn(x) { "Log many things about where I am now." }
|
62
|
+
#
|
63
|
+
def x
|
64
|
+
|
65
|
+
module_name = File.basename caller_locations(1,1).first.absolute_path, ".rb"
|
66
|
+
method_name = caller_locations(1,1).first.base_label
|
67
|
+
line_number = caller_locations(1,1).first.lineno
|
68
|
+
|
69
|
+
"#{module_name} | #{method_name} | (line #{line_number}) "
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
# This method returns an initialized logger.
|
75
|
+
#
|
76
|
+
# The logger returned may write to
|
77
|
+
#
|
78
|
+
# - a simple file
|
79
|
+
# - a service like fluentd
|
80
|
+
# - a message queue
|
81
|
+
# - a nosql database
|
82
|
+
# - all of the above
|
83
|
+
#
|
84
|
+
# Not that [memoization] should be used so that this method
|
85
|
+
# gets called ideally just once although in practise it may
|
86
|
+
# turn out to be a handful of times.
|
87
|
+
#
|
88
|
+
# @return [Logger] return an initialized logger object
|
89
|
+
def get_logger
|
90
|
+
|
91
|
+
file_logger = Logger.new @@log_path
|
92
|
+
original_formatter = Logger::Formatter.new
|
93
|
+
|
94
|
+
file_logger.formatter = proc { |severity, datetime, progname, msg|
|
95
|
+
original_formatter.call( severity, datetime, progname, msg.dump.chomp.strip )
|
96
|
+
}
|
97
|
+
|
98
|
+
return file_logger
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
# Overtly long file paths in the log files sometimes hamper readability
|
104
|
+
# and this method improves the situation by returning just the two
|
105
|
+
# immediate ancestors of the file (or folder) path.
|
106
|
+
#
|
107
|
+
# @example A really long input like
|
108
|
+
# <tt>/home/joe/project/degrees/math/2020</tt>
|
109
|
+
# is reduced to
|
110
|
+
# <tt>degrees/math/2020</tt>
|
111
|
+
#
|
112
|
+
# So this method returns the name of the grandparent folder then parent folder
|
113
|
+
# and then the most significant file (or folder) name.
|
114
|
+
#
|
115
|
+
# When this is not possible due to the filepath being colisively near the
|
116
|
+
# filesystem's root, it returns the parameter name.
|
117
|
+
#
|
118
|
+
# @param object_path [String] overtly long path that will be made more readable
|
119
|
+
# @return [String] the (separated) three most significant path name segments
|
120
|
+
def nickname object_path
|
121
|
+
|
122
|
+
object_name = File.basename object_path
|
123
|
+
parent_folder = File.dirname object_path
|
124
|
+
parent_name = File.basename parent_folder
|
125
|
+
granny_folder = File.dirname parent_folder
|
126
|
+
granny_name = File.basename granny_folder
|
127
|
+
|
128
|
+
return [granny_name,parent_name,object_name].join("/")
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
end
|
data/lib/opensecret.rb
CHANGED
@@ -1,10 +1,19 @@
|
|
1
1
|
require "thor"
|
2
|
+
require "fileutils"
|
2
3
|
require "session/time.stamp"
|
3
|
-
require "session/
|
4
|
+
require "session/attributes"
|
5
|
+
require "logging/gem.logging"
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
7
|
+
require "usecase/usecases/safe"
|
8
|
+
require "usecase/usecases/init"
|
9
|
+
|
10
|
+
include OpenLogger
|
11
|
+
|
12
|
+
# This standard out sync command flushes text destined for STDOUT immediately,
|
13
|
+
# without waiting either for a full cache or script completion.
|
14
|
+
$stdout.sync = true
|
15
|
+
|
16
|
+
# This command line processor extends the Thor gem CLI tools in order to
|
8
17
|
#
|
9
18
|
# - read the posted commands, options and switches
|
10
19
|
# - maps the incoming string data to objects
|
@@ -13,7 +22,9 @@ require "session/session"
|
|
13
22
|
# - ensure that the parameter values are in range
|
14
23
|
# - delegate processing to the registered handlers
|
15
24
|
#
|
16
|
-
class
|
25
|
+
class CliInterpreter < Thor
|
26
|
+
|
27
|
+
log.info(x) {"Wake up loggers."}
|
17
28
|
|
18
29
|
#
|
19
30
|
# This class option allows every CLI call the option to include
|
@@ -22,11 +33,21 @@ class CommandProcessor < Thor
|
|
22
33
|
#
|
23
34
|
class_option :debug, :type => :boolean
|
24
35
|
|
36
|
+
|
37
|
+
|
38
|
+
# Description of the init configuration call.
|
39
|
+
desc "init", "initialize secret keys and check access to the crypt store"
|
40
|
+
|
41
|
+
# Initialize secret keys and check access to the crypt store.
|
25
42
|
#
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
43
|
+
# - checks the installed configuration.
|
44
|
+
def init
|
45
|
+
OpenSecret::Init.new.flow_of_events
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
# Description of the mandatory safe and (safe directory) configuration.
|
50
|
+
desc "safe SAFE_DIR", "SAFE_DIR full path to the (ideally USB key) storage location"
|
30
51
|
|
31
52
|
#
|
32
53
|
# A USB key drive is the ideal store for the encrypted private
|
@@ -37,59 +58,95 @@ class CommandProcessor < Thor
|
|
37
58
|
# - if not, it attempts to create the path
|
38
59
|
# - if successful it's written into HOME/.opensecret/opensecret.keydir.txt
|
39
60
|
#
|
40
|
-
# @
|
61
|
+
# @param safe_dir [String] the path to USB key for storing encrypted keys
|
62
|
+
#
|
63
|
+
def safe safe_dir
|
64
|
+
|
65
|
+
configure_safe_uc = OpenSecret::Safe.new
|
66
|
+
configure_safe_uc.safe_path = safe_dir
|
67
|
+
configure_safe_uc.flow_of_events
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
#
|
73
|
+
# Description of the email-address that is unique
|
74
|
+
# for the domain in question.
|
41
75
|
#
|
42
|
-
|
76
|
+
desc "email EMAIL_ADDRESS", "EMAIL_ADDRESS Your email address unique for the domain."
|
77
|
+
|
43
78
|
#
|
44
|
-
#
|
45
|
-
#
|
79
|
+
# This method collects the email address that is unique for the domain in
|
80
|
+
# question. For the email address to be valid it must consist of only alphanumerics,
|
81
|
+
# underscores, periods, hyphens and (at most) one @ symbol.
|
46
82
|
#
|
47
|
-
#
|
83
|
+
# Note that underscores, periods, hyphens and @ symbol are permissable if not
|
84
|
+
# at the start or end of the email address nor can they appear consecutively.
|
48
85
|
#
|
49
|
-
|
86
|
+
# <tt>a@b.cd</tt> is the minimum size of an externally addressable email
|
87
|
+
# address so 6 or more characters is enforced by this configuation method.
|
88
|
+
#
|
89
|
+
# email validation will be added to opensecret including
|
90
|
+
# - validation of the email address character array
|
91
|
+
# - proof of control and ownership of the email address
|
92
|
+
#
|
93
|
+
# If an email address already exists within the domain section of the
|
94
|
+
# configuration file, it is overwritten. If there is no configuration
|
95
|
+
# file yet, one is created within the auspices of the home directory.
|
96
|
+
#
|
97
|
+
# @param email_address [String] email address of the user (eg a@b.cd)
|
98
|
+
#
|
99
|
+
def email email_address
|
50
100
|
|
51
|
-
if
|
52
|
-
abort "The
|
101
|
+
if email_address.length < 6
|
102
|
+
abort "The tiniest (externally accessible) email address [a@b.cd] has 6 characters."
|
53
103
|
end
|
54
104
|
|
55
|
-
|
105
|
+
OpenSession::Attributes.stash "opensecret", "email", email_address
|
56
106
|
|
57
|
-
|
58
|
-
secret_session.write_keyvalue "opensecret", "key_folder", keypath
|
59
|
-
session_file = secret_session.get_filepath "opensecret"
|
107
|
+
end
|
60
108
|
|
61
|
-
puts ""
|
62
|
-
puts "private key directory => [ #{keypath} ]"
|
63
|
-
puts "session configuration => [ #{session_file} ]"
|
64
|
-
puts "session time stamp is => [ #{OpenSession::Stamp.yyjjj_hhmm_sst} ]"
|
65
|
-
puts ""
|
66
109
|
|
67
|
-
|
110
|
+
desc "store STORE_URL", "STORE_URL denotes the location of the backend crypt store"
|
68
111
|
|
69
112
|
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
# - an opensecret domain like » **lecturers@harvard**
|
73
|
-
# - the url to a backend store like Git, S3 or an SSH accessible drive.
|
74
|
-
#
|
75
|
-
# The domain will be extended to cover verified internet domains.
|
76
|
-
# They will also latch onto LDAP domains so when admins add, revoke
|
77
|
-
# or remove users, their opensecret access is adjusted accordingly.
|
113
|
+
# Here we define the location (the URL) of the crypt store. The crypt store will hold
|
114
|
+
# the cipher text and is known as <tt>backend storage</tt>.
|
78
115
|
#
|
79
|
-
#
|
116
|
+
# The planned list of backend storage systems (each onlined with a plugin), is
|
80
117
|
#
|
81
|
-
#
|
82
|
-
#
|
118
|
+
# - Git (including GitHub, GitLab, BitBucket, OpenGit and private repositories.
|
119
|
+
# - S3 Buckets from the Amazon Web Services (AWS) cloud.
|
120
|
+
# - SSH, SCP, SFTP connected file-systems
|
121
|
+
# - network storage including Samba, NFS, VMWare vSAN and
|
122
|
+
# - GoogleDrive (only Windows has suitable synchronized support).
|
83
123
|
#
|
84
|
-
#
|
124
|
+
# @param store_url [String] the STORE_URL identifying a filesystem or Git or S3 storage location
|
125
|
+
def store store_url
|
85
126
|
|
86
|
-
# ---> OpenSecret::Crypto.register_domain domain, store_url
|
87
127
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
128
|
+
if store_url.strip.length < 3
|
129
|
+
abort "4 characters is the minimum domain name length."
|
130
|
+
end
|
131
|
+
|
132
|
+
OpenSession::Attributes.stash "opensecret", "store", store_url.strip
|
133
|
+
|
134
|
+
### if( File.exists?( store_url ) && !(File.directory? store_url) )
|
135
|
+
### abort "The store url path cannot be a file => #{store_url}"
|
136
|
+
### end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
desc "on", "Open a session to encrypt (lock) one or more secrets"
|
142
|
+
|
143
|
+
# The [on] message tells opensecret to prepare to lock one or more secrets.
|
144
|
+
def on
|
145
|
+
|
146
|
+
#### FileUtils.mkdir_p store_url unless File.exists? store_url
|
147
|
+
#### OpenSession::Attributes.stash "opensecret", "store.id.#{store_id}", store_url
|
148
|
+
|
149
|
+
end
|
92
150
|
|
93
|
-
# ---> end
|
94
151
|
|
95
152
|
end
|
@@ -24,56 +24,3 @@ public.keypath = e>> File.join @s[:public_keydir], @s[:public_keyname]
|
|
24
24
|
prompt.1 = Enter a Robust Password
|
25
25
|
prompt.2 = Re-enter that Password
|
26
26
|
|
27
|
-
#--
|
28
|
-
#-- ------------------------------------------
|
29
|
-
#-- How to Add the Secret Material on Windows
|
30
|
-
#-- ------------------------------------------
|
31
|
-
#--
|
32
|
-
#-- Check that the variable is not set.
|
33
|
-
#-- $ set
|
34
|
-
#--
|
35
|
-
#-- Run the commands below and then acquire another
|
36
|
-
#-- command prompt or emacs/cygwin window.
|
37
|
-
#--
|
38
|
-
#-- $ setx SECRET_MATERIAL ABC123
|
39
|
-
#-- $ set
|
40
|
-
#--
|
41
|
-
#-- Check (with last command) on new prompt that the
|
42
|
-
#-- environment variable is now set.
|
43
|
-
#--
|
44
|
-
#-- ----------------------------------------
|
45
|
-
#-- How to Add the Secret Material (Linux)
|
46
|
-
#-- ----------------------------------------
|
47
|
-
#--
|
48
|
-
#-- Check that the variable is not set.
|
49
|
-
#-- $ printenv | sort
|
50
|
-
#--
|
51
|
-
#-- Run the commands below and then reboot.
|
52
|
-
#-- (Ensure that the whole disk is encrypted so that the
|
53
|
-
#-- /etc/environment file cannot be accessed if your desktop
|
54
|
-
#-- or laptop is stolen.
|
55
|
-
#--
|
56
|
-
#-- $ sudo chmod 666 /etc/environment
|
57
|
-
#-- $ sudo echo "SECRET_MATERIAL=ABC123" >> /etc/environment
|
58
|
-
#-- $ sudo chmod 644 /etc/environment
|
59
|
-
#-- $ printenv | sort
|
60
|
-
#--
|
61
|
-
#-- Check (with last command) after the reboot to ensure
|
62
|
-
#-- that the environment variable is now set.
|
63
|
-
#--
|
64
|
-
#-- ---------------------------------------------------
|
65
|
-
#-- How to TEMPORARILY Add the Secret Material (Linux)
|
66
|
-
#-- ---------------------------------------------------
|
67
|
-
#--
|
68
|
-
#-- Check that the variable is not set.
|
69
|
-
#-- $ printenv | sort
|
70
|
-
#--
|
71
|
-
#-- We are only adding for the session (perhaps to test it)
|
72
|
-
#-- therefore we simply export. On closing the shell the
|
73
|
-
#-- environment variable will be gone.
|
74
|
-
#--
|
75
|
-
#-- $ export SECRET_MATERIAL=ABC123
|
76
|
-
#-- $ printenv | sort
|
77
|
-
#--
|
78
|
-
#-- Now the environment variable should be temporarily set.
|
79
|
-
#--
|
@@ -17,6 +17,7 @@
|
|
17
17
|
module OpenSession
|
18
18
|
|
19
19
|
require 'inifile'
|
20
|
+
require 'singleton'
|
20
21
|
|
21
22
|
|
22
23
|
## ---> Cleaning User Input - Use Me
|
@@ -73,13 +74,30 @@ module OpenSession
|
|
73
74
|
# This "session awakening" wipes the slate clean and starts afresh
|
74
75
|
# with regard to the two dimensional array of configuration directive
|
75
76
|
# pointers.
|
76
|
-
class
|
77
|
-
|
77
|
+
class Attributes
|
78
|
+
include Singleton
|
78
79
|
|
79
80
|
@@filename_tail = "-session.ini"
|
80
81
|
attr_reader :time_stamp
|
81
82
|
|
82
83
|
|
84
|
+
|
85
|
+
# Stash the attribute within the session's configuration file and
|
86
|
+
# print out the current state of the configuration.
|
87
|
+
#
|
88
|
+
# @param section_name [String] name grouping the section of config values
|
89
|
+
# @param key_name [String] the name of the key whose value is to be written
|
90
|
+
# @param key_value [String] the data item value of the key specified
|
91
|
+
def self.stash section_name, key_name, key_value
|
92
|
+
|
93
|
+
the_session = OpenSession::Attributes.instance
|
94
|
+
the_session.write_keyvalue section_name, key_name, key_value
|
95
|
+
puts "\n" + File.read(the_session.get_filepath(section_name)) + "\n"
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
|
83
101
|
# This singleton (one instance) class initializes by getting
|
84
102
|
# the current timestamp.
|
85
103
|
def initialize
|
@@ -138,6 +156,42 @@ module OpenSession
|
|
138
156
|
end
|
139
157
|
|
140
158
|
|
159
|
+
# Given the configuration key name and the context name, get the
|
160
|
+
# corresponding key value from the configuration file whose path
|
161
|
+
# is acquired using the {self#get_filepath} method.
|
162
|
+
#
|
163
|
+
# @param context_name [String] name of program writing a session attribute
|
164
|
+
# @param key_name [String] the key whose value is to be retrieved
|
165
|
+
#
|
166
|
+
# @return [String] the value configured for the parameter key
|
167
|
+
#
|
168
|
+
# @raise ArgumentError for any one of a long list of reasons that
|
169
|
+
# cause the key value to not be retrieved. This can range from
|
170
|
+
# non-existent directories and files, non readable files, incorrect
|
171
|
+
# configurations right down to missing keys or even missing values.
|
172
|
+
def get_value context_name, key_name
|
173
|
+
|
174
|
+
the_file = get_filepath context_name
|
175
|
+
raise ArgumentError.new "No configuration file found => [ #{the_file} ]" unless File.exists? the_file
|
176
|
+
|
177
|
+
the_text = File.read the_file
|
178
|
+
raise ArgumentError.new "Configuration file is empty => [ #{the_file} ]" if the_text.empty?
|
179
|
+
|
180
|
+
the_data = IniFile.load the_file
|
181
|
+
key_exists = the_data[ context_name ].has_key?( key_name )
|
182
|
+
raise ArgumentError.new "Key [#{key_name}] not configured => #{the_data.to_s}" unless key_exists
|
183
|
+
|
184
|
+
rawvalue = the_data[context_name][key_name]
|
185
|
+
raise ArgumentError.new "Empty value 4 key [#{key_name}] => #{the_data.to_s}" if rawvalue.empty?
|
186
|
+
|
187
|
+
keyvalue = rawvalue.chomp.strip
|
188
|
+
raise ArgumentError.new "Whitespace value 4 key [#{key_name}] => #{the_data.to_s}" if keyvalue.empty?
|
189
|
+
|
190
|
+
return keyvalue
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
|
141
195
|
#
|
142
196
|
# Get the path to the session context file.
|
143
197
|
# This file will be in a folder whose name is simply the dot
|
@@ -147,7 +201,7 @@ module OpenSession
|
|
147
201
|
# @example ~/.openbox/openbox-session.ini is the filepath for context "openbox"
|
148
202
|
#
|
149
203
|
# @param context_name [String] name of program writing a session attribute
|
150
|
-
#
|
204
|
+
# @return [String] full path to the context configuration file
|
151
205
|
def get_filepath context_name
|
152
206
|
|
153
207
|
return File.join( get_filedir(context_name), "#{context_name}#{@@filename_tail}" )
|
@@ -165,7 +219,7 @@ module OpenSession
|
|
165
219
|
# @example ~/.openbox is the directory for context "openbox"
|
166
220
|
#
|
167
221
|
# @param context_name [String] name of program (or use case) context
|
168
|
-
#
|
222
|
+
# @return [String] path to directory holding context configuration file
|
169
223
|
def get_filedir context_name
|
170
224
|
|
171
225
|
return File.join home_directory, ".#{context_name}"
|
@@ -173,7 +227,6 @@ module OpenSession
|
|
173
227
|
end
|
174
228
|
|
175
229
|
|
176
|
-
#
|
177
230
|
# On non-windows systems the home directory is defined
|
178
231
|
# perfectly by Ruby's Dir object.
|
179
232
|
#
|
@@ -181,6 +234,7 @@ module OpenSession
|
|
181
234
|
# onto the actual home directory. In these cases this
|
182
235
|
# method removes it.
|
183
236
|
#
|
237
|
+
# @return [String] the path to the machine user's home directory
|
184
238
|
def home_directory
|
185
239
|
|
186
240
|
return Dir.home unless Gem.win_platform?
|
@@ -205,6 +259,7 @@ module OpenSession
|
|
205
259
|
# - ENV['USERNAME'] for the Windows platform
|
206
260
|
# - ENV['USER'] for Linux (and everything else)
|
207
261
|
#
|
262
|
+
# @return [String] the username of the machine user
|
208
263
|
def username
|
209
264
|
|
210
265
|
return ENV['USERNAME'] if Gem.win_platform?
|