razorrisk-cassini-common 0.26.24
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,176 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# ##########################################################################
|
4
|
+
#
|
5
|
+
# Copyright (c) 2019 Razor Risk Technologies Pty Limited. All rights reserved.
|
6
|
+
#
|
7
|
+
# ##########################################################################
|
8
|
+
|
9
|
+
|
10
|
+
# ##########################################################
|
11
|
+
# requires
|
12
|
+
|
13
|
+
require 'razor_risk/core/diagnostics/exceptions/rrcs_base_exception'
|
14
|
+
require 'razor_risk/core/diagnostics/logger'
|
15
|
+
|
16
|
+
require 'pantheios'
|
17
|
+
require 'xqsr3/quality/parameter_checking'
|
18
|
+
|
19
|
+
|
20
|
+
# ##########################################################
|
21
|
+
# modules
|
22
|
+
|
23
|
+
module RazorRisk
|
24
|
+
module Cassini
|
25
|
+
module Mixin
|
26
|
+
|
27
|
+
|
28
|
+
# ##########################################################
|
29
|
+
# Mixin Module
|
30
|
+
|
31
|
+
# Methods for handling qualified responses from Razor. Should be included by
|
32
|
+
# a Sintra Microservice. When included into a microservice that inherits from
|
33
|
+
# Sinatra::Base it will define a custom error hanlder so exceptions generated
|
34
|
+
# during validation do not need to be caught.
|
35
|
+
module RazorResponseValidator
|
36
|
+
|
37
|
+
# ##########################################################
|
38
|
+
# extends
|
39
|
+
|
40
|
+
extend self
|
41
|
+
|
42
|
+
|
43
|
+
# ##########################################################
|
44
|
+
# includes
|
45
|
+
|
46
|
+
include ::Pantheios
|
47
|
+
include ::Xqsr3::Quality::ParameterChecking
|
48
|
+
include ::RazorRisk::Core::Diagnostics::Logger
|
49
|
+
|
50
|
+
|
51
|
+
# ##########################################################
|
52
|
+
# exceptions
|
53
|
+
|
54
|
+
class RazorErrorException < ::RazorRisk::Core::Diagnostics::Exceptions::RRCSBaseException
|
55
|
+
|
56
|
+
include ::Pantheios
|
57
|
+
include ::Xqsr3::Quality::ParameterChecking
|
58
|
+
include ::RazorRisk::Core::Diagnostics::Logger
|
59
|
+
|
60
|
+
attr_reader :http_status
|
61
|
+
attr_reader :options
|
62
|
+
|
63
|
+
# Raised when a qualified response failed with a Razor Error
|
64
|
+
# specified.
|
65
|
+
#
|
66
|
+
# @param http_status [Integer] The recommended HTTP error status.
|
67
|
+
# @param message [String] The exception message.
|
68
|
+
# @param options [Hash] The options hash.
|
69
|
+
#
|
70
|
+
# @option options [Exception] :cause The causing exception.
|
71
|
+
def initialize http_status, message, **options
|
72
|
+
|
73
|
+
trace(
|
74
|
+
ParamNames[ :http_status, :message, :options ],
|
75
|
+
http_status, message, options
|
76
|
+
)
|
77
|
+
|
78
|
+
@http_status = check_parameter(
|
79
|
+
http_status, 'http_status',
|
80
|
+
type: Integer,
|
81
|
+
)
|
82
|
+
|
83
|
+
super message, **options
|
84
|
+
|
85
|
+
@options = options
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
# ##########################################################
|
91
|
+
# methods
|
92
|
+
|
93
|
+
# Adds a custom error handler to a Sintra Application so the exceptions
|
94
|
+
# raised by +validate_qualified_response+ will automatically get handled.
|
95
|
+
def included(base)
|
96
|
+
|
97
|
+
if base.respond_to? :error
|
98
|
+
base.error RazorErrorException do
|
99
|
+
x = env['sinatra.error']
|
100
|
+
halt(
|
101
|
+
x.http_status,
|
102
|
+
{ 'Content-Type' => 'text/plain' },
|
103
|
+
x.message
|
104
|
+
)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Halts procressing the request with an appropriate status code if the
|
110
|
+
# response is a failure and provided a Razor Error code.
|
111
|
+
#
|
112
|
+
# @raise [RazorErrorException] if the response is a failure and provided
|
113
|
+
# a Razor Error code.
|
114
|
+
def validate_qualified_razor_response qualified_result
|
115
|
+
|
116
|
+
return unless qualified_result.respond_to? :succeeded?
|
117
|
+
|
118
|
+
unless qualified_result.succeeded?
|
119
|
+
|
120
|
+
failure_qualifier = qualified_result.failure_qualifier
|
121
|
+
return unless failure_qualifier.respond_to? :reasons
|
122
|
+
|
123
|
+
reasons = failure_qualifier.reasons
|
124
|
+
|
125
|
+
if r = reasons.lookup?('RZ0007')
|
126
|
+
# Unauthorized
|
127
|
+
log :debug1, 'Invalid Razor session'
|
128
|
+
raise RazorErrorException.new 401, 'Invalid credentials'
|
129
|
+
elsif r = reasons.lookup?('RZ0009')
|
130
|
+
# Invalid session
|
131
|
+
log :debug1, 'Invalid Razor session'
|
132
|
+
raise RazorErrorException.new 401, 'Invalid credentials'
|
133
|
+
elsif r = reasons.lookup?('RZ0002')
|
134
|
+
# Generic error, should be checked before others as will
|
135
|
+
# acompany errors such as ODBC errors that should not be
|
136
|
+
# reported to the user.
|
137
|
+
reasons_str = reasons.map { |r| "#{r.message}: #{r.details}" }.to_s
|
138
|
+
log :warning, 'Request Failed:', reasons_str
|
139
|
+
raise RazorErrorException.new 500, "#{r.message}: #{r.details}"
|
140
|
+
elsif r = reasons.lookup?('RZ0011')
|
141
|
+
# Record does not exist
|
142
|
+
log :debug1, 'Record does not exist'
|
143
|
+
raise RazorErrorException.new 404, "#{r.message}: #{r.details}"
|
144
|
+
elsif r = reasons.lookup?('RZ0010')
|
145
|
+
# Duplicate record
|
146
|
+
log :debug1, 'Duplicate record'
|
147
|
+
raise RazorErrorException.new 400, "#{r.message}: #{r.details}"
|
148
|
+
elsif r = reasons.lookup?('RZ0008')
|
149
|
+
# ODBC Error. Should not be reported to the user.
|
150
|
+
reasons_str = reasons.map { |r| "#{r.message}: #{r.details}" }.to_s
|
151
|
+
log :warning, 'Request Failed:', reasons_str
|
152
|
+
raise RazorErrorException.new 500, 'Oops! Something went wrong!'
|
153
|
+
elsif !reasons.empty?
|
154
|
+
# Unhandled Razor error code.
|
155
|
+
reasons_str = reasons.map { |r| "#{r.message}: #{r.details}" }.to_s
|
156
|
+
log :warning, 'Request Failed:', reasons_str
|
157
|
+
raise RazorErrorException.new 500, 'Oops! Something went wrong!'
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
nil
|
162
|
+
end
|
163
|
+
end # module RazorResponseHandler
|
164
|
+
|
165
|
+
|
166
|
+
# ##########################################################
|
167
|
+
# modules
|
168
|
+
|
169
|
+
end # module Mixin
|
170
|
+
end # module Cassini
|
171
|
+
end # module RazorRisk
|
172
|
+
|
173
|
+
|
174
|
+
# ############################## end of file ############################# #
|
175
|
+
|
176
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# ######################################################################## #
|
4
|
+
# File: razor_risk/cassini/testing/suppress_pantheios_logging.rb
|
5
|
+
#
|
6
|
+
# Purpose: When required before 'pantheios', sets the log-service class
|
7
|
+
# to be the ::Pantheios::Services::NullLogService class
|
8
|
+
#
|
9
|
+
# Created: 9th January 2018
|
10
|
+
# Updated: 4th March 2018
|
11
|
+
#
|
12
|
+
# Author: Matthew Wilson
|
13
|
+
#
|
14
|
+
# Copyright (c) 2018, Razor Risk Technologies Pty Ltd
|
15
|
+
# All rights reserved.
|
16
|
+
#
|
17
|
+
# ######################################################################## #
|
18
|
+
|
19
|
+
|
20
|
+
# ##########################################################################
|
21
|
+
# requires
|
22
|
+
|
23
|
+
require 'pantheios/globals'
|
24
|
+
require 'pantheios/services/null_log_service'
|
25
|
+
|
26
|
+
# Sets the initial log-service class to the null log-service class
|
27
|
+
::Pantheios::Globals.INITIAL_SERVICE_CLASSES = [ ::Pantheios::Services::NullLogService ]
|
28
|
+
|
29
|
+
# ############################## end of file ############################# #
|
30
|
+
|
31
|
+
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# ######################################################################## #
|
4
|
+
# File: razor_risk/cassini/util/conversion_util.rb
|
5
|
+
#
|
6
|
+
# Purpose: RRAWT::Util module
|
7
|
+
#
|
8
|
+
# Created: 21st May 2018
|
9
|
+
# Updated: 7th November 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
|
+
require 'xqsr3/quality/parameter_checking'
|
20
|
+
|
21
|
+
require 'nokogiri'
|
22
|
+
require 'active_support/core_ext/hash'
|
23
|
+
|
24
|
+
require 'json'
|
25
|
+
|
26
|
+
require 'razor_risk/core/diagnostics/logger'
|
27
|
+
|
28
|
+
=begin
|
29
|
+
=end
|
30
|
+
|
31
|
+
module RazorRisk
|
32
|
+
module Cassini
|
33
|
+
module Util
|
34
|
+
|
35
|
+
module ConversionUtil
|
36
|
+
|
37
|
+
include ::Xqsr3::Quality::ParameterChecking
|
38
|
+
include ::RazorRisk::Core::Diagnostics::Logger
|
39
|
+
|
40
|
+
module ConversionUtil_Constants
|
41
|
+
|
42
|
+
XML_to_JSON_Schemes = [
|
43
|
+
:default,
|
44
|
+
:gdata,
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.included receiver
|
49
|
+
|
50
|
+
receiver.extend self
|
51
|
+
end
|
52
|
+
|
53
|
+
# Converts XML to a Hash
|
54
|
+
#
|
55
|
+
# === Signature
|
56
|
+
#
|
57
|
+
# * *Options:*
|
58
|
+
# @option +:scheme+:: The scheme to use for the conversion. May be
|
59
|
+
# +:default+, +:gdata+ or +nil+, if +nil+ the +:default+ scheme is used.
|
60
|
+
#
|
61
|
+
# === Return
|
62
|
+
# A hash representing the supplied XML.
|
63
|
+
#
|
64
|
+
def convert_XML_to_Hash xml, **options
|
65
|
+
|
66
|
+
check_parameter xml, 'xml', types: [ ::Nokogiri::XML::Node, ::String ]
|
67
|
+
scheme = check_option options, :scheme, type: ::Symbol, allow_nil: true, values: ConversionUtil_Constants::XML_to_JSON_Schemes
|
68
|
+
scheme ||= :default
|
69
|
+
|
70
|
+
case scheme
|
71
|
+
when :gdata
|
72
|
+
|
73
|
+
xml_to_gdata_hash_ xml
|
74
|
+
when :default
|
75
|
+
|
76
|
+
xml_to_hash_ xml
|
77
|
+
else
|
78
|
+
|
79
|
+
log :violation, "invalid scheme '#{scheme}'"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Converts XML to a JSON
|
84
|
+
#
|
85
|
+
# === Signature
|
86
|
+
#
|
87
|
+
# * *Options:*
|
88
|
+
# @option +:scheme+:: The scheme to use for the conversion. May be
|
89
|
+
# +:default+, +:gdata+ or +nil+, if +nil+ the +:default+ scheme is used.
|
90
|
+
#
|
91
|
+
# === Return
|
92
|
+
# The supplied XML in JSON format.
|
93
|
+
#
|
94
|
+
def convert_XML_to_JSON xml, **options
|
95
|
+
|
96
|
+
check_parameter xml, 'xml', types: [ ::Hash, ::Nokogiri::XML::Node, ::String ]
|
97
|
+
|
98
|
+
case xml
|
99
|
+
when ::Hash
|
100
|
+
|
101
|
+
h = xml
|
102
|
+
else
|
103
|
+
|
104
|
+
h = convert_XML_to_Hash xml, options
|
105
|
+
end
|
106
|
+
|
107
|
+
JSON.generate(h)
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
def xml_to_hash_ xml
|
112
|
+
|
113
|
+
case xml
|
114
|
+
when ::Nokogiri::XML::Node
|
115
|
+
|
116
|
+
h = Hash.from_xml xml.to_s
|
117
|
+
when ::String
|
118
|
+
|
119
|
+
h = Hash.from_xml xml
|
120
|
+
else
|
121
|
+
|
122
|
+
log :violation, "unexpected case: xml parameter is of type '#{xml.class}'}"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def xml_to_gdata_hash_ xml
|
127
|
+
|
128
|
+
case xml
|
129
|
+
when ::Nokogiri::XML::Node
|
130
|
+
|
131
|
+
xml_dom = xml.class == ::Nokogiri::XML::Document ? xml.root : xml
|
132
|
+
when ::String
|
133
|
+
|
134
|
+
xml_dom = ::Nokogiri.XML(xml).root
|
135
|
+
else
|
136
|
+
|
137
|
+
log :violation, "unexpected case: xml parameter is of type '#{xml.class}'}"
|
138
|
+
end
|
139
|
+
|
140
|
+
[ xml_element_to_gdata_hash_(xml_dom) ].to_h
|
141
|
+
end
|
142
|
+
|
143
|
+
def xml_element_to_gdata_hash_ element
|
144
|
+
|
145
|
+
body = [
|
146
|
+
unless 0 != element.element_children.count
|
147
|
+
|
148
|
+
[ [ '$t', element.text ] ] unless (element.text.empty?)
|
149
|
+
else
|
150
|
+
|
151
|
+
element.element_children.map { |c| xml_element_to_gdata_hash_ c }
|
152
|
+
end,
|
153
|
+
element.attributes
|
154
|
+
.reject { |k| k == 'ns' }
|
155
|
+
.map { |_,v| [ v.name, v.value ] }
|
156
|
+
].flatten(1).compact
|
157
|
+
|
158
|
+
unless body.empty?
|
159
|
+
body = body.group_by(&:first)
|
160
|
+
body.transform_values! { |v| v.map(&:last) }
|
161
|
+
body.transform_values! { |v| v.length == 1 ? v.first : v }
|
162
|
+
end
|
163
|
+
|
164
|
+
[ element.name, body ]
|
165
|
+
end
|
166
|
+
|
167
|
+
end # module ProgramExecutionUtil
|
168
|
+
|
169
|
+
end # module Util
|
170
|
+
end # module Cassini
|
171
|
+
end # module RazorRisk
|
172
|
+
|
173
|
+
# ############################## end of file ############################# #
|
174
|
+
|
175
|
+
|
176
|
+
|