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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +22 -0
- data/LICENSE +5 -0
- data/README.md +2 -0
- data/Rakefile +102 -0
- data/lib/razor_risk/cassini/applications/microservice.rb +318 -0
- data/lib/razor_risk/cassini/applications/rest_framework/route_verb_dispatcher.rb +120 -0
- data/lib/razor_risk/cassini/applications/rest_framework/verb_handler.rb +117 -0
- data/lib/razor_risk/cassini/applications/route_verb_adaptors/utilities/collection_get_helper.rb +86 -0
- data/lib/razor_risk/cassini/applications/securable_microservice.rb +164 -0
- data/lib/razor_risk/cassini/applications/secured_microservice.rb +63 -0
- data/lib/razor_risk/cassini/applications/unsecured_microservice.rb +77 -0
- data/lib/razor_risk/cassini/authorisation/header_helpers.rb +271 -0
- data/lib/razor_risk/cassini/authorisation/security_model_helpers.rb +93 -0
- data/lib/razor_risk/cassini/authorisation.rb +27 -0
- data/lib/razor_risk/cassini/cli.rb +19 -0
- data/lib/razor_risk/cassini/common/version.rb +44 -0
- data/lib/razor_risk/cassini/common.rb +32 -0
- data/lib/razor_risk/cassini/constants.rb +68 -0
- data/lib/razor_risk/cassini/diagnostics/util_functions.rb +248 -0
- data/lib/razor_risk/cassini/diagnostics/zeroth_include.rb +35 -0
- data/lib/razor_risk/cassini/extensions/libclimate/common_options.rb +267 -0
- data/lib/razor_risk/cassini/extensions/libclimate.rb +26 -0
- data/lib/razor_risk/cassini/header_functions.rb +59 -0
- data/lib/razor_risk/cassini/main.rb +238 -0
- data/lib/razor_risk/cassini/mixin/razor_response_validator.rb +176 -0
- data/lib/razor_risk/cassini/testing/suppress_pantheios_logging.rb +31 -0
- data/lib/razor_risk/cassini/util/conversion_util.rb +176 -0
- data/lib/razor_risk/cassini/util/program_execution_util.rb +379 -0
- data/lib/razor_risk/cassini/util/secrets_util.rb +229 -0
- data/lib/razor_risk/cassini/util/version_util.rb +88 -0
- data/lib/razor_risk/sinatra/helpers/check_auth_helper.rb +209 -0
- data/lib/razor_risk/sinatra/helpers/validate_accept_helper.rb +69 -0
- data/lib/razor_risk/sinatra/helpers/validate_content_type_helper.rb +74 -0
- data/lib/razor_risk/sinatra/helpers/validate_query_parameters_helper.rb +198 -0
- data/test/scratch/cassini/util/convert_XML.rb +54 -0
- data/test/unit/applications/route_verb_adaptors/utilities/tc_collection_get_helper.rb +236 -0
- data/test/unit/applications/tc_verb_handler.rb +130 -0
- data/test/unit/mixin/tc_razor_response_validator.rb +328 -0
- data/test/unit/sinatra/helpers/tc_validate_query_parameters_helper.rb +134 -0
- data/test/unit/tc_authorisation_util.rb +265 -0
- data/test/unit/tc_load_secrets.rb +95 -0
- data/test/unit/util/tc_conversion_util.rb +393 -0
- data/test/unit/util/tc_program_execution_util.rb +462 -0
- metadata +380 -0
data/lib/razor_risk/cassini/applications/route_verb_adaptors/utilities/collection_get_helper.rb
ADDED
@@ -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
|
+
|