gloo 4.6.1 → 5.0

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/gloo.gemspec +22 -11
  4. data/lib/VERSION +1 -1
  5. data/lib/VERSION_NOTES +12 -0
  6. data/lib/gloo/app/engine.rb +8 -1
  7. data/lib/gloo/app/running_app.rb +13 -0
  8. data/lib/gloo/app/settings.rb +5 -1
  9. data/lib/gloo/core/dictionary.rb +15 -2
  10. data/lib/gloo/objs/ctrl/each.rb +2 -2
  11. data/lib/gloo/plugin/base.rb +19 -0
  12. data/lib/gloo/plugin/callback.rb +33 -0
  13. data/lib/gloo/plugin/ext_manager.rb +90 -0
  14. data/lib/gloo/plugin/lib_manager.rb +97 -0
  15. data/lib/gloo/verbs/exists.rb +75 -0
  16. data/lib/gloo/verbs/help.rb +58 -1
  17. data/lib/gloo/verbs/load.rb +49 -5
  18. data/lib/gloo/verbs/redirect.rb +2 -1
  19. metadata +38 -166
  20. data/lib/gloo/objs/cli/colorize.rb +0 -73
  21. data/lib/gloo/objs/cli/confirm.rb +0 -96
  22. data/lib/gloo/objs/cli/menu.rb +0 -370
  23. data/lib/gloo/objs/cli/menu_item.rb +0 -95
  24. data/lib/gloo/objs/cli/prompt.rb +0 -110
  25. data/lib/gloo/objs/cli/select.rb +0 -127
  26. data/lib/gloo/objs/ctrl/each_repo.rb +0 -84
  27. data/lib/gloo/objs/data/markdown.rb +0 -133
  28. data/lib/gloo/objs/data/markdown_ext.rb +0 -260
  29. data/lib/gloo/objs/data/mysql.rb +0 -254
  30. data/lib/gloo/objs/data/pg.rb +0 -216
  31. data/lib/gloo/objs/data/query.rb +0 -269
  32. data/lib/gloo/objs/data/query_result.rb +0 -158
  33. data/lib/gloo/objs/data/sqlite.rb +0 -174
  34. data/lib/gloo/objs/data/table.rb +0 -267
  35. data/lib/gloo/objs/dev/git.rb +0 -140
  36. data/lib/gloo/objs/dev/stats.rb +0 -123
  37. data/lib/gloo/objs/system/ssh_exec.rb +0 -126
  38. data/lib/gloo/objs/web/slack.rb +0 -130
  39. data/lib/gloo/objs/web/teams.rb +0 -117
  40. data/lib/gloo/objs/web_svr/element.rb +0 -254
  41. data/lib/gloo/objs/web_svr/field.rb +0 -429
  42. data/lib/gloo/objs/web_svr/form.rb +0 -271
  43. data/lib/gloo/objs/web_svr/page.rb +0 -562
  44. data/lib/gloo/objs/web_svr/partial.rb +0 -210
  45. data/lib/gloo/objs/web_svr/svr.rb +0 -713
  46. data/lib/gloo/utils/stats.rb +0 -206
  47. data/lib/gloo/verbs/alert.rb +0 -79
  48. data/lib/gloo/verbs/beep.rb +0 -40
  49. data/lib/gloo/web_svr/asset.rb +0 -407
  50. data/lib/gloo/web_svr/asset_info.rb +0 -116
  51. data/lib/gloo/web_svr/config.rb +0 -56
  52. data/lib/gloo/web_svr/embedded_renderer.rb +0 -154
  53. data/lib/gloo/web_svr/handler.rb +0 -154
  54. data/lib/gloo/web_svr/request.rb +0 -143
  55. data/lib/gloo/web_svr/request_params.rb +0 -181
  56. data/lib/gloo/web_svr/response.rb +0 -177
  57. data/lib/gloo/web_svr/response_code.rb +0 -69
  58. data/lib/gloo/web_svr/routing/resource_router.rb +0 -47
  59. data/lib/gloo/web_svr/routing/router.rb +0 -232
  60. data/lib/gloo/web_svr/routing/show_routes.rb +0 -94
  61. data/lib/gloo/web_svr/server.rb +0 -105
  62. data/lib/gloo/web_svr/session.rb +0 -215
  63. data/lib/gloo/web_svr/table_renderer.rb +0 -151
  64. data/lib/gloo/web_svr/web_method.rb +0 -54
  65. /data/lib/gloo/objs/{security → str_utils}/cipher.rb +0 -0
  66. /data/lib/gloo/objs/{security → str_utils}/csrf_token.rb +0 -0
  67. /data/lib/gloo/objs/{security → str_utils}/password.rb +0 -0
  68. /data/lib/gloo/objs/{ror → system}/erb.rb +0 -0
  69. /data/lib/gloo/objs/{ror → system}/eval.rb +0 -0
@@ -1,713 +0,0 @@
1
- # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
- # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
- #
4
- # A web web server running inside gloo.
5
- #
6
-
7
- module Gloo
8
- module Objs
9
- class Svr < Gloo::Core::Obj
10
-
11
- KEYWORD = 'server'.freeze
12
- KEYWORD_SHORT = 'svr'.freeze
13
-
14
- # ---------------------------------------------------------------------
15
- # CONFIGURATION KEYS
16
- # ---------------------------------------------------------------------
17
- CONFIG = 'config'.freeze
18
- SCHEME = 'scheme'.freeze
19
- HTTP = 'http'.freeze
20
- HTTPS = 'https'.freeze
21
- HOST = 'host'.freeze
22
- PORT = 'port'.freeze
23
- SESSION_NAME = 'session_name'.freeze
24
- ENCRYPT_KEY = 'encryption_key'.freeze
25
- ENCRYPT_IV = 'encryption_iv'.freeze
26
- COOKIE_EXPIRES = 'cookie_expires'.freeze
27
- COOKIE_PATH = 'cookie_path'.freeze
28
- DEFAULT_COOKIE_PATH = '/'.freeze
29
-
30
- # SSL Configuration
31
- SSL_CERT = 'ssl_cert'.freeze
32
- SSL_KEY = 'ssl_key'.freeze
33
-
34
- # ---------------------------------------------------------------------
35
- # OTHER KEYS
36
- # ---------------------------------------------------------------------
37
-
38
- # Events
39
- ON_START = 'on_start'.freeze
40
- ON_STOP = 'on_stop'.freeze
41
- ON_REQUEST = 'on_request'.freeze
42
- ON_RESPONSE = 'on_response'.freeze
43
- RESQUEST_DATA = 'request_data'.freeze
44
- METHOD = 'method'.freeze
45
- PATH = 'path'.freeze
46
- QUERY = 'query'.freeze
47
- IP = 'ip'.freeze
48
- RESPONSE_DATA = 'response_data'.freeze
49
- TYPE = 'type'.freeze
50
- CODE = 'code'.freeze
51
- ELAPSED = 'elapsed'.freeze
52
- DB = 'db'.freeze
53
- PAGE = 'page'.freeze
54
- CURRENT_PAGE = 'current_page'.freeze
55
-
56
- # Container with pages in the web app.
57
- PAGES = 'pages'.freeze
58
-
59
- # Default layout for pages.
60
- LAYOUT = 'layout'.freeze
61
-
62
- # Alias to the home and error pages
63
- HOME = 'home'.freeze
64
- ERR_PAGE = 'error'.freeze
65
-
66
- # Session
67
- SESSION = 'session'.freeze
68
-
69
-
70
- # Messages
71
- SERVER_NOT_RUNNING = 'The web server is not running!'.freeze
72
-
73
- #
74
- # Should the current request be redirected?
75
- # If the redirect is set, then use that page instead
76
- # of the one requested.
77
- #
78
- attr_accessor :redirect, :redirect_hard
79
- attr_accessor :router, :asset, :embedded_renderer
80
- attr_accessor :session
81
-
82
- #
83
- # The name of the object type.
84
- #
85
- def self.typename
86
- return KEYWORD
87
- end
88
-
89
- #
90
- # The short name of the object type.
91
- #
92
- def self.short_typename
93
- return KEYWORD_SHORT
94
- end
95
-
96
- #
97
- # Set the value with any necessary type conversions.
98
- #
99
- def set_value( new_value )
100
- self.value = new_value.to_s
101
- end
102
-
103
- #
104
- # Does this object support multi-line values?
105
- # Initially only true for scripts.
106
- #
107
- def multiline_value?
108
- return false
109
- end
110
-
111
- #
112
- # Get the default layout for the app.
113
- #
114
- def default_page_layout
115
- o = find_child LAYOUT
116
- return nil unless o
117
-
118
- o = Gloo::Objs::Alias.resolve_alias( @engine, o )
119
- return o
120
- end
121
-
122
-
123
- # ---------------------------------------------------------------------
124
- # Configuration
125
- # ---------------------------------------------------------------------
126
-
127
- #
128
- # Get the Scheme (http or https) from the child object.
129
- # Returns nil if there is none.
130
- #
131
- def scheme_value
132
- config = find_child CONFIG
133
- scheme = config.find_child SCHEME
134
- return nil unless scheme
135
-
136
- return scheme.value
137
- end
138
-
139
- #
140
- # Get the host from the child object.
141
- # Returns nil if there is none.
142
- #
143
- def host_value
144
- config = find_child CONFIG
145
- host = config.find_child HOST
146
- return nil unless host
147
-
148
- return host.value
149
- end
150
-
151
- #
152
- # Get the port from the child object.
153
- # Returns nil if there is none.
154
- #
155
- def port_value
156
- config = find_child CONFIG
157
- port = config.find_child PORT
158
- return nil unless port
159
-
160
- return port.value
161
- end
162
-
163
- #
164
- # Is this server configured to use a session?
165
- # It is if theere is a non-empty session name.
166
- #
167
- def use_session?
168
- return ! session_name.blank?
169
- end
170
-
171
- #
172
- # Get the session cookie name.
173
- #
174
- def session_name
175
- config = find_child CONFIG
176
- session_name = config.find_child SESSION_NAME
177
- return nil unless session_name
178
-
179
- name = session_name.value
180
- return nil if name.blank?
181
-
182
- return name
183
- end
184
-
185
- #
186
- # Get the key for the encryption cipher.
187
- #
188
- def encryption_key
189
- config = find_child CONFIG
190
- o = config.find_child ENCRYPT_KEY
191
- return nil unless o
192
-
193
- o = Gloo::Objs::Alias.resolve_alias( @engine, o )
194
- return o.value
195
- end
196
-
197
- #
198
- # Get the initialization vector for the cipher.
199
- #
200
- def encryption_iv
201
- config = find_child CONFIG
202
- o = config.find_child ENCRYPT_IV
203
- return nil unless o
204
-
205
- o = Gloo::Objs::Alias.resolve_alias( @engine, o )
206
- return o.value
207
- end
208
-
209
- #
210
- # Get the path for the session cookie.
211
- # If not specified, use the root path.
212
- #
213
- def session_cookie_path
214
- config = find_child CONFIG
215
- o = config.find_child COOKIE_PATH
216
- if o
217
- return o.value
218
- else
219
- return DEFAULT_COOKIE_PATH
220
- end
221
- end
222
-
223
- #
224
- # Get the expiration time for the session cookie.
225
- # If not specified, use one week from now.
226
- #
227
- def session_cookie_expires
228
- config = find_child CONFIG
229
- o = config.find_child COOKIE_EXPIRES
230
- if o
231
- dt = Chronic.parse( o.value )
232
- return dt
233
- else
234
- return 1.week.from_now
235
- end
236
- end
237
-
238
- #
239
- # Should the session cookie be secure?
240
- # Get the value from the scheme settings/config.
241
- #
242
- def session_cookie_secure
243
- return scheme_value.downcase == HTTPS
244
- end
245
-
246
-
247
- # ---------------------------------------------------------------------
248
- # Session
249
- # ---------------------------------------------------------------------
250
-
251
- #
252
- # Get the session container object.
253
- # If there is none, one will be created.
254
- #
255
- def session_container
256
- o = find_child SESSION
257
-
258
- unless o
259
- o = add_session_container
260
- end
261
-
262
- return o
263
- end
264
-
265
- #
266
- # Add the session container because it is missing.
267
- #
268
- def add_session_container
269
- fac = @engine.factory
270
- return fac.create_can SESSION, self
271
- end
272
-
273
- #
274
- # Get the data from the session container.
275
- # Data will be in the form of a hash ( key => value ).
276
- #
277
- def get_session_data
278
- data = {}
279
-
280
- session_container.children.each do |session_var|
281
- key = session_var.name
282
- value = session_var.value
283
- data[ key ] = value
284
- end
285
-
286
- return data
287
- end
288
-
289
- #
290
- # Get the session child object with the given value.
291
- # Create the child if it does not exist.
292
- #
293
- def set_session_var( key, value )
294
- child_obj = session_container.find_child( key )
295
- unless child_obj
296
- fac = @engine.factory
297
- child_obj = fac.create_string key, value, session_container
298
- end
299
- child_obj.value = value
300
- end
301
-
302
- #
303
- # Clear out all session data.
304
- # Important to do this after the response is sent
305
- # to avoid holding on to data that is no longer needed.
306
- #
307
- def reset_session_data
308
- session_container.children.each do |session_var|
309
- session_var.value = ''
310
- end
311
- end
312
-
313
-
314
- # ---------------------------------------------------------------------
315
- # SSL
316
- # ---------------------------------------------------------------------
317
-
318
- #
319
- # Is SSL configured for this server?
320
- # True if the Cert and Key are both present.
321
- #
322
- def use_ssl?
323
- return ssl_cert && ssl_key
324
- end
325
-
326
- #
327
- # Get the SSL certificate from the child object.
328
- # Returns nil if there is none.
329
- #
330
- def ssl_cert
331
- cert = find_child SSL_CERT
332
- return nil unless cert
333
-
334
- cert = Gloo::Objs::Alias.resolve_alias( @engine, cert )
335
- return cert
336
- end
337
-
338
- #
339
- # Get the SSL key from the child object.
340
- # Returns nil if there is none.
341
- #
342
- def ssl_key
343
- key = find_child SSL_KEY
344
- return nil unless key
345
-
346
- key = Gloo::Objs::Alias.resolve_alias( @engine, key )
347
- return key
348
- end
349
-
350
- #
351
- # Get the SSL configuration for the server.
352
- #
353
- def ssl_config
354
- return nil unless use_ssl?
355
-
356
- return {
357
- :private_key_file => ssl_key.value,
358
- :cert_chain_file => ssl_cert.value,
359
- :verify_peer => false,
360
- }
361
- end
362
-
363
- # ---------------------------------------------------------------------
364
- # Children
365
- # ---------------------------------------------------------------------
366
-
367
- #
368
- # Does this object have children to add when an object
369
- # is created in interactive mode?
370
- # This does not apply during obj load, etc.
371
- #
372
- def add_children_on_create?
373
- return true
374
- end
375
-
376
- #
377
- # Add children to this object.
378
- # This is used by containers to add children needed
379
- # for default configurations.
380
- #
381
- def add_default_children
382
- fac = @engine.factory
383
-
384
- # Configuration
385
- config = fac.create_can CONFIG, self
386
- fac.create_string SCHEME, HTTP, config
387
- fac.create_string HOST, 'localhost', config
388
- fac.create_string PORT, '8080', config
389
-
390
- fac.create_script ON_START, '', self
391
- fac.create_script ON_STOP, '', self
392
-
393
- fac.create_alias LAYOUT, nil, self
394
- fac.create_alias HOME, nil, self
395
- fac.create_alias ERR_PAGE, nil, self
396
-
397
- fac.create_can PAGES, self
398
- end
399
-
400
-
401
- # ---------------------------------------------------------------------
402
- # Messages
403
- # ---------------------------------------------------------------------
404
-
405
- #
406
- # Get a list of message names that this object receives.
407
- #
408
- def self.messages
409
- return super + [ 'start', 'stop',
410
- 'list_routes', 'list_assets',
411
- 'add_session_to_response', 'clear_session_data',
412
- 'list_asset_img', 'list_asset_css', 'list_asset_js' ]
413
- end
414
-
415
- #
416
- # Start the gloo web server.
417
- #
418
- def msg_start
419
- @engine.log.debug "Starting web server…"
420
- # @engine.log.quiet = true
421
-
422
- # Set running app to this object.
423
- @engine.start_running_app( self )
424
- # The running app will call the start function (below)
425
- end
426
-
427
- #
428
- # Stop the running web server.
429
- #
430
- def msg_stop
431
- if @web_server
432
- @engine.stop_running_app
433
- # The running app will call the stop function (below)
434
- else
435
- @engine.err SERVER_NOT_RUNNING
436
- end
437
- end
438
-
439
- #
440
- # Helper message to show all routes in the running server.
441
- # A Debugging tool.
442
- #
443
- def msg_list_routes
444
- if @router
445
- @router.show_routes
446
- else
447
- @engine.err SERVER_NOT_RUNNING
448
- end
449
- end
450
-
451
- #
452
- # Helper message to show all assets in the running server.
453
- # A Debugging tool.
454
- #
455
- def msg_list_assets
456
- if @router
457
- Gloo::WebSvr::AssetInfo.list_all( @engine )
458
- else
459
- @engine.err SERVER_NOT_RUNNING
460
- end
461
- end
462
-
463
- #
464
- # List all asset images in the running server.
465
- # A Debugging tool.
466
- #
467
- def msg_list_asset_img
468
- if @router
469
- @asset.list_image_assets
470
- else
471
- @engine.err SERVER_NOT_RUNNING
472
- end
473
- end
474
-
475
- #
476
- # List all asset css in the running server.
477
- # A Debugging tool.
478
- #
479
- def msg_list_asset_css
480
- if @router
481
- @asset.list_css_assets
482
- else
483
- @engine.err SERVER_NOT_RUNNING
484
- end
485
- end
486
-
487
- #
488
- # List all asset javascript in the running server.
489
- # A Debugging tool.
490
- #
491
- def msg_list_asset_js
492
- if @router
493
- @asset.list_js_assets
494
- else
495
- @engine.err SERVER_NOT_RUNNING
496
- end
497
- end
498
-
499
- #
500
- # Add the session data to the response.
501
- # This will be done for the current (next) request only.
502
- #
503
- def msg_add_session_to_response
504
- @session.add_session_to_response if @session
505
- end
506
-
507
- #
508
- # Clear out the session data, and remove it from the response.
509
- #
510
- def msg_clear_session_data
511
- reset_session_data
512
- @session.clear_session_data if @session
513
- end
514
-
515
-
516
- # ---------------------------------------------------------------------
517
- # Start and Stop Events
518
- # Might come from messages or from other application events.
519
- # RunningApp fires these events.
520
- # ---------------------------------------------------------------------
521
-
522
- #
523
- # Start running the web server.
524
- #
525
- def start
526
- config = Gloo::WebSvr::Config.new( scheme_value, host_value, port_value )
527
- @engine.log.info "Web Server URL: #{config.base_url}"
528
-
529
- handler = Gloo::WebSvr::Handler.new( @engine, self )
530
- @web_server = Gloo::WebSvr::Server.new( @engine, handler, config, ssl_config )
531
- @web_server.start
532
-
533
- @router = Gloo::WebSvr::Routing::Router.new( @engine, self )
534
- @router.add_page_routes
535
-
536
- @asset = Gloo::WebSvr::Asset.new( @engine, self )
537
- @asset.add_asset_routes
538
-
539
- @embedded_renderer = Gloo::WebSvr::EmbeddedRenderer.new( @engine, self )
540
-
541
- @session = Gloo::WebSvr::Session.new( @engine, self )
542
-
543
- run_on_start
544
- @engine.log.info "Web server started and listening…"
545
- end
546
-
547
- #
548
- # Stop the running web server.
549
- #
550
- def stop
551
- @engine.log.info "Stopping web server…"
552
-
553
- # Last chance to clear out session data.
554
- reset_session_data
555
-
556
- @web_server.stop
557
- @web_server = nil
558
- @router = nil
559
-
560
- run_on_stop
561
- @engine.log.info "Web server stopped…"
562
- end
563
-
564
-
565
- # ---------------------------------------------------------------------
566
- # On Events - Scripts
567
- # ---------------------------------------------------------------------
568
-
569
- #
570
- # Run the on start script if there is one.
571
- #
572
- def run_on_start
573
- o = find_child ON_START
574
- return unless o
575
-
576
- Gloo::Exec::Dispatch.message( @engine, 'run', o )
577
- end
578
-
579
- #
580
- # Run the on stop script if there is one.
581
- #
582
- def run_on_stop
583
- o = find_child ON_STOP
584
- return unless o
585
-
586
- Gloo::Exec::Dispatch.message( @engine, 'run', o )
587
- end
588
-
589
- #
590
- # Run the on request script if there is one.
591
- # Set thee current page object so the app knows
592
- # which page is being requested.
593
- #
594
- def run_on_request current_page
595
- for_page = find_child CURRENT_PAGE
596
- alias_value = current_page.pn
597
- for_page.set_value( alias_value ) if for_page
598
- o = find_child ON_REQUEST
599
- return unless o
600
- o = Gloo::Objs::Alias.resolve_alias( @engine, o )
601
-
602
- Gloo::Exec::Dispatch.message( @engine, 'run', o, CURRENT_PAGE => current_page )
603
- end
604
-
605
- #
606
- # Run the on response script if there is one.
607
- #
608
- def run_on_response
609
- o = find_child ON_RESPONSE
610
- return unless o
611
- o = Gloo::Objs::Alias.resolve_alias( @engine, o )
612
-
613
- Gloo::Exec::Dispatch.message( @engine, 'run', o )
614
- end
615
-
616
- #
617
- # Set up the request data for the page load.
618
- # This is done before the on_request event is fired.
619
- #
620
- def set_request_data( request )
621
- # Clear out the redirect if there is one since this is the start of
622
- # a new request.
623
- @redirect = nil
624
-
625
- data = find_child RESQUEST_DATA
626
- return unless data
627
- data = Gloo::Objs::Alias.resolve_alias( @engine, data )
628
-
629
- data.find_child( METHOD )&.set_value( request.method )
630
- data.find_child( HOST )&.set_value( request.host )
631
- data.find_child( PATH )&.set_value( request.path )
632
- data.find_child( QUERY )&.set_value( request.query )
633
- data.find_child( IP )&.set_value( request.ip )
634
- end
635
-
636
- #
637
- # Set up the response data for the page load.
638
- # This is done after the page is rendered and before
639
- # the on_response event is fired.
640
- #
641
- def set_response_data( request, response, page_obj=nil )
642
- begin
643
- data = find_child RESPONSE_DATA
644
- return unless data
645
- data = Gloo::Objs::Alias.resolve_alias( @engine, data )
646
-
647
- data.find_child( ELAPSED )&.set_value( request.elapsed )
648
- data.find_child( DB )&.set_value( request.db )
649
-
650
- if ( response )
651
- data.find_child( TYPE )&.set_value( response.type )
652
- data.find_child( CODE )&.set_value( response.code )
653
- else
654
- data.find_child( TYPE )&.set_value( '' )
655
- data.find_child( CODE )&.set_value( '' )
656
- end
657
-
658
- if page_obj
659
- data.find_child( PAGE )&.set_value( page_obj.pn )
660
- end
661
- rescue => e
662
- @engine.log_exception e
663
- end
664
- end
665
-
666
-
667
- # ---------------------------------------------------------------------
668
- # Pages and standard elements.
669
- # ---------------------------------------------------------------------
670
-
671
- #
672
- # Get the pages container.
673
- #
674
- def pages_container
675
- return find_child PAGES
676
- end
677
-
678
- #
679
- # Get the home page, the root/default route.
680
- #
681
- def home_page
682
- o = find_child HOME
683
- return nil unless o
684
-
685
- o = Gloo::Objs::Alias.resolve_alias( @engine, o )
686
- return o
687
- end
688
-
689
- #
690
- # Get the application error page.
691
- #
692
- def err_page
693
- o = find_child ERR_PAGE
694
- return nil unless o
695
-
696
- o = Gloo::Objs::Alias.resolve_alias( @engine, o )
697
- return o
698
- end
699
-
700
- #
701
- # Get the default layout for pages.
702
- #
703
- def default_layout
704
- o = find_child LAYOUT
705
- return nil unless o
706
-
707
- o = Gloo::Objs::Alias.resolve_alias( @engine, o )
708
- return o
709
- end
710
-
711
- end
712
- end
713
- end