services-clientedgeservice 0.14.10

Sign up to get free protection for your applications and to get access to all the features.
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: []