razorrisk-cassini-common 0.26.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +22 -0
  3. data/LICENSE +5 -0
  4. data/README.md +2 -0
  5. data/Rakefile +102 -0
  6. data/lib/razor_risk/cassini/applications/microservice.rb +318 -0
  7. data/lib/razor_risk/cassini/applications/rest_framework/route_verb_dispatcher.rb +120 -0
  8. data/lib/razor_risk/cassini/applications/rest_framework/verb_handler.rb +117 -0
  9. data/lib/razor_risk/cassini/applications/route_verb_adaptors/utilities/collection_get_helper.rb +86 -0
  10. data/lib/razor_risk/cassini/applications/securable_microservice.rb +164 -0
  11. data/lib/razor_risk/cassini/applications/secured_microservice.rb +63 -0
  12. data/lib/razor_risk/cassini/applications/unsecured_microservice.rb +77 -0
  13. data/lib/razor_risk/cassini/authorisation/header_helpers.rb +271 -0
  14. data/lib/razor_risk/cassini/authorisation/security_model_helpers.rb +93 -0
  15. data/lib/razor_risk/cassini/authorisation.rb +27 -0
  16. data/lib/razor_risk/cassini/cli.rb +19 -0
  17. data/lib/razor_risk/cassini/common/version.rb +44 -0
  18. data/lib/razor_risk/cassini/common.rb +32 -0
  19. data/lib/razor_risk/cassini/constants.rb +68 -0
  20. data/lib/razor_risk/cassini/diagnostics/util_functions.rb +248 -0
  21. data/lib/razor_risk/cassini/diagnostics/zeroth_include.rb +35 -0
  22. data/lib/razor_risk/cassini/extensions/libclimate/common_options.rb +267 -0
  23. data/lib/razor_risk/cassini/extensions/libclimate.rb +26 -0
  24. data/lib/razor_risk/cassini/header_functions.rb +59 -0
  25. data/lib/razor_risk/cassini/main.rb +238 -0
  26. data/lib/razor_risk/cassini/mixin/razor_response_validator.rb +176 -0
  27. data/lib/razor_risk/cassini/testing/suppress_pantheios_logging.rb +31 -0
  28. data/lib/razor_risk/cassini/util/conversion_util.rb +176 -0
  29. data/lib/razor_risk/cassini/util/program_execution_util.rb +379 -0
  30. data/lib/razor_risk/cassini/util/secrets_util.rb +229 -0
  31. data/lib/razor_risk/cassini/util/version_util.rb +88 -0
  32. data/lib/razor_risk/sinatra/helpers/check_auth_helper.rb +209 -0
  33. data/lib/razor_risk/sinatra/helpers/validate_accept_helper.rb +69 -0
  34. data/lib/razor_risk/sinatra/helpers/validate_content_type_helper.rb +74 -0
  35. data/lib/razor_risk/sinatra/helpers/validate_query_parameters_helper.rb +198 -0
  36. data/test/scratch/cassini/util/convert_XML.rb +54 -0
  37. data/test/unit/applications/route_verb_adaptors/utilities/tc_collection_get_helper.rb +236 -0
  38. data/test/unit/applications/tc_verb_handler.rb +130 -0
  39. data/test/unit/mixin/tc_razor_response_validator.rb +328 -0
  40. data/test/unit/sinatra/helpers/tc_validate_query_parameters_helper.rb +134 -0
  41. data/test/unit/tc_authorisation_util.rb +265 -0
  42. data/test/unit/tc_load_secrets.rb +95 -0
  43. data/test/unit/util/tc_conversion_util.rb +393 -0
  44. data/test/unit/util/tc_program_execution_util.rb +462 -0
  45. metadata +380 -0
@@ -0,0 +1,379 @@
1
+ # encoding: UTF-8
2
+
3
+ # ######################################################################## #
4
+ #
5
+ # Utility methods for creating commands to execute microservices.
6
+ #
7
+ # Copyright (c) 2018 Razor Risk Technologies Pty Limited. All rights reserved.
8
+ #
9
+ # ######################################################################## #
10
+
11
+
12
+ require 'razor_risk/core/system/system_traits'
13
+
14
+ require 'pantheios'
15
+ require 'recls'
16
+ require 'xqsr3/quality/parameter_checking'
17
+
18
+ require 'uri'
19
+
20
+ require 'razor_risk/core/diagnostics/logger'
21
+
22
+ module RazorRisk
23
+ module Cassini
24
+ module Util
25
+
26
+ module ProgramExecutionUtil
27
+
28
+ include ::RazorRisk::Core::System::SystemTraits
29
+
30
+ include ::Pantheios
31
+ include ::Xqsr3::Quality::ParameterChecking
32
+
33
+ include ::RazorRisk::Core::Diagnostics::Logger
34
+
35
+ module Util_Internals_
36
+
37
+ include ::Pantheios
38
+
39
+ end # module Util_Internals_
40
+
41
+ module Constants
42
+ module SecretServer
43
+ DEFAULT_NAME = 'secret-server'
44
+ end
45
+ end
46
+
47
+ class Command < ::Array
48
+
49
+ def cmd
50
+ self[0]
51
+ end
52
+
53
+ def uri
54
+ self[1]
55
+ end
56
+ end
57
+
58
+ private
59
+ def add_command_element_ s, a0, a1 = nil, **options
60
+
61
+ trace
62
+
63
+ case a0
64
+ when ::String
65
+
66
+ ;
67
+
68
+ when ::Recls::Entry
69
+
70
+ a0 = a0.to_str
71
+ else
72
+ end
73
+
74
+ case a1
75
+ when ::String
76
+
77
+ ;
78
+ when nil
79
+
80
+ ;
81
+ when ::Recls::Entry
82
+
83
+ a1 = a1.to_str
84
+ else
85
+ end
86
+
87
+ a0 = %Q<"#{a0}"> if a0.include? ' '
88
+ a1 = %Q<"#{a1}"> if a1 && a1.to_s.include?(' ')
89
+
90
+ if options[:use_equal]
91
+
92
+ "#{s} #{a0}=#{a1}"
93
+ else
94
+
95
+ r = "#{s} #{a0}"
96
+ r += " #{a1}" if a1
97
+
98
+ r
99
+ end
100
+ end
101
+ public
102
+
103
+ def program_name_from_executable p
104
+
105
+ p.to_s.split(windows? ? /[;|]/ : /[:|]/)[0]
106
+ end
107
+
108
+ def make_secretserver_command \
109
+ cassini_root_directory,
110
+ secrets_path,
111
+ host,
112
+ port,
113
+ **options
114
+
115
+ trace ParamNames[ :cassini_root_directory, :secrets_path, :host, :port, :options ], cassini_root_directory, secrets_path, host, port, options
116
+
117
+ check_parameter cassini_root_directory, 'cassini_root_directory', types: [ ::Recls::Entry, ::String ]
118
+ check_parameter port, 'port', type: ::Integer
119
+
120
+ # 1. Form command
121
+
122
+ cmd = if options[:ruby_path]
123
+ options[:ruby_path]
124
+ else
125
+ "ruby" + (Recls::Ximpl::OS::OS_IS_WINDOWS ? '.exe' : '')
126
+ end
127
+
128
+ cmd = add_command_element_ cmd, '-d' if options[:debug]
129
+
130
+ if options[:path]
131
+
132
+ cmd = add_command_element_ cmd, options[:path]
133
+ else
134
+
135
+ cmd = add_command_element_ cmd, Recls.combine_paths(cassini_root_directory, 'tools/utilities', Constants::SecretServer::DEFAULT_NAME, 'ws.rb', canonicalise: true)
136
+ end
137
+
138
+ cmd = add_command_element_ cmd, '-h', host if host
139
+
140
+ cmd = add_command_element_ cmd, '-p', port
141
+
142
+ cmd = add_command_element_ cmd, '-w', options[:web_server] if options[:web_server]
143
+
144
+ cmd = add_command_element_ cmd, Recls.combine_paths(cassini_root_directory, secrets_path, canonicalise: true)
145
+
146
+ if lt = options[:log_threshold]
147
+
148
+ case lt
149
+ when :debug4, 'debug4'
150
+
151
+ lt = :debug
152
+ when ::Array
153
+
154
+ lt = lt.empty? ? nil : lt.join(',')
155
+ else
156
+
157
+ end
158
+
159
+ cmd = add_command_element_ cmd, '--log-threshold', lt, use_equal: true
160
+ end
161
+
162
+ if ld = options[:log_directory]
163
+ cmd = add_command_element_ cmd, '--log-directory', ld, use_equal: true
164
+ end
165
+
166
+ pr_name = options[:program_name] || Constants::SecretServer::DEFAULT_NAME
167
+
168
+ cmd = add_command_element_ cmd, '--program-name', pr_name, use_equal: true
169
+
170
+ if rc = options[:routes_config]
171
+
172
+ cmd = add_command_element_ cmd, rc
173
+ end
174
+
175
+
176
+ # 2. Form URL
177
+
178
+ url_path= '/'
179
+ scheme = options[:uri_scheme] || 'http'
180
+ host ||= 'localhost'
181
+ path = '/' == (url_path || '')[0] ? url_path : '/' + url_path
182
+ url = "#{scheme}://#{host}:#{port}#{path}"
183
+ uri = URI.parse url
184
+
185
+
186
+ # 3. Form return value
187
+
188
+ log :debug2, 'creating secret server: url=\'', url, '\'; cmd=\'', cmd, ?'
189
+
190
+ Command.[](cmd, uri)
191
+ end
192
+
193
+ # Creates a string that can be used to start a mircoservice from the CLI.
194
+ #
195
+ # @param microservice_name [::String] The name of the microservice.
196
+ # @param security_model [:basic, :authorisation_only, :jwt] The security
197
+ # model the microservice is to use.
198
+ # @param razor_executable [::String] The path to the RazorRequest
199
+ # executable file.
200
+ # @param cassini_root_directory [::String] The path to the root direcotry
201
+ # Cassini is installed in.
202
+ # @param clarite_config_path [::String] The path the ClarITe config XML
203
+ # file.
204
+ # @param host [::String] The URI host the microservice will be
205
+ # accessible at.
206
+ # @param port [::String] The URI port the microservice will be accessible
207
+ # at.
208
+ # @param url_path [::String] The URL path the microservice will be
209
+ # accessible at.
210
+ # @param options [::Hash] The options hash.
211
+ #
212
+ #
213
+ # @option options [::String] razor_environment The Razor environment to
214
+ # connect to.
215
+ # @option options [::String] razor_space The Razor space to
216
+ # connect to.
217
+ # @option options [::String] razor_alias The Razor alias to
218
+ # connect to.
219
+ # @option options [Boolean] :benchmark Causes the child processes to be
220
+ # run with benchmarking enabled.
221
+ # @option options [Boolean] :debug Determines whether to run child
222
+ # processes in debug mode.
223
+ # @option options [::Symbol] :log_threshold Specifies the log-threshold
224
+ # to be used with the child process.
225
+ # @option options ['http', 'https'] :uri_scheme Determines whether to the
226
+ # target URI is to be hit with the HTTPS protocol, rather than HTTP.
227
+ # @option options [::String] :path Specifies a specific path to be used,
228
+ # thereby suppressing the normal inference mechanism.
229
+ # @option options [::String, Array<::String>] :additional_arguments Some
230
+ # additional arguments to be incorporated, which will be ...
231
+ #
232
+ # @return [Array<::String, ::String>] A tuple of command + URL
233
+ def make_microservice_command \
234
+ microservice_name,
235
+ security_model,
236
+ razor_executable,
237
+ cassini_root_directory,
238
+ clarite_config_path,
239
+ host,
240
+ port,
241
+ url_path,
242
+ **options
243
+
244
+ trace ParamNames[ :microservice_name, :security_model, :razor_executable, :cassini_root_directory, :clarite_config_path, :host, :port, :url_path, :options ], microservice_name, security_model, razor_executable, cassini_root_directory, clarite_config_path, host, port, url_path, options
245
+
246
+ check_parameter security_model, 'security_model', type: ::Symbol, values: [ :basic, :authorisation_only, :jwt ]
247
+ check_parameter cassini_root_directory, 'cassini_root_directory', types: [ ::Recls::Entry, ::String ]
248
+ check_parameter port, 'port', type: ::Integer
249
+
250
+
251
+ # 1. Form command
252
+
253
+ cmd = if options[:ruby_path]
254
+ options[:ruby_path]
255
+ else
256
+ "ruby" + (Recls::Ximpl::OS::OS_IS_WINDOWS ? '.exe' : '')
257
+ end
258
+
259
+ cmd = add_command_element_ cmd, '-d' if options[:debug]
260
+
261
+ rel_l1 = options[:restful] ? 'tools/services/restful' : 'tools/services'
262
+
263
+ if options[:path]
264
+
265
+ cmd = add_command_element_ cmd, options[:path]
266
+ else
267
+
268
+ cmd = add_command_element_ cmd, Recls.combine_paths(cassini_root_directory, rel_l1, microservice_name, 'ws.rb', canonicalise: true)
269
+ end
270
+
271
+ cmd = add_command_element_ cmd, '-x', [razor_executable].flatten.join(windows? ? ';' : ':') if razor_executable
272
+ cmd = add_command_element_ cmd, '-e', options[:razor_environment] if options[:razor_environment]
273
+ cmd = add_command_element_ cmd, '--razor-alias', options[:razor_alias] if options[:razor_alias]
274
+ cmd = add_command_element_ cmd, '--razor-space', options[:razor_space] if options[:razor_space]
275
+
276
+ case security_model
277
+ when :basic
278
+
279
+ sm = 'b'
280
+ when :authorisation_only
281
+
282
+ sm = 'a'
283
+ when :jwt
284
+
285
+ sm = 'j'
286
+ else
287
+
288
+ log :violation, 'unrecognised security model \'', security_model, ?'
289
+ end
290
+
291
+ cmd = add_command_element_ cmd, '-a', sm
292
+ cmd = add_command_element_ cmd, '-h', host if host
293
+ cmd = add_command_element_ cmd, '-p', port
294
+ cmd = add_command_element_ cmd, '-o', clarite_config_path if clarite_config_path
295
+ cmd = add_command_element_ cmd, '-s', options[:secret_server] if options[:secret_server]
296
+ cmd = add_command_element_ cmd, '-j', options[:jwt_encoding_algorithm] if options[:jwt_encoding_algorithm]
297
+ cmd = add_command_element_ cmd, '-w', options[:web_server] if options[:web_server]
298
+ cmd = add_command_element_ cmd, '-u', options[:web_ui_server] if options[:web_ui_server]
299
+ cmd = add_command_element_ cmd, '--benchmark' if options[:benchmark]
300
+ cmd = add_command_element_ cmd, '--authorization-test-mode' if options[:auth_test_mode]
301
+
302
+ if lt = options[:log_threshold]
303
+
304
+ case lt
305
+ when :debug4, 'debug4'
306
+
307
+ lt = :debug
308
+ when ::Array
309
+
310
+ lt = lt.empty? ? nil : lt.join(',')
311
+ else
312
+
313
+ end
314
+
315
+ cmd = add_command_element_ cmd, '--log-threshold', lt, use_equal: true
316
+ end
317
+
318
+ if ld = options[:log_directory]
319
+ cmd = add_command_element_ cmd, '--log-directory', ld, use_equal: true
320
+ end
321
+
322
+ pr_name = options[:program_name] || microservice_name
323
+
324
+ cmd = add_command_element_ cmd, '--program-name', pr_name, use_equal: true
325
+
326
+ if rc = options[:routes_config]
327
+
328
+ cmd = add_command_element_ cmd, rc
329
+ end
330
+
331
+ case aa = options[:additional_arguments]
332
+ when nil
333
+
334
+ ;
335
+ when ::Array
336
+
337
+ aa.each do |a|
338
+
339
+ case a
340
+ when ::Array
341
+
342
+ warn "processing additional arguments array element that does not contain exactly two elements" unless 2 == a.size
343
+
344
+ cmd = add_command_element_ cmd, a[0], a[1], use_equal: true
345
+ else # ::String
346
+
347
+ cmd = add_command_element_ cmd, a
348
+ end
349
+ end
350
+
351
+ else # ::String
352
+
353
+ cmd = add_command_element_ cmd, aa
354
+ end
355
+
356
+ # 2. Form URL
357
+
358
+ scheme = options[:uri_scheme] || 'http'
359
+ host ||= 'localhost'
360
+ path = '/' == (url_path || '')[0] ? url_path : "/#{url_path}"
361
+ url = "#{scheme}://#{host}:#{port}#{path}"
362
+ uri = URI.parse url
363
+
364
+ # 3. Form return value
365
+
366
+ log :debug2, 'creating microservice: url=\'', url, '\'; cmd=\'', cmd, ?'
367
+
368
+ Command.[](cmd, uri)
369
+ end
370
+
371
+ end # module ProgramExecutionUtil
372
+
373
+ end # module Util
374
+ end # module Cassini
375
+ end # module RazorRisk
376
+
377
+ # ############################## end of file ############################# #
378
+
379
+
@@ -0,0 +1,229 @@
1
+ # encoding: UTF-8
2
+
3
+ # ######################################################################## #
4
+ # File: razor_risk/cassini/util/secrets_util.rb
5
+ #
6
+ # Purpose: Security functions
7
+ #
8
+ # Created: 25th November 2017
9
+ # Updated: 15th February 2018
10
+ #
11
+ # Author: Matthew Wilson
12
+ #
13
+ # Copyright (c) 2017-2018, Razor Risk Technologies Pty Ltd
14
+ # All rights reserved.
15
+ #
16
+ # ######################################################################## #
17
+
18
+
19
+ # ##########################################################################
20
+ # requires
21
+
22
+ require 'razor_risk/extensions/hash/dig'
23
+ require 'razor_risk/core/diagnostics/logger'
24
+
25
+ require 'pantheios'
26
+ require 'recls'
27
+ require 'xqsr3/extensions/hash/deep_transform'
28
+ require 'xqsr3/quality/parameter_checking'
29
+
30
+ require 'json'
31
+ require 'net/http'
32
+ require 'resolv-replace'
33
+ require 'yaml'
34
+
35
+ module RazorRisk
36
+ module Cassini
37
+ module Util
38
+
39
+ # Include-module that introduces the +load_secrets+ function
40
+ module SecretsUtil
41
+
42
+ include ::Pantheios
43
+ include ::Xqsr3::Quality::ParameterChecking
44
+ include ::RazorRisk::Core::Diagnostics::Logger
45
+
46
+ def included receiver
47
+
48
+ receiver.extend self
49
+ end
50
+
51
+ # Gets the given secret - +category+ + +algorithm+ - from the given
52
+ # server (+secret_server_url+), according to the given options
53
+ #
54
+ # === Signature
55
+ #
56
+ # * *Parameters:*
57
+ # - +secret_server_url+:: [ ::String, ::URI ] The URI of the secret
58
+ # server
59
+ # - +category+:: [ ::String, ::Symbol ] The secret category. May be
60
+ # +nil+
61
+ # - +algorithm+:: [ ::String, ::Symbol ] The secret algorithm
62
+ #
63
+ # NOTE: all algorithm names are converted to lowercase before processing
64
+ def get_secret_from_server secret_server_url, category, algorithm, **options
65
+
66
+ trace ParamNames[ :secret_server_url, :category, :algorithm, :options ], secret_server_url, category, algorithm, options
67
+
68
+ check_parameter secret_server_url, 'secret_server_url', types: [ ::String, ::URI::Generic ]
69
+ check_parameter algorithm, 'algorithm', types: [ ::String, ::Symbol ]
70
+ check_parameter category, 'category', types: [ ::String, ::Symbol ], allow_nil: true
71
+
72
+ uri = URI.parse secret_server_url
73
+ host = uri.host
74
+ port = uri.port
75
+
76
+ headers = {
77
+
78
+ 'Accept' => 'application/json',
79
+ }
80
+
81
+ params = { 'algorithm' => algorithm }
82
+
83
+ params['category'] = category if category
84
+
85
+ headers.reject! { |k, v| ::NilClass === v }
86
+
87
+ begin
88
+
89
+ # there are issues in sending through a path-less URI to the
90
+ # server, so we step in and assign it (as the root) if it
91
+ # does not exist
92
+
93
+ path = (uri.path || '').empty? ? '/' : uri.path
94
+ query = URI.encode_www_form params
95
+
96
+ log :debug0, "host: '#{host}'; port: '#{port}'; path: '#{path}'; query: '#{query}'"
97
+
98
+ response = Net::HTTP.start(host, port, :use_ssl => uri.scheme == 'https') do |http|
99
+
100
+ full_uri = URI::HTTP.build host: host, port: port, path: path, query: query
101
+ full_url = full_uri.to_s
102
+
103
+ log :debug0, 'issuing request to \'', full_uri, '\'; scheme=\'', uri.scheme, '\''
104
+
105
+ request = Net::HTTP::Get.new full_uri, headers
106
+
107
+ http.request request
108
+ end
109
+
110
+ if '200' != response.code.to_s
111
+
112
+ abort "could not obtain secret for algorithm '#{algorithm}' from server '#{secret_server_url}': #{response.code}: #{response.body}"
113
+ end
114
+
115
+ j = JSON.parse response.body
116
+
117
+ j['secret']
118
+ rescue Errno::ECONNREFUSED
119
+
120
+ log :warning, 'failed to contact secret server ', secret_server_url
121
+
122
+ return nil
123
+ end
124
+ end
125
+
126
+ def get_secret_from_hash h, category, algorithm, **options
127
+
128
+ trace ParamNames[ :h, :category, :algorithm, :options ], h, category, algorithm, options
129
+
130
+ check_parameter h, 'h', type: ::Hash
131
+ check_parameter algorithm, 'algorithm', types: [ ::String, ::Symbol ]
132
+ check_parameter category, 'category', types: [ ::String, ::Symbol ], allow_nil: true
133
+
134
+ h = h['secrets'] if 1 == h.size && h.has_key?('secrets')
135
+
136
+ h = h.deep_transform { |k, v| [ k.to_s.downcase, v ] }
137
+
138
+ category ||= 'all'
139
+
140
+ category = category.downcase
141
+ algorithm = algorithm.downcase
142
+
143
+ secret = nil
144
+ secret ||= h.dig(category, algorithm) if 'all' != category
145
+ secret ||= h.dig('all', algorithm)
146
+
147
+ secret
148
+ end
149
+
150
+ # Loads the secrets for the given algorithms from the given source
151
+ #
152
+ # === Signature
153
+ #
154
+ # * *Parameters:*
155
+ # - +source+:: [::String, ::URI] The source of the secrets, which may
156
+ # be a URI of a secret server, or the path of a YAML file
157
+ # - +algorithms+:: An array of algorithms (::String or ::Symbol), or
158
+ # [ category, algorithm ] tuples
159
+ # - +options+:: Options
160
+ #
161
+ # * *Options:*
162
+ # - +:source_is+:: [::Symbol] If +:uri+, then +source+ is assumed to be
163
+ # a specified, then +source+ type is inferred from its type and
164
+ # content
165
+ #
166
+ # === Returns
167
+ # A hash representing the obtained secrets
168
+ #
169
+ # NOTE: all algorithm names are converted to lowercase before processing
170
+ def load_secrets source, *algorithms, **options
171
+
172
+ trace ParamNames[ :source, :algorithms, :options ], source, algorithms, options
173
+
174
+ check_parameter source, 'source', types: [ ::String, ::URI::Generic ]
175
+ check_parameter algorithms, 'algorithms', types: [ [ ::String, ::Symbol ] ]
176
+ check_option options, :source_is, type: ::Symbol, values: [ :path, :uri ], allow_nil: true
177
+
178
+ source_is = options[:source_is]
179
+
180
+ source_is ||= :uri if ::URI::Generic === source
181
+ source_is ||= :path if Recls.stat(source) rescue nil
182
+ source_is ||= :uri if URI.parse(source) rescue nil
183
+
184
+ raise ArgumentError, "could not identify whether source - '#{source}' - is a file-system path or a URI" unless source_is
185
+
186
+ acs = algorithms.map do |a|
187
+
188
+ alg = nil
189
+ cat = nil
190
+
191
+ case a
192
+ when ::String, ::Symbol
193
+
194
+ alg = a.to_s.downcase
195
+ else
196
+
197
+ log :warning, "unexpected element - '#{a}' (#{a.class}) - in array argument"
198
+ end
199
+
200
+ [ cat, alg ]
201
+ end.reject { |ar| ar[1].nil? }
202
+
203
+ secrets = {}
204
+
205
+ yaml = YAML.load_file(source) if :path == source_is
206
+
207
+ acs.each do |category, algorithm|
208
+
209
+ if :uri == source_is
210
+
211
+ secrets[algorithm] = get_secret_from_server source, category, algorithm, **options
212
+ else
213
+
214
+ secrets[algorithm] = get_secret_from_hash yaml, category, algorithm, **options
215
+ end
216
+ end
217
+
218
+ secrets
219
+ end
220
+
221
+ end # module SecretsUtil
222
+
223
+ end # module Util
224
+ end # module Cassini
225
+ end # module RazorRisk
226
+
227
+ # ############################## end of file ############################# #
228
+
229
+
@@ -0,0 +1,88 @@
1
+ # encoding: UTF-8
2
+
3
+ # ######################################################################## #
4
+ # File: razor_risk/cassini/util/version_util.rb
5
+ #
6
+ # Purpose: Conducts claimed version checks
7
+ #
8
+ # Created: 2nd January 2018
9
+ # Updated: 15th May 2018
10
+ #
11
+ # Author: Matthew Wilson
12
+ #
13
+ # Copyright (c) 2018, Razor Risk Technologies Pty Ltd
14
+ # All rights reserved.
15
+ #
16
+ # ######################################################################## #
17
+
18
+
19
+ # ##########################################################################
20
+ # requires
21
+
22
+ require 'pantheios'
23
+ require 'xqsr3/quality/parameter_checking'
24
+
25
+ =begin
26
+ =end
27
+
28
+ module RazorRisk
29
+ module Cassini
30
+ module Util
31
+
32
+ module VersionUtil
33
+
34
+ include ::Pantheios
35
+ include ::Xqsr3::Quality::ParameterChecking
36
+
37
+ def self.included receiver
38
+
39
+ receiver.extend self
40
+ end
41
+
42
+ # Checks the required and actual version of a given library, aborting
43
+ # with a detailed message if not compatible
44
+ #
45
+ # === Signature
46
+ #
47
+ # * *Parameters:*
48
+ # - +actual_module_or_version+:: [ ::Module, ::String, [ ::String,
49
+ # Integer]] The module or version being tested. Recommended usage is
50
+ # to pass the module (which allows inference of the name)
51
+ # - +required_version+:: [ ::String, [ ::Integer ]] The required
52
+ # version, e.g. [ 0, 1, 2, 3] or '0.1.2.3'
53
+ # - +lib_name+:: [::String] The name of the library. May be +nil+ if
54
+ # +actual_module_or_version+ is a +::Module+, the name of which will
55
+ # be used instead
56
+ #
57
+ # * *Options:*
58
+ # - +:aborter+:: [ responds to :abort(::String) ] An aborter. May be
59
+ # +nil+, in which case +::Kernel+ is used
60
+ # - +:process_name+:: [::String] The name of the process. May be
61
+ # +nil+, in which case it is inferred from the calling script
62
+ def check_version_compatibility actual_module_or_version, required_version, lib_name = nil, **options
63
+
64
+ check_parameter actual_module_or_version, 'actual_module_or_version', types: [ ::Module, [ ::String, ::Integer ], ::String ]
65
+ check_parameter required_version, 'required_version', types: [ [ ::String, ::Integer ], ::String ]
66
+
67
+ check_option options, :aborter, allow_nil: true, responds_to: [ :abort ]
68
+
69
+ aborter = options[:aborter] || ::Kernel
70
+ process_name = options[:process_name] || ::Pantheios::Util::ProcessUtil.derive_process_name
71
+
72
+ lib_name ||= actual_module_or_version.to_s if ::Module === actual_module_or_version
73
+
74
+ actual_version = ::Module === actual_module_or_version ? actual_module_or_version::VERSION : actual_module_or_version
75
+ required_s = ::Array === required_version ? required_version.join('.') : required_version
76
+
77
+ aborter.abort "#{process_name}: FATAL: this program requires #{lib_name} version #{required_s} or later" if ::Pantheios::Util::VersionUtil.version_compare(required_version, actual_version) > 0
78
+ end
79
+
80
+ end # module VersionUtil
81
+
82
+ end # module Util
83
+ end # module Cassini
84
+ end # module RazorRisk
85
+
86
+ # ############################## end of file ############################# #
87
+
88
+