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