razorrisk-cassini-common 0.26.24

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.
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,86 @@
1
+ # encoding: UTF-8
2
+
3
+ # ######################################################################## #
4
+ # File: razor_risk/cassini/applications/route_verb_adaptors/utilities/collection_get_helper.rb
5
+ #
6
+ # Purpose: Adaptor for Portfolios microservice's collection GET verb
7
+ #
8
+ # Author: Matthew Wilson
9
+ #
10
+ # Copyright (c) 2018, Razor Risk Technologies Pty Ltd
11
+ # All rights reserved.
12
+ #
13
+ # ######################################################################## #
14
+
15
+
16
+ # ##########################################################################
17
+ # requires
18
+
19
+ require 'pantheios'
20
+ require 'xqsr3/quality/parameter_checking'
21
+
22
+ module RazorRisk
23
+ module Cassini
24
+ module Applications
25
+ module RouteVerbAdaptors
26
+ module Utilities
27
+
28
+ # ##########################################################################
29
+ # modules
30
+
31
+ module CollectionGetHelper
32
+
33
+ include ::Pantheios
34
+
35
+ include ::Xqsr3::Quality::ParameterChecking
36
+
37
+ # This function validates that at most of the given
38
+ # +search_parameter_names+ is specified in the +params+ hash, or issues
39
+ # a halt with a suitable message
40
+ #
41
+ # === Signature
42
+ #
43
+ # * *Parameters:*
44
+ # @param +params+:: (::Hash) The verb handler adaptor's +params+ attribute.
45
+ # May not be +nil+
46
+ # @param +search_parameter_names+:: (::Array) The names of the query
47
+ # parameters to validate
48
+ # @param +options+:: (::Hash) Options
49
+ #
50
+ # * *Options:*
51
+ # @option +:halt_code+:: (::Integer) Specifies the halt code to be
52
+ # issued. Defaults to 422. If 0, the function does not call halt, and
53
+ # instead returns +false+
54
+ # @option +:message_scope+:: (::String) The scoping part of the
55
+ # message. Defaults to 'invalid search specifier'. If specified as the
56
+ # empty string no scoping part will be included in the halt message
57
+ def validate_exclusive_search_parameters params, *search_parameter_names, **options
58
+
59
+ halt_code = Integer(options[:halt_code] || 422)
60
+
61
+ message_scope = options[:message_scope] || 'invalid search specifier'
62
+ message_scope += ': ' unless message_scope.empty?
63
+
64
+ names_present = search_parameter_names.select { |name| params[name] }.sort
65
+
66
+ case names_present.count
67
+ when 0, 1
68
+
69
+ true
70
+ else
71
+
72
+ halt *[ halt_code, {}, "#{message_scope}cannot specify '#{names_present[0]}' and '#{names_present[1]}' together" ]
73
+ end
74
+ end
75
+
76
+ end # module CollectionGetHelper
77
+
78
+ end # module Utilities
79
+ end # module RouteVerbAdaptors
80
+ end # module Applications
81
+ end # module Cassini
82
+ end # module RazorRisk
83
+
84
+ # ############################## end of file ############################# #
85
+
86
+
@@ -0,0 +1,164 @@
1
+
2
+ #############################################################################
3
+ # File: lib/razor_risk/cassini/applications/securable_microservice.rb
4
+ #
5
+ # Purpose: Define the SecurableMicroservice base class
6
+ #
7
+ # Author: Matthew Wilson
8
+ #
9
+ # Copyright (c) 2017, Razor Risk Technologies Pty Ltd
10
+ # All rights reserved
11
+ #
12
+ # ##########################################################################
13
+
14
+
15
+ require 'razor_risk/cassini/applications/microservice'
16
+
17
+ require 'razor_risk/sinatra/helpers/check_auth_helper'
18
+
19
+ require 'razor_risk/razor/connectivity/razor_3/razor_requester'
20
+
21
+ require 'razor_risk/core/diagnostics/logger'
22
+
23
+ module RazorRisk
24
+ module Cassini
25
+ module Applications
26
+
27
+ class SecurableMicroservice < Microservice
28
+
29
+ helpers ::RazorRisk::Sinatra::Helpers::CheckAuthHelper
30
+ include ::RazorRisk::Core::Diagnostics::Logger
31
+
32
+ private
33
+
34
+ def self.init_service_ \
35
+ authentication_scheme,
36
+ jwt_encoding_algorithm,
37
+ secrets,
38
+ options
39
+
40
+ trace ParamNames[ :authentication_scheme, :jwt_encoding_algorithm, :secrets, :options], authentication_scheme, jwt_encoding_algorithm, secrets, options
41
+
42
+ set :authentication_scheme, authentication_scheme
43
+ set :jwt_encoding_algorithm, jwt_encoding_algorithm
44
+ set :secrets, secrets
45
+
46
+ if true == options[:auth_test_mode]
47
+ log :warning, "YOU ARE IN AUTHORIZATION TEST MODE! NO AUTHENTICATION WILL BE PERFORMED! THIS MUST NOT BE USED IN PRODUCTION!"
48
+ set :auth_test_mode, true
49
+ else
50
+ set :auth_test_mode, false
51
+ end
52
+
53
+ set :microservice_is_initialised, Time.now
54
+
55
+ self
56
+ end
57
+
58
+ public
59
+
60
+ # This must be invoked prior to activation of the application
61
+ #
62
+ # === Signature
63
+ #
64
+ # * *Parameters:*
65
+ # - +host+:: [String] The host to which the application binds. May be:
66
+ # +nil+, in which case no binding is performed and the Sinatra
67
+ # defaults are observed; +'0.0.0.0', in which case the server will
68
+ # listen on all available interfaces; a specific IP addres, in which
69
+ # case the server will listen only on that address. It is recommend
70
+ # that a specific address is used. Required
71
+ # - +port+:: [Integer] The port on which to activate. Required
72
+ # - +authentication_scheme+:: [String, Symbol] The authentication
73
+ # scheme to be used. Must be one of
74
+ # RECOGNISED_AUTHENTICATION_SCHEMES. Required
75
+ # - +jwt_encoding_algorithm+:: [String] The algorithm that will be
76
+ # used for encoding the JWT in the +:jwt+ authentication scheme.
77
+ # Must be one of RECOGNISED_ALGORITHMS. Required only if
78
+ # +authentication_scheme+ is +:jwt+
79
+ # - +secrets+:: [Hash] An association of secrets for algorithms. Must
80
+ # contain at least secrets for the algorithms specified for
81
+ # +jwt_encoding_algorithm+.
82
+ def self.init_service \
83
+ host: to_nil(host_not_given_ = true),
84
+ port: to_nil(port_not_given_ = true),
85
+ authentication_scheme: to_nil(authentication_scheme_not_given_ = true),
86
+ jwt_encoding_algorithm: to_nil(jwt_encoding_algorithm_not_given_ = true),
87
+ secrets: to_nil(secrets_not_given_ = true),
88
+ **options
89
+
90
+ trace ParamNames[ :host, :port, :authentication_scheme, :jwt_encoding_algorithm, :secrets ], host, port, authentication_scheme, jwt_encoding_algorithm, secrets
91
+
92
+ raise ArgumentError, 'missing keyword: host' if host_not_given_
93
+ check_parameter host, 'host', type: ::String, allow_nil: true
94
+
95
+ raise ArgumentError, 'missing keyword: port' if port_not_given_
96
+ check_parameter port, 'port', type: Integer
97
+
98
+ raise ArgumentError, 'missing keyword: authentication_scheme' if authentication_scheme_not_given_
99
+ # check_parameter cannot types types then convert (by block) then
100
+ # check values in one operation, so instead convert to Symbol only
101
+ # if String
102
+ authentication_scheme = authentication_scheme.to_sym if ::String === authentication_scheme
103
+ check_parameter authentication_scheme, 'authentication_scheme', types: [ ::String, ::Symbol ], values: RECOGNISED_AUTHENTICATION_SCHEMES
104
+
105
+ if :jwt == authentication_scheme
106
+
107
+ if severity_logged? :debug4
108
+
109
+ log :debug4, "jwt_encoding_algorithm (#{jwt_encoding_algorithm.class})=#{jwt_encoding_algorithm}"
110
+ end
111
+
112
+ raise ArgumentError, 'missing keyword: jwt_encoding_algorithm' if jwt_encoding_algorithm_not_given_
113
+ check_parameter jwt_encoding_algorithm, 'jwt_encoding_algorithm', type: ::String, values: RECOGNISED_ALGORITHMS
114
+ end
115
+
116
+ init_service_ \
117
+ authentication_scheme,
118
+ jwt_encoding_algorithm,
119
+ secrets,
120
+ options
121
+
122
+ # invoke superclass
123
+ init_base_service host: host, port: port, **options
124
+ end
125
+
126
+ def self.secret algorithm
127
+
128
+ trace ParamNames[:algorithm], algorithm
129
+
130
+ return nil if algorithm.nil?
131
+ return nil unless settings.respond_to? :secrets
132
+
133
+ settings.secrets[algorithm.downcase]
134
+ end
135
+
136
+ def secret algorithm
137
+
138
+ trace ParamNames[:algorithm], algorithm
139
+
140
+ self.class.secret algorithm
141
+ end
142
+
143
+
144
+ before do
145
+
146
+ trace
147
+ end
148
+
149
+ # Error handler for invalid credentials.
150
+ error Razor::Connectivity::Razor3::RazorRequester::InvalidCredentialsException do
151
+ x = env['sinatra.error']
152
+ log :warning, "Invalid Credentials"
153
+ error 401, "Invalid Credentials"
154
+ end
155
+
156
+ end # class SecurableMicroservice
157
+
158
+ end # module Applications
159
+ end # module Cassini
160
+ end # module RazorRisk
161
+
162
+ # ############################## end of file ############################# #
163
+
164
+
@@ -0,0 +1,63 @@
1
+
2
+ #############################################################################
3
+ # File: lib/razor_risk/cassini/applications/securable_microservice.rb
4
+ #
5
+ # Purpose: Define the SecurableMicroservice base class
6
+ #
7
+ # Author: Matthew Wilson
8
+ #
9
+ # Copyright (c) 2017, Razor Risk Technologies Pty Ltd
10
+ # All rights reserved
11
+ #
12
+ # ##########################################################################
13
+
14
+
15
+ require 'razor_risk/cassini/applications/securable_microservice'
16
+ require 'razor_risk/core/diagnostics/logger'
17
+
18
+ module RazorRisk
19
+ module Cassini
20
+ module Applications
21
+
22
+ # A refinement of the SecurableMicroservice class that checks authorisation
23
+ # for every request (in the before handler) and exposes the obtained
24
+ # credentials (in an authentication scheme-dependent form) in the
25
+ # +credentials+ attribute
26
+ class SecuredMicroservice < SecurableMicroservice
27
+ include ::RazorRisk::Core::Diagnostics::Logger
28
+ before do
29
+
30
+ trace
31
+
32
+ # because all routes in this class are authorised, we can do the
33
+ # check in one place
34
+
35
+ log :informational, 'verifying authentication'
36
+
37
+ options = {
38
+
39
+ credentials: true,
40
+ }
41
+
42
+ if :jwt == settings.authentication_scheme
43
+ options[:jwt_secret] = secret(settings.jwt_encoding_algorithm)
44
+ end
45
+
46
+ @credentials = check_auth env, settings.authentication_scheme, **options
47
+
48
+ log :debug4, "@credentials(#{@credentials.class})='#{@credentials}'"
49
+ end
50
+
51
+ attr_reader :credentials
52
+
53
+ private
54
+
55
+ end # class SecuredMicroservice
56
+
57
+ end # module Applications
58
+ end # module Cassini
59
+ end # module RazorRisk
60
+
61
+ # ############################## end of file ############################# #
62
+
63
+
@@ -0,0 +1,77 @@
1
+
2
+ #############################################################################
3
+ # File: lib/razor_risk/cassini/applications/unsecured_microservice.rb
4
+ #
5
+ # Purpose: Define the UnsecuredMicroservice base class
6
+ #
7
+ # Author: Matthew Wilson
8
+ #
9
+ # Copyright (c) 2017, Razor Risk Technologies Pty Ltd
10
+ # All rights reserved
11
+ #
12
+ # ##########################################################################
13
+
14
+
15
+ require 'razor_risk/cassini/applications/microservice'
16
+
17
+ module RazorRisk
18
+ module Cassini
19
+ module Applications
20
+
21
+ class UnsecuredMicroservice < Microservice
22
+
23
+ private
24
+
25
+ def self.init_service_ \
26
+ options
27
+
28
+ trace
29
+
30
+ set :microservice_is_initialised, Time.now
31
+
32
+ self
33
+ end
34
+
35
+ public
36
+
37
+ # This must be invoked prior to activation of the application
38
+ #
39
+ # === Signature
40
+ #
41
+ # * *Parameters:*
42
+ # - +host+:: [String] The host to which the application binds. May be:
43
+ # +nil+, in which case no binding is performed and the Sinatra
44
+ # defaults are observed; +'0.0.0.0', in which case the server will
45
+ # listen on all available interfaces; a specific IP addres, in which
46
+ # case the server will listen only on that address. It is recommend
47
+ # that a specific address is used. Required
48
+ # - +port+:: [Integer] The port on which to activate. Required
49
+ def self.init_service \
50
+ host: to_nil(host_not_given_ = true),
51
+ port: to_nil(port_not_given_ = true),
52
+ **options
53
+
54
+ trace ParamNames[:host, :port, ], host, port
55
+
56
+ raise ArgumentError, 'missing keyword: host' if host_not_given_
57
+ check_parameter host, 'host', type: ::String, allow_nil: true
58
+
59
+ raise ArgumentError, 'missing keyword: port' if port_not_given_
60
+ check_parameter port, 'port', type: Integer
61
+
62
+ init_service_ \
63
+ options
64
+
65
+ # invoke superclass
66
+ init_base_service host: host, port: port, **options
67
+ end
68
+
69
+ end # class UnsecuredMicroservice
70
+
71
+ end # module Applications
72
+ end # module Cassini
73
+ end # module RazorRisk
74
+
75
+ # ############################## end of file ############################# #
76
+
77
+
@@ -0,0 +1,271 @@
1
+ # encoding: UTF-8
2
+
3
+ # ######################################################################## #
4
+ # File: razor_risk/cassini/authorisation/header_helpers.rb
5
+ #
6
+ # Purpose: ::RazorRisk::Cassini::Authorisation::HeaderHelpers module
7
+ #
8
+ # Created: 16th February 2018
9
+ # Updated: 4th March 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 'razor_risk/core/cryptography/ciphers/aes_cipher'
23
+ require 'razor_risk/core/diagnostics/logger'
24
+
25
+ require 'pantheios'
26
+ require 'xqsr3/quality/parameter_checking'
27
+
28
+ require 'jwt'
29
+
30
+ require 'json'
31
+
32
+ =begin
33
+ =end
34
+
35
+ module RazorRisk
36
+ module Cassini
37
+ module Authorisation
38
+
39
+ module HeaderHelpers
40
+
41
+ include ::Pantheios
42
+ include ::Xqsr3::Quality::ParameterChecking
43
+ include ::RazorRisk::Core::Diagnostics::Logger
44
+
45
+ module Authorisation_HeaderHelpers_Constants_
46
+
47
+ CIPHER_KEY_LENGTH = 256
48
+ CIPHER_MODE = :CBC
49
+ end
50
+
51
+ # Constructs a Basic Authentication authorisation token from the given
52
+ # +username+, +password+, and, optionally, +domain+.
53
+ #
54
+ # === Signature
55
+ #
56
+ # * *Parameters:*
57
+ # - +:username+ [ ::String ] - the username
58
+ # - +:password+ [ ::String ] - the password. May be +nil+
59
+ # - +:domain+ [ ::String ] - the domain. May be +nil+
60
+ # - +:options+ [ ::Hash ] - options
61
+ #
62
+ # * *Options:*
63
+ # - +:no_chomp+ [ boolean ] Prevents the result being chomped
64
+ #
65
+ # === Return
66
+ # A string of the form 'Basic <credentials-data>'. Note that the string
67
+ # will NOT contain a trailing new-line sequence unless the option
68
+ # +:no_chomp+ is specified
69
+ def Basic_from_credentials username, password, domain = nil, **options
70
+
71
+ trace ParamNames[ :username, :password, :domain, :options ], username, password, domain, options
72
+
73
+ check_parameter username, 'username', type: ::String
74
+
75
+ if (domain || '').empty?
76
+
77
+ credentials = "#{username}:#{password}"
78
+ else
79
+
80
+ credentials = "#{domain}\\#{username}:#{password}"
81
+ end
82
+
83
+ r = 'Basic ' + [ credentials ].pack('m')
84
+
85
+ r = r.chomp unless options[:no_chomp]
86
+
87
+ r
88
+ end
89
+
90
+ # Returns a credentials array - [ username, password, domain ] - if
91
+ # present
92
+ #
93
+ # === Signature
94
+ #
95
+ # * *Parameters:*
96
+ # - +auth+ [ ::String ] - the authorisation token, in the format
97
+ # "Basic <credentials-data>"
98
+ #
99
+ # * *Options:*
100
+ # - +:nil+ [Boolean] - causes +nil+ to be returned if not matched;
101
+ # otherwise an empty +Array+ is returned
102
+ def credentials_from_Basic auth, **options
103
+
104
+ trace ParamNames[ :auth, :options ], auth, options
105
+
106
+ check_parameter auth, 'auth', type: ::String
107
+
108
+ if auth !~ /^Basic /i
109
+
110
+ log :failure, 'authorisation token is not Basic'
111
+ else
112
+
113
+ uid = $'.unpack('m')[0]
114
+
115
+ if uid !~ /^([^:]+):(.*)$/
116
+
117
+ log :failure, 'Basic authorisation token is not well-formed'
118
+ else
119
+
120
+ username = $1
121
+ password = $2
122
+ domain = nil
123
+
124
+ if username =~ /\\/
125
+
126
+ domain, username = $`, $'
127
+ end
128
+
129
+ return [ username, password, domain ]
130
+ end
131
+ end
132
+
133
+ options[:nil] ? nil : []
134
+ end
135
+
136
+
137
+ # Constructs an Authentication-only authorisation token from the given
138
+ # +username+
139
+ #
140
+ # === Signature
141
+ #
142
+ # * *Parameters:*
143
+ # - +:username+ [ ::String ] - the username
144
+ # - +:options+ [ ::Hash ] - options
145
+ #
146
+ # * *Options:*
147
+ def AuthorisationOnly_from_credentials username, **options
148
+
149
+ trace ParamNames[ :username, :options ], username, options
150
+
151
+ check_parameter username, 'username', type: ::String
152
+
153
+ 'RazorRisk.Cassini.AuthorisationOnly ' + [ username ].pack('m')
154
+ end
155
+
156
+ # Returns a credentials array containing only username
157
+ #
158
+ # === Signature
159
+ #
160
+ # * *Parameters:*
161
+ # - +auth+ [ ::String ] - the authorisation token, in the format
162
+ # "RazorRisk.Razor.AuthorisationOnly <credentials-data>"
163
+ #
164
+ # * *Options:*
165
+ # - +:nil+ [Boolean] - causes +nil+ to be returned if not matched;
166
+ # otherwise an empty +Array+ is returned
167
+ def credentials_from_AuthorisationOnly auth, **options
168
+
169
+ trace ParamNames[ :auth, :options ], auth, options
170
+
171
+ username = nil
172
+
173
+ if auth =~ /^RazorRisk\.(?:Cassini|Razor)\.Auth(?:ori[sz]ation)Only /i && !$'.empty?
174
+
175
+ username = $'.unpack('m')[0]
176
+
177
+ [ username, nil, nil ]
178
+ else
179
+
180
+ options[:nil] ? nil : []
181
+ end
182
+ end
183
+
184
+
185
+ # Constructs a JWT authorisation token for a user session.
186
+ #
187
+ # @param session_id [::String] The session ID.
188
+ # @param user_id [::String] The user ID.
189
+ # @param user_name [::String] The user's long name.
190
+ # @param jwt_algorithm [::String] the JWT algorithm
191
+ # @param jwt_secret [::String] the JWT secret
192
+ # @param options [::Hash] options
193
+ #
194
+ # @return [::String] The created JSON Web Token.
195
+ def JWT_from_credentials session_id, user_id, user_name, jwt_algorithm, jwt_secret, **options
196
+
197
+ trace(
198
+ ParamNames[ :session_id, :jwt_algorithm, :jwt_secret, :options ],
199
+ session_id, jwt_algorithm, jwt_secret, options
200
+ )
201
+
202
+ check_parameter session_id, 'session_id', type: ::String
203
+ check_parameter jwt_secret, 'jwt_secret', type: ::String
204
+
205
+ payload = {
206
+ 'razorrisk.razor.user_id' => user_id,
207
+ 'razorrisk.razor.user_name' => user_name,
208
+ 'razorrisk.razor.session_id' => session_id,
209
+ }
210
+
211
+ JWT.encode payload, jwt_secret, jwt_algorithm
212
+ end
213
+
214
+
215
+ # Returns a credentials array from a JSON Web Token.
216
+ #
217
+ # * *Parameters:*
218
+ # @param auth [::String] The authorisation token, in the format "Bearer
219
+ # <credentials-data>", where <credentials-data> is a JWT.
220
+ # @param jwt_secret [::String] The secret used for JWT encryption.
221
+ # @param options [::Hash] The options hash.
222
+ #
223
+ # @option options [Boolean] nil Causes +nil+ to be returned if not
224
+ # matched; otherwise an empty +Array+ is returned.
225
+ #
226
+ # @return [Arrary<::String>] A credentials array, +[session_id]+, if
227
+ # present.
228
+ def credentials_from_JWT auth, jwt_secret, **options
229
+
230
+ trace(
231
+ ParamNames[ :auth, :jwt_secret, :options ],
232
+ auth, jwt_secret, options
233
+ )
234
+
235
+ check_parameter auth, 'auth', type: ::String
236
+ check_parameter jwt_secret, 'jwt_secret', type: ::String
237
+
238
+ if auth !~ /^Bearer /i
239
+
240
+ log :failure, 'authorisation token is not Bearer'
241
+ else
242
+
243
+ jwt = $'.strip
244
+
245
+ payload, header = JWT.decode jwt, jwt_secret, true
246
+
247
+ if payload && header
248
+
249
+ session_id = payload['razorrisk.razor.session_id']
250
+ user_id = payload['razorrisk.razor.user_id']
251
+ user_name = payload['razorrisk.razor.user_name']
252
+
253
+ return [
254
+ session_id,
255
+ user_id,
256
+ user_name
257
+ ] if session_id
258
+ end
259
+ end
260
+
261
+ options[:nil] ? nil : []
262
+ end
263
+ end # module HeaderHelpers
264
+
265
+ end # module Authorisation
266
+ end # module Cassini
267
+ end # module RazorRisk
268
+
269
+ # ############################## end of file ############################# #
270
+
271
+