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