services-clientedgeservice 0.14.10

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 649ace591b448aee555bb12648b5764c609102b5
4
+ data.tar.gz: ce8cf4daaadc7daa1287532f2966ab99d8ae3463
5
+ SHA512:
6
+ metadata.gz: a3b010ebad4136f33fce36c6d6ea372a198d0760d9d02c377795909a6a6d018973a9e4b8313be387d675ae9ba9edcb6c5d5721f8698deb9fb2d7e95e0a577953
7
+ data.tar.gz: 60718774f4f779b3a7d695437e24b701bbfb144f6a0666712212f1d18258f2ea8f7073aff3ead01288d51b52fcd73141d0fe708d47af78fd23ee957d9924fc79
data/CHANGELOG.md ADDED
@@ -0,0 +1,22 @@
1
+ # Change Log
2
+
3
+ ## [0.12.1] (2018-06-20)
4
+
5
+ **Implemented enhancements:**
6
+
7
+ none
8
+
9
+ **Fixed defects:**
10
+
11
+ none
12
+
13
+ **Dependencies and packaging:**
14
+
15
+ - separated into own project/repo/package [WEBAPI-138]
16
+
17
+ **Merged pull requests:**
18
+
19
+ none
20
+
21
+ ## END OF CHANGE LOG
22
+
data/LICENSE ADDED
@@ -0,0 +1,5 @@
1
+ Cassini
2
+
3
+ Copyright (c) 2017-2018, Razor Risk Technologies Pty Ltd
4
+ All rights reserved.
5
+
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ T.B.C.
2
+
@@ -0,0 +1,396 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # ######################################################################## #
5
+ # File: tools/servers/ces/ws.rb
6
+ #
7
+ # Purpose: Main module/entry file for the Client Edge Service
8
+ #
9
+ # Author: Matthew Wilson
10
+ #
11
+ # Copyright (c) 2017-2018, Razor Risk Technologies Pty Ltd
12
+ # All rights reserved.
13
+ #
14
+ # ######################################################################## #
15
+
16
+
17
+ # ##########################################################################
18
+
19
+ # Service: Client Edge Service (CES)
20
+ #
21
+ # Supported:
22
+ #
23
+ # - [*] /* {Secured, Unsecured}
24
+ #
25
+
26
+ # ##########################################################################
27
+ # requires
28
+
29
+ require 'razor_risk/cassini/diagnostics/zeroth_include'
30
+
31
+ require 'razor_risk/cassini/applications/services/client_edge_service/version'
32
+
33
+ require 'razor_risk/cassini/ces'
34
+ require 'razor_risk/cassini/ces/version'
35
+
36
+ require 'razor_risk/cassini/applications/securable_microservice'
37
+ require 'razor_risk/cassini/cli'
38
+ require 'razor_risk/cassini/common/version'
39
+ require 'razor_risk/cassini/constants'
40
+ require 'razor_risk/cassini/diagnostics/util_functions'
41
+ require 'razor_risk/cassini/extensions/libclimate'
42
+ require 'razor_risk/cassini/util/secrets_util'
43
+ require 'razor_risk/cassini/util/version_util'
44
+
45
+ require 'razor_risk/sinatra/helpers/check_auth_helper'
46
+
47
+ require 'razor_risk/core/diagnostics/extensions/libclimate'
48
+ require 'razor_risk/core/diagnostics/logger'
49
+
50
+ require 'libclimate'
51
+ require 'pantheios'
52
+ require 'xqsr3/extensions/enumerable/detect_map'
53
+ require 'xqsr3/extensions/kernel/integer'
54
+ require 'xqsr3/extensions/string'
55
+
56
+ require 'sinatra/base'
57
+
58
+ require 'uri'
59
+
60
+ require 'yaml'
61
+
62
+ # ##########################################################################
63
+ # includes
64
+
65
+ include ::RazorRisk::Cassini::CES::RouteMapping
66
+
67
+ include ::RazorRisk::Cassini
68
+
69
+ include ::RazorRisk::Cassini::Applications
70
+ include ::RazorRisk::Cassini::Constants
71
+ include ::RazorRisk::Cassini::MicroserviceDispatcher
72
+ include ::RazorRisk::Cassini::Util::SecretsUtil
73
+ include ::RazorRisk::Cassini::Util::VersionUtil
74
+
75
+ include ::RazorRisk::Cassini::Diagnostics
76
+ include ::RazorRisk::Core::Diagnostics::Logger
77
+
78
+ include ::Pantheios
79
+
80
+ # ##########################################################################
81
+ # constants
82
+
83
+ PROGRAM_VERSION = ::RazorRisk::Cassini::Applications::Services::ClientEdgeService::VERSION
84
+
85
+ # ##########################################################################
86
+ # compatibility checks
87
+
88
+ check_version_compatibility ::RazorRisk::Cassini::CES, [ 0, 6 ], 'RazorRisk.Cassini.CES'
89
+ check_version_compatibility ::RazorRisk::Cassini::Common, [ 0, 21 ], 'RazorRisk.Cassini.Common'
90
+ check_version_compatibility ::LibCLImate, '0.10'
91
+ check_version_compatibility ::Pantheios, '0.20'
92
+ check_version_compatibility ::Sinatra, '1.4.8'
93
+
94
+ # ##########################################################################
95
+ # functions
96
+
97
+ # ##########################################################################
98
+ # static set-up
99
+
100
+ # ##########################################################################
101
+ # application
102
+
103
+ class ClientEdgeServiceApp < SecurableMicroservice
104
+
105
+ include ::Pantheios
106
+ include ::RazorRisk::Core::Diagnostics::Logger
107
+
108
+ FULL_DESIGNATION = 'Client Edge'
109
+ SHORT_DESIGNATION = 'CES'
110
+ SERVICE_TYPE = :service
111
+
112
+ def self.on_init_service options
113
+
114
+ trace ParamNames[ :options ], options
115
+
116
+ raise ArgumentError, 'missing keyword: mapped_routes' unless options.has_key? :mapped_routes
117
+
118
+ set :mapped_routes, options[:mapped_routes]
119
+ set :web_ui_server, options[:web_ui_server]
120
+ end
121
+
122
+
123
+ def log_response verb, request, handler, svr_resp
124
+
125
+ log :debug0, "#{verb} '#{request.path_info}' => '#{handler.uri}': code=#{svr_resp.code}; body-length=#{svr_resp.body ? svr_resp.body.size : '(no body)'}" if severity_logged? :debug0
126
+ end
127
+
128
+ delete '/*' do
129
+
130
+ trace
131
+ dispatch_ 'DELETE'
132
+ end
133
+
134
+
135
+ get '/*' do
136
+
137
+ trace
138
+ dispatch_ 'GET'
139
+ end
140
+
141
+
142
+ post '/*' do
143
+
144
+ trace
145
+ dispatch_ 'POST'
146
+ end
147
+
148
+
149
+ put '/*' do
150
+
151
+ trace
152
+ dispatch_ 'PUT'
153
+ end
154
+
155
+ before do
156
+
157
+ response.headers['Access-Control-Allow-Origin'] = settings.web_ui_server if settings.web_ui_server
158
+ end
159
+
160
+ options '*' do
161
+
162
+ if settings.web_ui_server
163
+
164
+ response.headers["Allow"] = "GET, DELETE, PUT, POST, OPTIONS"
165
+ response.headers["Access-Control-Allow-Methods"] = "GET, DELETE, PUT, POST, OPTIONS"
166
+ response.headers["Access-Control-Allow-Headers"] = "Authorization, Content-Type, Accept, X-Auth-Token"
167
+ response.headers["Access-Control-Allow-Origin"] = settings.web_ui_server
168
+ end
169
+
170
+ status 200
171
+ end
172
+
173
+ private
174
+ def dispatch_ verb
175
+
176
+ num_servers_tried = 0
177
+
178
+ if handlers = settings.mapped_routes.detect_map { |mr| mr.match request }
179
+
180
+ handlers = handlers.shuffle
181
+
182
+ handlers.each do |handler|
183
+
184
+ jwt_sec = secret(settings.jwt_encoding_algorithm)
185
+
186
+ check_auth(env, settings.authentication_scheme, jwt_secret: jwt_sec) if handler.security
187
+
188
+ log :info, 'attempting routing to ', handler.uri
189
+
190
+ begin
191
+
192
+ num_servers_tried += 1
193
+
194
+ args = [ verb, handler.uri, env, 'Accept', 'Authorization' ]
195
+
196
+ if verb =~ /^POST|PUT$/
197
+ args << 'Content-Length'
198
+ args << 'Content-Type'
199
+ end
200
+
201
+ svr_resp = dispatch(*args) do |rq|
202
+
203
+ rq.body = request.body.read if verb =~ /^POST|PUT$/
204
+ end
205
+
206
+ log_response verb, request, handler, svr_resp
207
+
208
+ status = Integer(svr_resp.code)
209
+ headers = svr_resp.to_hash.reject do |k,v|
210
+ HOP_BY_HOP_HEADERS.include? k.downcase
211
+ end
212
+ body = svr_resp.body
213
+
214
+ return [ status, headers, body ]
215
+ rescue Errno::ECONNREFUSED
216
+
217
+ log :warning, 'failed to connect to \'', handler.uri, '\''
218
+ rescue EOFError => x
219
+
220
+ log :warning, "Routed request timed-out"
221
+ halt 504, { 'Content-Type' => 'text/plain' }, "Routed request unexpectedly closed"
222
+ rescue Net::ReadTimeout => x
223
+
224
+ log :warning, "Routed request timed-out"
225
+ halt 504, { 'Content-Type' => 'text/plain' }, "Routed request timed-out"
226
+ rescue ::Exception => x
227
+
228
+ log :debug0, "exception (#{x.class}): #{x}"
229
+
230
+ log :critical, "exception (of type #{x.class}) received when attempting to connect to '#{handler.uri}': #{x.message}"
231
+
232
+ raise
233
+ end
234
+ end
235
+
236
+ log :critical, "failed to connect to handler for '#{request.path_info}' (#{verb})"
237
+ end
238
+
239
+
240
+ halt *[ 500, {}, "could not serve '#{request.path_info}'" ] if 0 != num_servers_tried
241
+
242
+ status 404
243
+ end
244
+ end
245
+
246
+ TheApp = ClientEdgeServiceApp
247
+
248
+ # ##########################################################################
249
+ # command-line parsing
250
+
251
+ options = {}
252
+
253
+ climate = LibCLImate::Climate.new do |cl|
254
+
255
+ cl.option_tls_cert_and_key options
256
+
257
+ cl.add_flag('--accept-string-routes', alias: '-S', help: 'if specified, allows the YAML routes-configuration top-level keys to be strings, which will be made absolute and made trailing-slash permissive. Also required if specifying a JSON file') { options[:accept_string_routes] = true }
258
+
259
+ cl.add_option('--web-ui-server', alias: '-u', help: 'if specified, whitelists the provided url for CORS (Cross Origin Resource Sharing)') do |o,a|
260
+
261
+ cl.abort 'Web UI Server value was missing; use --help for usage' if o.value.nil?
262
+
263
+ options[:web_ui_server] = o.value
264
+ end
265
+
266
+ cl.option_web_server options
267
+
268
+ cl.option_host options
269
+ cl.option_port options
270
+
271
+ cl.option_authentication_scheme options, SUPPORTED_AUTHENTICATION_SCHEMES
272
+ cl.option_jwt_encoding_algorithm options
273
+ cl.option_credentials_encoding_algorithm options
274
+ cl.option_secret_server_source options
275
+
276
+ cl.option_log_threshold options, limit: -2
277
+
278
+ cl.info_lines = [
279
+
280
+ ::RazorRisk::Cassini::Common::DESCRIPTION,
281
+ ::RazorRisk::Cassini::CLI.Copyright(2017),
282
+ :version,
283
+ TheApp.full_description,
284
+ ]
285
+
286
+ cl.usage_values = '<routes-config-spec>'
287
+ end
288
+
289
+ log :debug0, 'parsing command line ...'
290
+
291
+ r = climate.run ARGV
292
+
293
+ ::Pantheios::Core.program_name = options[:program_name] if options[:program_name]
294
+
295
+ program_name = ::Pantheios::Core.program_name
296
+ log_directory = options[:log_directory] || './logs'
297
+ log_threshold = options[:log_threshold] || :notice
298
+
299
+ setup_diagnostic_logging program_name, log_directory, log_threshold
300
+
301
+ # amass the arguments that are required
302
+
303
+ options[:host] ||= nil
304
+
305
+ options[:authentication_scheme] ||= :jwt
306
+
307
+ routes_config_spec = r.values[0] or climate.abort 'no routes-config-path specified'
308
+
309
+ secret_server_source = options[:secret_server_source] or climate.abort 'no secret server url specified; use --help for usage' if :jwt == options[:authentication_scheme]
310
+
311
+ case options[:authentication_scheme]
312
+ when :jwt
313
+
314
+ options[:jwt_encoding_algorithm] or climate.abort "must specify JWT encoding algorithm; use --help for usage"
315
+
316
+ algorithms = (r.values.size < 2) ? [ options[:jwt_encoding_algorithm], ] : r.values[1..-1]
317
+ else
318
+
319
+ algorithms = []
320
+ end
321
+
322
+ if options[:tls_certificate_file]
323
+
324
+ climate.abort "TLS/SSL may only be used when using the Thin web server" if (options[:web_server] || 'thin').to_s.downcase.strip != 'thin'
325
+
326
+ climate.abort "no public-key file specified with the TLS/SSL certificate file" unless options[:tls_public_key_file]
327
+ end
328
+
329
+ if options[:web_ui_server]
330
+
331
+ climate.abort 'Web UI Server must be a valid URI; use --help for usage' unless options[:web_ui_server] =~ URI.regexp
332
+ end
333
+
334
+ # ##########################################################################
335
+ # main
336
+
337
+ log :informational, 'initialising ', TheApp::SHORT_DESIGNATION, ' from routes config \'', routes_config_spec, '\' and secret server \'', secret_server_source, '\''
338
+
339
+ handled_routes = load_routes routes_config_spec, **options
340
+
341
+ log :debug2, "handled routes:\n#{handled_routes}" if severity_logged? :debug2
342
+
343
+ mapped_routes = map_routes handled_routes
344
+
345
+ options[:secrets] = if :jwt == options[:authentication_scheme]
346
+ log :informational, 'loading secrets ...'
347
+ load_secrets(secret_server_source, *algorithms)
348
+ else
349
+ {}
350
+ end
351
+
352
+ log :informational, 'initialising application ...'
353
+ log :debug0, 'options: ', options
354
+
355
+ begin
356
+
357
+ TheApp.init_service **options, mapped_routes: mapped_routes, web_ui_server: options[:web_ui_server]
358
+ rescue ::ArgumentError, ::NameError, ::NoMethodError, ::TypeError => x
359
+
360
+ log :violation, "unexpected exception (#{x.class}): '#{x.message}': #{x.backtrace}"
361
+
362
+ raise
363
+ rescue ::Errno::EADDRINUSE => x
364
+
365
+ log :debug, x.message
366
+ msg = "Cannot start #{self.process_name}, '#{options[:host]}:#{options[:port]}' in use"
367
+ log :critical, msg
368
+ climate.abort msg
369
+ rescue => x
370
+
371
+ log :alert, "exception(#{x.class}): #{x.message}"
372
+
373
+ climate.abort x.message
374
+ end
375
+
376
+ log :notice, "starting #{TheApp::SHORT_DESIGNATION} server with authentication scheme '#{options[:authentication_scheme]}'"
377
+
378
+ begin
379
+
380
+ TheApp.run!
381
+ rescue ::ArgumentError, ::NameError, ::NoMethodError, ::TypeError => x
382
+
383
+ log :violation, "unexpected exception (#{x.class}): '#{x.message}': #{x.backtrace}"
384
+
385
+ raise
386
+ rescue => x
387
+
388
+ log :alert, "exception(#{x.class}): #{x.message}"
389
+
390
+ climate.abort x.message
391
+ end
392
+
393
+ # ############################## end of file ############################# #
394
+
395
+
396
+
@@ -0,0 +1,48 @@
1
+ # encoding: UTF-8
2
+
3
+ # ##########################################################################
4
+ #
5
+ # Version for RazorRisk.Cassini.Services.ClientEdgeService library
6
+ #
7
+ # Copyright (c) 2019 Razor Risk Technologies Pty Limited. All rights reserved.
8
+ #
9
+ # ##########################################################################
10
+
11
+ module RazorRisk
12
+ module Cassini
13
+ module Applications
14
+ module Services
15
+
16
+ module ClientEdgeService
17
+
18
+ # Current version of the RazorRisk.Cassini.Services.RESTful.ClientEdgeService library
19
+ VERSION = '0.14.10'
20
+
21
+ private
22
+ VERSION_PARTS_ = VERSION.split(/[.]/).collect { |n| n.to_i } # :nodoc:
23
+ public
24
+ # Major version of the RazorRisk.Cassini.Services.RESTful.ClientEdgeService library
25
+ VERSION_MAJOR = VERSION_PARTS_[0] # :nodoc:
26
+ # Minor version of the RazorRisk.Cassini.Services.RESTful.ClientEdgeService library
27
+ VERSION_MINOR = VERSION_PARTS_[1] # :nodoc:
28
+ # Patch version of the RazorRisk.Cassini.Services.RESTful.ClientEdgeService library
29
+ VERSION_PATCH = VERSION_PARTS_[2] # :nodoc:
30
+ # Commit version of the RazorRisk.Cassini.Services.RESTful.ClientEdgeService library
31
+ VERSION_COMMIT = VERSION_PARTS_[3] || 0 # :nodoc:
32
+
33
+
34
+ # The description of the framework
35
+ DESCRIPTION = "Razor Risk's Cassini Web-framework's Client Edge Service"
36
+
37
+ # [DEPRECATED] Instead use +DESCRIPTION+
38
+ FRAMEWORK_DESCRIPTION = DESCRIPTION
39
+ end # module ClientEdgeService
40
+
41
+ end # module Services
42
+ end # module Applications
43
+ end # module Cassini
44
+ end # module RazorRisk
45
+
46
+ # ############################## end of file ############################# #
47
+
48
+
@@ -0,0 +1,2 @@
1
+
2
+ require 'razor_risk/cassini/applications/services/client_edge_service/version'
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: services-clientedgeservice
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.14.10
5
+ platform: ruby
6
+ authors:
7
+ - Razor Risk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-06-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: razorrisk-cassini-ces
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: razorrisk-cassini-common
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.26.22
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '1.0'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.26.22
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: clasp-ruby
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.14'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.14'
61
+ - !ruby/object:Gem::Dependency
62
+ name: libclimate-ruby
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.10'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.10'
75
+ - !ruby/object:Gem::Dependency
76
+ name: pantheios-ruby
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 0.20.2
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 0.20.2
89
+ - !ruby/object:Gem::Dependency
90
+ name: sinatra
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 1.4.8
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 1.4.8
103
+ - !ruby/object:Gem::Dependency
104
+ name: xqsr3
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.30'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '0.30'
117
+ description: Razor Risk's Cassini Web-framework's Client Edge Service
118
+ email: operations@razor-risk.com
119
+ executables:
120
+ - razorrisk-microservice-clientedgeservice
121
+ extensions: []
122
+ extra_rdoc_files: []
123
+ files:
124
+ - CHANGELOG.md
125
+ - LICENSE
126
+ - README.md
127
+ - bin/razorrisk-microservice-clientedgeservice
128
+ - lib/razor_risk/cassini/applications/services/client_edge_service.rb
129
+ - lib/razor_risk/cassini/applications/services/client_edge_service/version.rb
130
+ homepage: https://razor-risk.com/
131
+ licenses:
132
+ - Nonstandard
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: '2.0'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.6.14
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: Razor Risk Cassini Client Edge Service
154
+ test_files: []