glib-web 0.4.6 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +5 -5
  2. data/app/controllers/concerns/application/json/libs.rb +0 -0
  3. data/app/controllers/concerns/application/json/transformation.rb +0 -0
  4. data/app/controllers/concerns/application/json/ui.rb +0 -0
  5. data/app/controllers/concerns/application/json/validation.rb +0 -0
  6. data/app/controllers/concerns/glib/auth/policy.rb +0 -0
  7. data/app/controllers/concerns/glib/json/dynamic_text.rb +21 -18
  8. data/app/controllers/concerns/glib/json/libs.rb +13 -9
  9. data/app/controllers/concerns/glib/json/new_dynamic_text.rb +120 -0
  10. data/app/controllers/concerns/glib/json/traversal.rb +86 -0
  11. data/app/controllers/glib/home_controller.rb +0 -0
  12. data/app/helpers/glib/dynamic_texts_helper.rb +4 -2
  13. data/app/helpers/glib/json_ui/abstract_builder.rb +0 -0
  14. data/app/helpers/glib/json_ui/action_builder.rb +0 -0
  15. data/app/helpers/glib/json_ui/list_builders.rb +0 -0
  16. data/app/helpers/glib/json_ui/menu_builder.rb +0 -0
  17. data/app/helpers/glib/json_ui/page_helper.rb +0 -0
  18. data/app/helpers/glib/json_ui/response_helper.rb +0 -0
  19. data/app/helpers/glib/json_ui/split_builders.rb +0 -0
  20. data/app/helpers/glib/json_ui/styling_helper.rb +0 -0
  21. data/app/helpers/glib/json_ui/table_builders.rb +0 -0
  22. data/app/helpers/glib/json_ui/view_builder/banners.rb +0 -0
  23. data/app/helpers/glib/json_ui/view_builder/fields.rb +0 -0
  24. data/app/helpers/glib/json_ui/view_builder/panels.rb +0 -0
  25. data/app/helpers/glib/json_ui/view_builder.rb +0 -0
  26. data/app/models/glib/dynamic_text_record.rb +0 -0
  27. data/app/models/glib/text.rb +0 -0
  28. data/app/policies/glib/application_policy.rb +148 -148
  29. data/app/views/app/views/json_ui/vue/renderer.html.erb +0 -0
  30. data/app/views/json_ui/garage/_nav_menu.json.jbuilder +0 -0
  31. data/app/views/json_ui/garage/actions/index.json.jbuilder +0 -0
  32. data/app/views/json_ui/garage/dynamic_texts/basic.json.jbuilder +1 -0
  33. data/app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder +0 -0
  34. data/app/views/json_ui/garage/forms/basic.json.jbuilder +0 -0
  35. data/app/views/json_ui/garage/forms/basic_post.json.jbuilder +0 -0
  36. data/app/views/json_ui/garage/forms/checkboxes.json.jbuilder +0 -0
  37. data/app/views/json_ui/garage/forms/dynamic_select.json.jbuilder +0 -0
  38. data/app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder +0 -0
  39. data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +0 -0
  40. data/app/views/json_ui/garage/forms/floating_submit.json.jbuilder +0 -0
  41. data/app/views/json_ui/garage/forms/generic_post.json.jbuilder +0 -0
  42. data/app/views/json_ui/garage/forms/get_request.json.jbuilder +0 -0
  43. data/app/views/json_ui/garage/forms/index.json.jbuilder +0 -0
  44. data/app/views/json_ui/garage/forms/pickers.json.jbuilder +0 -0
  45. data/app/views/json_ui/garage/forms/rich_text.json.jbuilder +0 -0
  46. data/app/views/json_ui/garage/forms/selects.json.jbuilder +0 -0
  47. data/app/views/json_ui/garage/forms/submission_flow.json.jbuilder +0 -0
  48. data/app/views/json_ui/garage/forms/submission_flow_post.json.jbuilder +0 -0
  49. data/app/views/json_ui/garage/forms/submission_indicator.json.jbuilder +0 -0
  50. data/app/views/json_ui/garage/forms/submission_indicator_post.json.jbuilder +0 -0
  51. data/app/views/json_ui/garage/forms/text_validation.json.jbuilder +0 -0
  52. data/app/views/json_ui/garage/home/blank.json.jbuilder +0 -0
  53. data/app/views/json_ui/garage/home/index.json.jbuilder +0 -0
  54. data/app/views/json_ui/garage/lists/_infinite_scroll_section.json.jbuilder +0 -0
  55. data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +0 -0
  56. data/app/views/json_ui/garage/lists/fab.json.jbuilder +0 -0
  57. data/app/views/json_ui/garage/lists/index.json.jbuilder +0 -0
  58. data/app/views/json_ui/garage/lists/infinite_scroll.json.jbuilder +0 -0
  59. data/app/views/json_ui/garage/lists/templating.json.jbuilder +0 -0
  60. data/app/views/json_ui/garage/pages/flat_centered.json.jbuilder +0 -0
  61. data/app/views/json_ui/garage/pages/full_width.json.jbuilder +0 -0
  62. data/app/views/json_ui/garage/pages/full_width_height.json.jbuilder +0 -0
  63. data/app/views/json_ui/garage/pages/index.json.jbuilder +0 -0
  64. data/app/views/json_ui/garage/pages/layout.json.jbuilder +0 -0
  65. data/app/views/json_ui/garage/pages/nav_buttons.json.jbuilder +0 -0
  66. data/app/views/json_ui/garage/pages/tab_bar.json.jbuilder +0 -0
  67. data/app/views/json_ui/garage/panels/card.json.jbuilder +0 -0
  68. data/app/views/json_ui/garage/panels/carousel.json.jbuilder +0 -0
  69. data/app/views/json_ui/garage/panels/custom.json.jbuilder +0 -0
  70. data/app/views/json_ui/garage/panels/horizontal.json.jbuilder +0 -0
  71. data/app/views/json_ui/garage/panels/index.json.jbuilder +0 -0
  72. data/app/views/json_ui/garage/panels/responsive.json.jbuilder +0 -0
  73. data/app/views/json_ui/garage/panels/split.json.jbuilder +0 -0
  74. data/app/views/json_ui/garage/panels/vertical.json.jbuilder +0 -0
  75. data/app/views/json_ui/garage/tables/_autoload_section.json.jbuilder +0 -0
  76. data/app/views/json_ui/garage/tables/autoload_all.json.jbuilder +0 -0
  77. data/app/views/json_ui/garage/tables/export_import.json.jbuilder +0 -0
  78. data/app/views/json_ui/garage/tables/horizontal_scroll.json.jbuilder +0 -0
  79. data/app/views/json_ui/garage/tables/index.json.jbuilder +0 -0
  80. data/app/views/json_ui/garage/views/banners.json.jbuilder +0 -0
  81. data/app/views/json_ui/garage/views/calendar_data.json.jbuilder +0 -0
  82. data/app/views/json_ui/garage/views/carousels.json.jbuilder +0 -0
  83. data/app/views/json_ui/garage/views/charts.json.jbuilder +0 -0
  84. data/app/views/json_ui/garage/views/images.json.jbuilder +0 -0
  85. data/app/views/json_ui/garage/views/index.json.jbuilder +0 -0
  86. data/app/views/json_ui/garage/views/links.json.jbuilder +0 -0
  87. data/app/views/json_ui/garage/views/map_data.json.jbuilder +0 -0
  88. data/app/views/json_ui/garage/views/misc.json.jbuilder +0 -0
  89. data/app/views/json_ui/garage/views/texts.json.jbuilder +0 -0
  90. data/config/routes.rb +0 -0
  91. data/lib/generators/glib/install_generator.rb +0 -0
  92. data/lib/generators/templates/20191017062519_create_texts.rb +0 -0
  93. data/lib/generators/templates/20191024063257_add_scope_to_texts.rb +0 -0
  94. data/lib/generators/templates/20191112095018_add_lang_to_texts.rb +0 -0
  95. data/lib/generators/templates/20191126071051_create_active_storage_tables.active_storage.rb +0 -0
  96. data/lib/generators/templates/database.yml +0 -0
  97. data/lib/generators/templates/dynamic_text.rb +0 -0
  98. data/lib/glib/engine.rb +0 -0
  99. data/lib/glib/json_crawler/action_crawler.rb +0 -0
  100. data/lib/glib/json_crawler/action_crawlers/action_http.rb +0 -0
  101. data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +0 -0
  102. data/lib/glib/json_crawler/action_crawlers/nav_initiate.rb +0 -0
  103. data/lib/glib/json_crawler/action_crawlers/windows_open.rb +0 -0
  104. data/lib/glib/json_crawler/http.rb +0 -0
  105. data/lib/glib/json_crawler/router.rb +10 -50
  106. data/lib/glib/json_crawler.rb +0 -0
  107. data/lib/glib/value.rb +0 -0
  108. data/lib/glib/version.rb +0 -0
  109. data/lib/glib-web.rb +0 -0
  110. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 722e3662e1925d71fe99c6eec5897c0e59bf0f53
4
- data.tar.gz: 6cb98608b96b0fc9a9a88c8ba44b7e15855f0465
2
+ SHA256:
3
+ metadata.gz: b310f37fb4b17ad903b9747af586ced2918eb3bd2415dafc68ebf7133415ca40
4
+ data.tar.gz: 6fca728dab6fffa7ced37f979f5d0537d42bbee83410ce7db54a26d10441f482
5
5
  SHA512:
6
- metadata.gz: 233399bbc9018a97adb6fa9316b566698e19e24607f0433fc684b58648af295778aaf5676f3af51edc9a4813410e6e82d1d6443a6d512d13e668cdf9a1c44f13
7
- data.tar.gz: 437210e7dfb02b783d8593809c59e155b91f552be6785ef46d05b7cf6f73138e783ffffa0fc814c7dce31099159e0b6644e49ea3570854cf8102fbace060b532
6
+ metadata.gz: 6f1b8b84319689a92c56827bd4791be5da1fe048f627b88a3e60c1d5d8a47adac19ac2e7b6d6ea0985ed8c0bdff4426893c88780aa548eecac29d907138d757b
7
+ data.tar.gz: 02a7d64bd89e2a49073b6d9d66e7b145c36f750d05f143ed5c6b476dcedba5af1e55d6c60115e26a06dea7ac50d7bd14d10f1976cd746b4d14e5365780705664
File without changes
File without changes
File without changes
@@ -38,8 +38,8 @@ module Glib::Json::DynamicText
38
38
  JSON.parse(response)
39
39
  end
40
40
 
41
- def crawl views
42
- Glib::Json::DynamicText::crawl_multiple views, ->(view) do
41
+ def crawl(views)
42
+ Glib::Json::Crawler.new.crawl_multiple views, ->(view) do
43
43
  extract_spec(view, 'text')
44
44
  end
45
45
  end
@@ -58,31 +58,35 @@ module Glib::Json::DynamicText
58
58
  view[prop] = text.gsub(/\{\{(\w+)\}\}/) { args.fetch($1, "{{#{$1}}}") }
59
59
  end
60
60
  end
61
+ end
62
+
63
+ class Glib::Json::Crawler
64
+ attr_reader :forms
65
+
66
+ def initialize
67
+ @forms = []
68
+ end
61
69
 
62
- def self.crawl_multiple views, block
70
+ def crawl_multiple(views, block)
63
71
  if views.is_a? Array
64
72
  views.each do |view|
65
- crawl_single view, block
73
+ case view['view']
74
+ when 'panels/form-v1'
75
+ @forms << view
76
+ crawl_single view, block
77
+ @forms.pop
78
+ else
79
+ crawl_single view, block
80
+ end
66
81
  end
67
-
68
- # views.each do |view|
69
- # case view['view']
70
- # when 'panels/form-v1'
71
- # @@forms << view
72
- # crawl_single view, block
73
- # @@forms.pop
74
- # else
75
- # crawl_single view, block
76
- # end
77
- # end
78
82
  end
79
83
  end
80
84
 
81
- def self.crawl_vertical_content view, block
85
+ def crawl_vertical_content(view, block)
82
86
  crawl_multiple view['childViews'], block if view
83
87
  end
84
88
 
85
- def self.crawl_single view, block
89
+ def crawl_single(view, block)
86
90
  block.call view
87
91
 
88
92
  # Generic view children
@@ -106,5 +110,4 @@ module Glib::Json::DynamicText
106
110
  end
107
111
  end
108
112
  end
109
-
110
113
  end
@@ -27,7 +27,7 @@ module Glib::Json::Libs
27
27
  def json_ui_app_is_android?
28
28
  json_ui_app_device_os == 'android'
29
29
  end
30
-
30
+
31
31
  def json_ui_app_is_ios?
32
32
  json_ui_app_device_os == 'ios'
33
33
  end
@@ -44,7 +44,9 @@ module Glib::Json::Libs
44
44
  include Glib::Json::Transformation
45
45
  include Glib::Json::Validation
46
46
  include Glib::Json::Ui
47
- include Glib::Json::DynamicText
47
+
48
+ include Glib::Json::Traversal
49
+ include Glib::Json::NewDynamicText
48
50
 
49
51
  before_action :__json_ui_start
50
52
 
@@ -53,10 +55,12 @@ module Glib::Json::Libs
53
55
  __json_ui_commit(options)
54
56
  end
55
57
  after_action :__json_transformation_commit
56
- after_action :__json_dynamic_text_perform
57
58
  after_action :__json_validate_perform
59
+
60
+ after_action :__json_traversal_perform
61
+ after_action :__json_traversal_register_dynamic_text
58
62
  end
59
-
63
+
60
64
  def json_libs_set_locale
61
65
  before_action do
62
66
  # Need to explicitly fallback to EN
@@ -65,7 +69,7 @@ module Glib::Json::Libs
65
69
  I18n.locale = :en
66
70
  end
67
71
  end
68
-
72
+
69
73
  def json_libs_force_json_ui
70
74
  before_action do
71
75
  if params[:_render] != 'v1'
@@ -74,17 +78,17 @@ module Glib::Json::Libs
74
78
  end
75
79
  end
76
80
 
77
- def json_libs_rescue_csrf
81
+ def json_libs_rescue_csrf
78
82
  rescue_from ActionController::InvalidAuthenticityToken do |exception|
79
83
  sign_out(:user)
80
84
 
81
85
  respond_to do |format|
82
86
  format.json do
83
- render json: {
84
- onResponse: {
87
+ render json: {
88
+ onResponse: {
85
89
  action: 'windows/open-v1',
86
90
  url: root_url
87
- }
91
+ }
88
92
  }
89
93
  end
90
94
  end
@@ -0,0 +1,120 @@
1
+ module Glib::Json::NewDynamicText
2
+ def __json_traversal_register_dynamic_text
3
+ @__specs = {}
4
+ @__specs_db = {}
5
+
6
+ __json_traversal_on_traverse do |view|
7
+ extract_spec(view, 'text')
8
+ end
9
+
10
+ __json_traversal_on_complete do |view|
11
+ if @__specs.keys.size > 0
12
+ # translated_texts = retrieve_remote_texts(@__specs.keys)
13
+ translated_texts = retrieve_local_texts(@__specs.keys).merge(retrieve_remote_texts(@__specs.keys))
14
+ translated_texts.each do |key, value|
15
+ @__specs[key].each do |spec|
16
+ spec.substitute_with(value)
17
+ end
18
+
19
+ if @__specs_db[key] && @__specs_db[key].images.attached?
20
+ @__specs[key].each do |spec|
21
+ spec.substitute_image_with(@__specs_db[key].images)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def retrieve_example_texts(keys)
30
+ examples_translations = {
31
+ 'home.json_ui_garage.hello' => 'Hello {{name}}',
32
+ 'home.json_ui_garage.greeting' => 'Good day!',
33
+ }
34
+
35
+ translated_texts = {}
36
+ keys.each do |key|
37
+ translated_texts[key] = examples_translations[key]
38
+ end
39
+ translated_texts
40
+ end
41
+
42
+ def retrieve_remote_texts(keys)
43
+ response = RestClient.get(ENV['DTR_URL'], { params: { keys: keys } })
44
+ JSON.parse(response)
45
+ end
46
+
47
+ def retrieve_local_texts(keys)
48
+ translated_texts = {}
49
+ db_keys = []
50
+
51
+ contents = $dt_redis.pipelined do
52
+ keys.each do |key|
53
+ args = @__specs[key].first.args
54
+ options = {
55
+ scope: args.fetch(:scope, 'itinerarybuilder'),
56
+ lang: args.fetch(:lang, 'en')
57
+ }
58
+
59
+ scope_key = "#{options[:scope]}.#{options[:lang]}.#{key}"
60
+ $dt_redis.get(scope_key)
61
+ end
62
+ end
63
+
64
+ keys.each_with_index do |key, index|
65
+ if content = contents[index]
66
+ translated_texts[key] = content
67
+ db_keys << key if content.match(/\{\{image(\d)\}\}/)
68
+ else
69
+ db_keys << key
70
+ end
71
+ end
72
+
73
+ if db_keys.size > 0
74
+ texts = Glib::Text.where(key: db_keys)
75
+ texts.each do |text|
76
+ translated_texts[text.key] = text.content
77
+ @__specs_db[text.key] = text
78
+ end
79
+ end
80
+
81
+ translated_texts
82
+ end
83
+
84
+ def extract_spec(view, prop)
85
+ if (spec = view[prop])
86
+ if spec.is_a?(Hash) && (key = spec['dt_key'])
87
+ @__specs[key] ||= []
88
+ @__specs[key] << TextSpec.new(view, prop, spec)
89
+ end
90
+ end
91
+ end
92
+
93
+ TextSpec = Struct.new(:view, :prop, :args) do
94
+ def substitute_with(text)
95
+ view[prop] = text.gsub(/\{\{(\w+)\}\}/) { args.fetch($1, "{{#{$1}}}") }
96
+ end
97
+
98
+ def substitute_image_with(images)
99
+ view[prop] = view[prop].gsub(/\{\{image(\d)\}\}/) {
100
+ if image = images[$1.to_i - 1]
101
+ image_server_url(image.blob.key)
102
+ else
103
+ "{{image#{$1}}}"
104
+ end
105
+ }
106
+ end
107
+
108
+ def image_server_url(blob_key, w: 100, h: 100)
109
+ return unless blob_key.present?
110
+
111
+ uri = URI::HTTPS.build(
112
+ host: 'imageserver-demo.herokuapp.com',
113
+ path: "/image/#{ENV['AWS_S3_BUCKET']}/#{blob_key}",
114
+ query: { w: w, h: h }.to_param
115
+ )
116
+
117
+ uri.to_s
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,86 @@
1
+ module Glib::Json::Traversal
2
+ def __json_traversal_on_traverse(&block)
3
+ @__json_traversal_on_traverses ||= []
4
+ @__json_traversal_on_traverses << block
5
+ end
6
+
7
+ def __json_traversal_on_complete(&block)
8
+ @__json_traversal_on_completes ||= []
9
+ @__json_traversal_on_completes << block
10
+ end
11
+
12
+ def __json_traversal_perform
13
+ if (hash = json_transformation_start).is_a?(Hash)
14
+ traverse hash['header']&.[]('childViews')
15
+ traverse hash['body']&.[]('childViews')
16
+ traverse hash['footer']&.[]('childViews')
17
+
18
+ @__json_traversal_on_completes.each do |block|
19
+ block.call
20
+ end
21
+ end
22
+ end
23
+
24
+ def traverse(views)
25
+ Visitor.new.traverse_multiple views, ->(view) do
26
+ @__json_traversal_on_traverses.each do |block|
27
+ block.call(view)
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+
34
+ class Visitor
35
+ # Used in test crawler
36
+ attr_reader :forms
37
+
38
+ def initialize
39
+ @forms = []
40
+ end
41
+
42
+ def traverse_multiple(views, block)
43
+ if views.is_a? Array
44
+ views.each do |view|
45
+ case view['view']
46
+ when 'panels/form-v1'
47
+ @forms << view
48
+ traverse_single view, block
49
+ @forms.pop
50
+ else
51
+ traverse_single view, block
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ def traverse_vertical_content(view, block)
58
+ traverse_multiple view['childViews'], block if view
59
+ end
60
+
61
+ def traverse_single(view, block)
62
+ block.call view
63
+
64
+ # Generic view children
65
+ traverse_multiple view['childViews'], block
66
+
67
+ # panels/split
68
+ # crawl_multiple view['leftViews'], block
69
+ # crawl_multiple view['rightViews'], block
70
+
71
+ # Split panel
72
+ traverse_vertical_content view['left'], block
73
+ traverse_vertical_content view['center'], block
74
+ traverse_vertical_content view['right'], block
75
+
76
+ # TODO: crawl header and footer
77
+ # Table/List
78
+ if (sections = view['sections']).is_a? Array
79
+ sections.each do |section|
80
+ # Table
81
+ traverse_multiple section['rows'], block
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
File without changes
@@ -12,10 +12,10 @@ module Glib
12
12
  end
13
13
 
14
14
  content, text_object = Glib::Text.get_content(new_key, default_value, options: options)
15
- content.gsub(/\{\{(\w+)\}\}/) { args.fetch($1.to_sym, "{{#{$1}}}") }
15
+ content = content.gsub(/\{\{(\w+)\}\}/) { args.fetch($1.to_sym, "{{#{$1}}}") }
16
16
 
17
17
  if text_object.images.attached?
18
- content.gsub(/\{\{image(\d)\}\}/) {
18
+ content = content.gsub(/\{\{image(\d)\}\}/) {
19
19
  if image = text_object.images[$1.to_i - 1]
20
20
  image_server_url(image.blob.key)
21
21
  else
@@ -23,6 +23,8 @@ module Glib
23
23
  end
24
24
  }
25
25
  end
26
+
27
+ content
26
28
  end
27
29
 
28
30
  def dt_json(key, default_value = '', **args)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,148 +1,148 @@
1
- # The main purpose of this is for security. If it is important to display useful error message or to provide a "banana", then
2
- # it's better to perform an explicit check (e.g. as a validation in the model or using a before_action).
3
- module Glib
4
- class ApplicationPolicy
5
- attr_reader :user, :record, :controller, :request, :params
6
-
7
- private
8
- def initialize(user, record, controller, request, params)
9
- @user = user
10
- @record = record
11
- @controller = controller
12
- @request = request
13
- # Don't get params from request because we might not have a proper request object. This might execute in Sidekiq.
14
- # See Presenter::Model::inside_mock_controller()
15
- @params = params
16
- end
17
-
18
- class << self
19
- attr_reader :catch_all
20
-
21
- # This is to define the authorization logic for an action (or a group of actions). It's different from controller's
22
- # authorize().
23
- private # Used by child
24
- def authorize(*actions, &block)
25
- actions.each do |action|
26
- if action == :manage
27
- # Serve as a catch-all to all actions that have not been specified in the policy.
28
- @catch_all = block
29
- else
30
- method_name = "#{action}?"
31
- # Avoid accidentally redefining multiple times from child policies. But it's okay if the child policy
32
- # wants to override the parent's authorization method.
33
- raise "Action authorization has been declared: #{action}" if instance_methods(false).include?(method_name.to_sym)
34
- define_method method_name, &block
35
- end
36
- end
37
- end
38
- end
39
-
40
- private
41
- def catch_all
42
- self.class.catch_all
43
- end
44
-
45
- private
46
- # To ensure the block is called on the policy's instance instead class.
47
- def call_catch_all
48
- instance_eval(&catch_all)
49
- end
50
-
51
- authorize :index do
52
- # We need this line because in `index` action, this method will be called instead of method_missing().
53
- # Having this line ensures that the catch_all behaviour works according to the priority below:
54
- # - child_policy#index?
55
- # - child_policy#manage? -- catch_all
56
- # - application_policy@index?
57
- return call_catch_all if catch_all
58
-
59
- false
60
- end
61
-
62
- authorize :show do
63
- return call_catch_all if catch_all
64
-
65
- scope.where(id: record.id).exists?
66
- end
67
-
68
- authorize :create do
69
- return call_catch_all if catch_all
70
-
71
- false
72
- end
73
-
74
- authorize :new do
75
- return call_catch_all if catch_all
76
-
77
- create?
78
- end
79
-
80
- authorize :update do
81
- return call_catch_all if catch_all
82
-
83
- false
84
- end
85
-
86
- authorize :edit do
87
- return call_catch_all if catch_all
88
-
89
- update?
90
- end
91
-
92
- authorize :destroy do
93
- return call_catch_all if catch_all
94
-
95
- false
96
- end
97
-
98
- public
99
- def method_missing(name, *args, &block)
100
- if name.to_s.end_with?('?') && catch_all
101
- call_catch_all
102
- else
103
- super
104
- end
105
- end
106
-
107
- public
108
- def scope
109
- Pundit.policy_scope!(user, record.class)
110
- end
111
-
112
- private # Used by child
113
- def public?
114
- true
115
- end
116
-
117
- # # TODO: Revise because it seems there is no justification for allowing owner to see any of the deleted entities, which include User, Guild, and Post
118
- # private # Used by child
119
- # def not_deleted_unless_owner_or_moderator?(&block)
120
- # block ||= lambda { |unused_arg| @user.moderator? }
121
- # !@record.deleted? || (@user && (@user.id == @record.user_owner_id || block.call(@record)))
122
- # end
123
-
124
- # private # Used by child
125
- # def not_deleted_unless_moderator?(&block)
126
- # block ||= lambda { |unused_arg| @user.moderator? }
127
- # !@record.deleted? || (@user && block.call(@record))
128
- # end
129
-
130
- public
131
- def self.args_builder
132
- Proc.new { |controller| [] }
133
- end
134
-
135
- class Scope
136
- attr_reader :user, :scope
137
-
138
- def initialize(user, scope)
139
- @user = user
140
- @scope = scope
141
- end
142
-
143
- def resolve
144
- scope
145
- end
146
- end
147
- end
148
- end
1
+ # The main purpose of this is for security. If it is important to display useful error message or to provide a "banana", then
2
+ # it's better to perform an explicit check (e.g. as a validation in the model or using a before_action).
3
+ module Glib
4
+ class ApplicationPolicy
5
+ attr_reader :user, :record, :controller, :request, :params
6
+
7
+ private
8
+ def initialize(user, record, controller, request, params)
9
+ @user = user
10
+ @record = record
11
+ @controller = controller
12
+ @request = request
13
+ # Don't get params from request because we might not have a proper request object. This might execute in Sidekiq.
14
+ # See Presenter::Model::inside_mock_controller()
15
+ @params = params
16
+ end
17
+
18
+ class << self
19
+ attr_reader :catch_all
20
+
21
+ # This is to define the authorization logic for an action (or a group of actions). It's different from controller's
22
+ # authorize().
23
+ private # Used by child
24
+ def authorize(*actions, &block)
25
+ actions.each do |action|
26
+ if action == :manage
27
+ # Serve as a catch-all to all actions that have not been specified in the policy.
28
+ @catch_all = block
29
+ else
30
+ method_name = "#{action}?"
31
+ # Avoid accidentally redefining multiple times from child policies. But it's okay if the child policy
32
+ # wants to override the parent's authorization method.
33
+ raise "Action authorization has been declared: #{action}" if instance_methods(false).include?(method_name.to_sym)
34
+ define_method method_name, &block
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ private
41
+ def catch_all
42
+ self.class.catch_all
43
+ end
44
+
45
+ private
46
+ # To ensure the block is called on the policy's instance instead class.
47
+ def call_catch_all
48
+ instance_eval(&catch_all)
49
+ end
50
+
51
+ authorize :index do
52
+ # We need this line because in `index` action, this method will be called instead of method_missing().
53
+ # Having this line ensures that the catch_all behaviour works according to the priority below:
54
+ # - child_policy#index?
55
+ # - child_policy#manage? -- catch_all
56
+ # - application_policy@index?
57
+ return call_catch_all if catch_all
58
+
59
+ false
60
+ end
61
+
62
+ authorize :show do
63
+ return call_catch_all if catch_all
64
+
65
+ scope.where(id: record.id).exists?
66
+ end
67
+
68
+ authorize :create do
69
+ return call_catch_all if catch_all
70
+
71
+ false
72
+ end
73
+
74
+ authorize :new do
75
+ return call_catch_all if catch_all
76
+
77
+ create?
78
+ end
79
+
80
+ authorize :update do
81
+ return call_catch_all if catch_all
82
+
83
+ false
84
+ end
85
+
86
+ authorize :edit do
87
+ return call_catch_all if catch_all
88
+
89
+ update?
90
+ end
91
+
92
+ authorize :destroy do
93
+ return call_catch_all if catch_all
94
+
95
+ false
96
+ end
97
+
98
+ public
99
+ def method_missing(name, *args, &block)
100
+ if name.to_s.end_with?('?') && catch_all
101
+ call_catch_all
102
+ else
103
+ super
104
+ end
105
+ end
106
+
107
+ public
108
+ def scope
109
+ Pundit.policy_scope!(user, record.class)
110
+ end
111
+
112
+ private # Used by child
113
+ def public?
114
+ true
115
+ end
116
+
117
+ # # TODO: Revise because it seems there is no justification for allowing owner to see any of the deleted entities, which include User, Guild, and Post
118
+ # private # Used by child
119
+ # def not_deleted_unless_owner_or_moderator?(&block)
120
+ # block ||= lambda { |unused_arg| @user.moderator? }
121
+ # !@record.deleted? || (@user && (@user.id == @record.user_owner_id || block.call(@record)))
122
+ # end
123
+
124
+ # private # Used by child
125
+ # def not_deleted_unless_moderator?(&block)
126
+ # block ||= lambda { |unused_arg| @user.moderator? }
127
+ # !@record.deleted? || (@user && block.call(@record))
128
+ # end
129
+
130
+ public
131
+ def self.args_builder
132
+ Proc.new { |controller| [] }
133
+ end
134
+
135
+ class Scope
136
+ attr_reader :user, :scope
137
+
138
+ def initialize(user, scope)
139
+ @user = user
140
+ @scope = scope
141
+ end
142
+
143
+ def resolve
144
+ scope
145
+ end
146
+ end
147
+ end
148
+ end
File without changes
File without changes
File without changes
@@ -7,6 +7,7 @@ json_ui_page json do |page|
7
7
  scroll.h3 text: dt_json('.hello', name: 'John')
8
8
  scroll.spacer height: 6
9
9
  scroll.label text: dt_json('.greeting')
10
+ scroll.label text: dt_json('.greeting_with_image')
10
11
  end
11
12
 
12
13
  end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
data/config/routes.rb CHANGED
File without changes
File without changes
File without changes
File without changes
data/lib/glib/engine.rb CHANGED
File without changes
File without changes
File without changes
File without changes
@@ -1,19 +1,18 @@
1
-
2
1
  module Glib
3
2
  module JsonCrawler
4
3
  class Router
5
- def self.log action, url, response = nil
4
+ def self.log(action, url, response = nil)
6
5
  @@logger.puts ' ' * @@depth + [
7
6
  action,
8
7
  response.present? ? response.code : nil,
9
8
  url
10
9
  ].compact.join(' :: ')
11
10
  end
12
-
11
+
13
12
  def self.set_up(logger)
14
13
  @@depth = -1
15
14
  @@logger = logger
16
- @@forms = []
15
+ @@visitor = Glib::Json::Traversal::Visitor.new
17
16
  end
18
17
 
19
18
  def self.step(http, args)
@@ -35,13 +34,14 @@ module Glib
35
34
  when 'http/post-v1'
36
35
  JsonCrawler::ActionHttp.new(:post, http, params, action)
37
36
  when 'forms/submit-v1'
38
- raise 'Submit action needs to be inside a form' if @@forms.size < 1
39
- JsonCrawler::FormsSubmit.new(http, params, action, @@forms.last)
37
+ forms = @@visitor.forms
38
+ raise 'Submit action needs to be inside a form' if forms.size < 1
39
+ JsonCrawler::FormsSubmit.new(http, params, action, forms.last)
40
40
  else
41
41
  self.log action, params['url']
42
42
  end
43
43
  @@depth -= 1
44
- return child
44
+ child
45
45
  end
46
46
  end
47
47
  end
@@ -49,51 +49,11 @@ module Glib
49
49
  def self.tear_down
50
50
  @@logger.close
51
51
  end
52
-
53
- def self.crawl_multiple views, block
54
- if views.is_a? Array
55
- views.each do |view|
56
- case view['view']
57
- when 'panels/form-v1'
58
- @@forms << view
59
- crawl_single view, block
60
- @@forms.pop
61
- else
62
- crawl_single view, block
63
- end
64
- end
65
- end
66
- end
67
52
 
68
- def self.crawl_vertical_content view, block
69
- crawl_multiple view['childViews'], block if view
70
- end
71
-
72
- def self.crawl_single view, block
73
- block.call view
74
-
75
- # Generic view children
76
- crawl_multiple view['childViews'], block
77
-
78
- # panels/split
79
- # crawl_multiple view['leftViews'], block
80
- # crawl_multiple view['rightViews'], block
81
-
82
- # Split panel
83
- crawl_vertical_content view['left'], block
84
- crawl_vertical_content view['center'], block
85
- crawl_vertical_content view['right'], block
86
-
87
- # TODO: crawl header and footer
88
- # Table/List
89
- if (sections = view['sections']).is_a? Array
90
- sections.each do |section|
91
- # Table
92
- crawl_multiple section['rows'], block
93
- end
94
- end
53
+ def self.crawl_multiple(views, block)
54
+ @@visitor.traverse_multiple views, block
95
55
  end
96
56
 
97
57
  end
98
58
  end
99
- end
59
+ end
File without changes
data/lib/glib/value.rb CHANGED
File without changes
data/lib/glib/version.rb CHANGED
File without changes
data/lib/glib-web.rb CHANGED
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glib-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
@@ -71,7 +71,9 @@ files:
71
71
  - app/controllers/concerns/glib/auth/policy.rb
72
72
  - app/controllers/concerns/glib/json/dynamic_text.rb
73
73
  - app/controllers/concerns/glib/json/libs.rb
74
+ - app/controllers/concerns/glib/json/new_dynamic_text.rb
74
75
  - app/controllers/concerns/glib/json/transformation.rb
76
+ - app/controllers/concerns/glib/json/traversal.rb
75
77
  - app/controllers/concerns/glib/json/ui.rb
76
78
  - app/controllers/concerns/glib/json/validation.rb
77
79
  - app/controllers/glib/home_controller.rb
@@ -197,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
197
199
  version: '0'
198
200
  requirements: []
199
201
  rubyforge_project:
200
- rubygems_version: 2.6.8
202
+ rubygems_version: 2.7.6
201
203
  signing_key:
202
204
  specification_version: 4
203
205
  summary: ''