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,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?
|