glib-web 0.4.20 → 0.4.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +5 -5
  2. data/app/controllers/concerns/glib/auth/policy.rb +0 -0
  3. data/app/controllers/concerns/glib/json/new_dynamic_text.rb +0 -0
  4. data/app/controllers/concerns/glib/json/traversal.rb +0 -0
  5. data/app/controllers/concerns/glib/json/ui.rb +3 -1
  6. data/app/controllers/glib/home_controller.rb +0 -0
  7. data/app/helpers/glib/dynamic_images_helper.rb +0 -0
  8. data/app/helpers/glib/dynamic_texts_helper.rb +0 -0
  9. data/app/helpers/glib/json_ui/abstract_builder.rb +71 -68
  10. data/app/helpers/glib/json_ui/action_builder.rb +0 -0
  11. data/app/helpers/glib/json_ui/list_builders.rb +3 -2
  12. data/app/helpers/glib/json_ui/menu_builder.rb +0 -0
  13. data/app/helpers/glib/json_ui/page_helper.rb +0 -0
  14. data/app/helpers/glib/json_ui/response_helper.rb +0 -0
  15. data/app/helpers/glib/json_ui/split_builders.rb +0 -0
  16. data/app/helpers/glib/json_ui/styling_helper.rb +0 -0
  17. data/app/helpers/glib/json_ui/table_builders.rb +0 -0
  18. data/app/helpers/glib/json_ui/view_builder.rb +0 -0
  19. data/app/helpers/glib/json_ui/view_builder/banners.rb +0 -0
  20. data/app/helpers/glib/json_ui/view_builder/fields.rb +14 -0
  21. data/app/helpers/glib/json_ui/view_builder/panels.rb +8 -8
  22. data/app/models/glib/active_storage/attachment.rb +0 -0
  23. data/app/models/glib/active_storage/blob.rb +0 -0
  24. data/app/models/glib/dynamic_text_record.rb +0 -0
  25. data/app/models/glib/text.rb +0 -0
  26. data/app/policies/glib/application_policy.rb +148 -148
  27. data/app/views/app/views/json_ui/vue/renderer.html.erb +4 -0
  28. data/app/views/json_ui/garage/_nav_menu.json.jbuilder +0 -0
  29. data/app/views/json_ui/garage/actions/index.json.jbuilder +0 -0
  30. data/app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder +0 -0
  31. data/app/views/json_ui/garage/forms/basic.json.jbuilder +0 -0
  32. data/app/views/json_ui/garage/forms/basic_post.json.jbuilder +0 -0
  33. data/app/views/json_ui/garage/forms/checkboxes.json.jbuilder +0 -0
  34. data/app/views/json_ui/garage/forms/dynamic_group.json.jbuilder +33 -0
  35. data/app/views/json_ui/garage/forms/dynamic_select.json.jbuilder +0 -0
  36. data/app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder +0 -0
  37. data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +2 -1
  38. data/app/views/json_ui/garage/forms/floating_submit.json.jbuilder +0 -0
  39. data/app/views/json_ui/garage/forms/generic_post.json.jbuilder +0 -0
  40. data/app/views/json_ui/garage/forms/get_request.json.jbuilder +0 -0
  41. data/app/views/json_ui/garage/forms/index.json.jbuilder +7 -4
  42. data/app/views/json_ui/garage/forms/pickers.json.jbuilder +0 -0
  43. data/app/views/json_ui/garage/forms/rich_text.json.jbuilder +0 -0
  44. data/app/views/json_ui/garage/forms/selects.json.jbuilder +0 -0
  45. data/app/views/json_ui/garage/forms/submission_flow.json.jbuilder +0 -0
  46. data/app/views/json_ui/garage/forms/submission_flow_post.json.jbuilder +0 -0
  47. data/app/views/json_ui/garage/forms/submission_indicator.json.jbuilder +0 -0
  48. data/app/views/json_ui/garage/forms/submission_indicator_post.json.jbuilder +0 -0
  49. data/app/views/json_ui/garage/forms/text_validation.json.jbuilder +5 -1
  50. data/app/views/json_ui/garage/home/blank.json.jbuilder +0 -0
  51. data/app/views/json_ui/garage/home/index.json.jbuilder +0 -0
  52. data/app/views/json_ui/garage/lists/_infinite_scroll_section.json.jbuilder +0 -0
  53. data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +0 -0
  54. data/app/views/json_ui/garage/lists/fab.json.jbuilder +0 -0
  55. data/app/views/json_ui/garage/lists/index.json.jbuilder +0 -0
  56. data/app/views/json_ui/garage/lists/infinite_scroll.json.jbuilder +0 -0
  57. data/app/views/json_ui/garage/lists/templating.json.jbuilder +9 -1
  58. data/app/views/json_ui/garage/pages/flat_centered.json.jbuilder +6 -6
  59. data/app/views/json_ui/garage/pages/full_width.json.jbuilder +7 -7
  60. data/app/views/json_ui/garage/pages/full_width_height.json.jbuilder +0 -0
  61. data/app/views/json_ui/garage/pages/index.json.jbuilder +0 -0
  62. data/app/views/json_ui/garage/pages/layout.json.jbuilder +0 -0
  63. data/app/views/json_ui/garage/pages/nav_buttons.json.jbuilder +0 -0
  64. data/app/views/json_ui/garage/pages/tab_bar.json.jbuilder +0 -0
  65. data/app/views/json_ui/garage/panels/card.json.jbuilder +11 -34
  66. data/app/views/json_ui/garage/panels/carousel.json.jbuilder +0 -0
  67. data/app/views/json_ui/garage/panels/custom.json.jbuilder +0 -0
  68. data/app/views/json_ui/garage/panels/horizontal.json.jbuilder +0 -0
  69. data/app/views/json_ui/garage/panels/index.json.jbuilder +21 -7
  70. data/app/views/json_ui/garage/panels/responsive.json.jbuilder +0 -0
  71. data/app/views/json_ui/garage/panels/split.json.jbuilder +0 -0
  72. data/app/views/json_ui/garage/panels/vertical.json.jbuilder +0 -0
  73. data/app/views/json_ui/garage/services/dynamic_text.json.jbuilder +0 -0
  74. data/app/views/json_ui/garage/services/image.json.jbuilder +0 -0
  75. data/app/views/json_ui/garage/services/index.json.jbuilder +0 -0
  76. data/app/views/json_ui/garage/tables/_autoload_section.json.jbuilder +0 -0
  77. data/app/views/json_ui/garage/tables/autoload_all.json.jbuilder +0 -0
  78. data/app/views/json_ui/garage/tables/export_import.json.jbuilder +0 -0
  79. data/app/views/json_ui/garage/tables/horizontal_scroll.json.jbuilder +0 -0
  80. data/app/views/json_ui/garage/tables/index.json.jbuilder +0 -0
  81. data/app/views/json_ui/garage/views/banners.json.jbuilder +0 -0
  82. data/app/views/json_ui/garage/views/calendar_data.json.jbuilder +0 -0
  83. data/app/views/json_ui/garage/views/carousels.json.jbuilder +0 -0
  84. data/app/views/json_ui/garage/views/charts.json.jbuilder +0 -0
  85. data/app/views/json_ui/garage/views/images.json.jbuilder +0 -0
  86. data/app/views/json_ui/garage/views/index.json.jbuilder +0 -0
  87. data/app/views/json_ui/garage/views/links.json.jbuilder +0 -0
  88. data/app/views/json_ui/garage/views/map_data.json.jbuilder +0 -0
  89. data/app/views/json_ui/garage/views/misc.json.jbuilder +0 -0
  90. data/app/views/json_ui/garage/views/texts.json.jbuilder +0 -0
  91. data/app/views/layouts/json_ui/renderer.html.erb +32 -0
  92. data/config/routes.rb +0 -0
  93. data/lib/generators/glib/install_generator.rb +0 -0
  94. data/lib/generators/templates/20191017062519_create_texts.rb +0 -0
  95. data/lib/generators/templates/20191024063257_add_scope_to_texts.rb +0 -0
  96. data/lib/generators/templates/20191112095018_add_lang_to_texts.rb +0 -0
  97. data/lib/generators/templates/20191126071051_create_active_storage_tables.active_storage.rb +0 -0
  98. data/lib/generators/templates/database.yml +0 -0
  99. data/lib/generators/templates/dynamic_text.rb +0 -0
  100. data/lib/glib-web.rb +0 -0
  101. data/lib/glib/dynamic_text.rb +0 -0
  102. data/lib/glib/dynamic_text/config.rb +0 -0
  103. data/lib/glib/engine.rb +0 -0
  104. data/lib/glib/json_crawler.rb +0 -0
  105. data/lib/glib/json_crawler/action_crawler.rb +0 -0
  106. data/lib/glib/json_crawler/action_crawlers/action_http.rb +0 -0
  107. data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +0 -0
  108. data/lib/glib/json_crawler/action_crawlers/nav_initiate.rb +0 -0
  109. data/lib/glib/json_crawler/action_crawlers/windows_open.rb +0 -0
  110. data/lib/glib/json_crawler/http.rb +0 -0
  111. data/lib/glib/json_crawler/router.rb +0 -0
  112. data/lib/glib/value.rb +0 -0
  113. data/lib/glib/version.rb +0 -0
  114. metadata +4 -6
  115. data/app/controllers/concerns/application/json/libs.rb +0 -94
  116. data/app/controllers/concerns/application/json/transformation.rb +0 -11
  117. data/app/controllers/concerns/application/json/ui.rb +0 -66
  118. data/app/controllers/concerns/application/json/validation.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5c4c7bc6647854b613fa074f065ecfcb6b33dd50
4
- data.tar.gz: 8e74f10469c511bac536d56a3756eeac09a2db30
2
+ SHA256:
3
+ metadata.gz: aa9a08c06c8619898e10d67b5d68ee274401b277ce6da81c740d0e810a64cdb6
4
+ data.tar.gz: b71b5dbe3831eadbb862401842cdc682d0e611377f6047d8f3824348ab223eb3
5
5
  SHA512:
6
- metadata.gz: 41cb1081d27f1f961ac3c84b486443d51b6bce60661e9a56a2a3b7b9768188eb4a1dc4fe467efd6f1ed18d6d9310378aaaec3a7c56e8c7089f04572fac440b32
7
- data.tar.gz: 0635cdab21ed355d2f106ba8af3bd215e85403a6d70dc03c2b18040200e11d2b846d5f69537691874d0236177386183a3115d7bb3ba7e962461875aee5992fc1
6
+ metadata.gz: ef9bc351860c115971670b239749bee8e65e8720ef9938b15c711093d15e6d95f12260e72bb82851e359d8e82fc02cfaa6c962c215b0d332cf39053b3137202e
7
+ data.tar.gz: eb7e1725bd909c633710ea0d8bb45b74468c850231a7adb0b175822141d6b76d1cf7f747919756184429b57702637c2590ab676617fdb545f2aacb5b2764dd63
File without changes
File without changes
@@ -61,6 +61,8 @@ module Glib::Json::Ui
61
61
  def __json_ui_vue(hash, options)
62
62
  renderer_path = options[:renderer_path]
63
63
  @__json_ui_orig_page = response.body
64
- response.body = render_to_string(template: renderer_path, layout: false, content_type: 'text/html', locals: { page: hash, options: options })
64
+ response.body = render_to_string(template: renderer_path, layout: 'json_ui/renderer', content_type: 'text/html', locals: { page: hash, options: options })
65
+
66
+ # response.body = render_to_string(template: renderer_path, layout: false, content_type: 'text/html', locals: { page: hash, options: options })
65
67
  end
66
68
  end
File without changes
File without changes
File without changes
@@ -3,105 +3,108 @@ module Glib
3
3
  class AbstractBuilder
4
4
  attr_reader :json, :page
5
5
 
6
- def initialize json, page
6
+ def initialize(json, page)
7
7
  @json = json
8
8
  @page = page
9
9
  end
10
10
 
11
11
  private
12
+ def capitalize_first_letter_and_leave_others_alone(str)
13
+ str.slice(0,1).capitalize + str.slice(1..-1)
14
+ end
12
15
 
13
- def capitalize_first_letter_and_leave_others_alone(str)
14
- str.slice(0,1).capitalize + str.slice(1..-1)
15
- end
16
+ def add_singleton_element type, name, *args
17
+ name_components = name.to_s.split('_')
18
+ json.set! type, "#{name_components.join('/')}" if type
19
+ args = [yield] if block_given?
16
20
 
17
- def add_singleton_element type, name, *args
18
- name_components = name.to_s.split('_')
19
- json.set! type, "#{name_components.join('/')}" if type
20
- args = [yield] if block_given?
21
-
22
- # TODO: consider caching these instances
23
- "#{self.class.name}::#{name_components.map{ |str| capitalize_first_letter_and_leave_others_alone(str) }.join('::')}".constantize.new(json, @page).parse(*args)
24
- end
25
-
26
- def add_element_to_array type, name, *args
27
- json.child! do
28
- add_singleton_element type, name, *args
21
+ # TODO: consider caching these instances
22
+ "#{self.class.name}::#{name_components.map{ |str| capitalize_first_letter_and_leave_others_alone(str) }.join('::')}".constantize.new(json, @page).parse(*args)
29
23
  end
30
- end
31
24
 
32
- # TODO: Consider removing this in favour of non 'v1' suffix
33
- def add_singleton_element_v1 type, name, *args
34
- name_components = name.to_s.split('_')
35
- json.set! type, "#{name_components.join('/')}-v1" if type
36
- args = [yield] if block_given?
37
- "#{self.class.name}::#{name_components.map{ |str| capitalize_first_letter_and_leave_others_alone(str) }.join('::')}".constantize.new(json, @page).parse(*args)
38
- end
39
-
40
- # TODO: Consider removing this in favour of non 'v1' suffix
41
- def add_element_to_array_v1 type, name, *args
42
- json.child! do
43
- add_singleton_element_v1 type, name, *args
25
+ def add_element_to_array type, name, *args
26
+ json.child! do
27
+ add_singleton_element type, name, *args
28
+ end
44
29
  end
45
- end
46
-
30
+
31
+ # TODO: Consider removing this in favour of non 'v1' suffix
32
+ def add_singleton_element_v1 type, name, *args
33
+ name_components = name.to_s.split('_')
34
+ json.set! type, "#{name_components.join('/')}-v1" if type
35
+ args = [yield] if block_given?
36
+ "#{self.class.name}::#{name_components.map{ |str| capitalize_first_letter_and_leave_others_alone(str) }.join('::')}".constantize.new(json, @page).parse(*args)
37
+ end
38
+
39
+ # TODO: Consider removing this in favour of non 'v1' suffix
40
+ def add_element_to_array_v1 type, name, *args
41
+ json.child! do
42
+ add_singleton_element_v1 type, name, *args
43
+ end
44
+ end
45
+
47
46
  end
48
47
 
49
48
  class JsonUiElement
50
49
  attr_reader :json, :page
51
50
 
52
- def initialize json, page
51
+ def initialize(json, page)
53
52
  @json = json
54
53
  @page = page
55
54
  end
56
55
 
57
- def parse args = {}
56
+ def parse(args = {})
58
57
  @args = args
59
-
58
+
60
59
  if args.is_a? Hash
61
60
  args.each do |k, v|
62
61
  send(k, v)
63
62
  end
64
63
  end
65
-
64
+
66
65
  created
67
66
  end
68
67
 
69
68
  private
70
69
 
71
- def self.date propName
70
+ def self.date(propName)
72
71
  define_method(propName) do |value|
73
- if (value = value&.to_s)
74
- if !Rails.env.production?
75
- # TODO: Use regex to validate date
76
- end
77
-
78
- json.set! propName, value
79
- end
72
+ json.set! propName, value&.to_date
73
+
74
+ # if (value = value&.to_s)
75
+ # if !Rails.env.production?
76
+ # raise "Invalid date for #{propName}: #{value}" unless value =~ /^\d{4}-\d{2}-\d{2}$/
77
+ # end
78
+
79
+ # json.set! propName, value
80
+ # end
80
81
  end
81
82
  end
82
83
 
83
- def self.date_time propName
84
+ def self.date_time(propName)
84
85
  define_method(propName) do |value|
85
- if (value = value&.to_s)
86
- if !Rails.env.production?
87
- # TODO: Use regex to validate datetime
88
- end
89
-
90
- json.set! propName, value
91
- end
86
+ json.set! propName, value&.to_datetime
87
+
88
+ # if (value = value&.to_s)
89
+ # if !Rails.env.production?
90
+ # try Date.parse(value) rescue raise "Invalid date: #{value}"
91
+ # end
92
+
93
+ # json.set! propName, value
94
+ # end
92
95
  end
93
96
  end
94
97
 
95
98
  def self.color propName
96
- define_method(propName) do |value|
99
+ define_method(propName) do |value|
97
100
  if (value = value&.to_s)
98
101
  if !Rails.env.production?
99
102
  if !value.match /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i
100
103
  raise "Invalid color: #{value}"
101
104
  end
102
105
  end
103
-
104
- json.set! propName, value
106
+
107
+ json.set! propName, value
105
108
  end
106
109
  end
107
110
  end
@@ -119,15 +122,15 @@ module Glib
119
122
  end
120
123
  end
121
124
  end
122
-
123
- json.set! propName, value
125
+
126
+ json.set! propName, value
124
127
  end
125
128
  end
126
129
  end
127
130
 
128
131
  def self.string propName, options = {}
129
132
  define_method(propName) do |value|
130
- str = value&.to_s
133
+ str = value&.to_s
131
134
  instance_variable_set("@#{propName}", str) if options[:cache]
132
135
  json.set! propName, str
133
136
  end
@@ -162,7 +165,7 @@ module Glib
162
165
 
163
166
  def self.icon propName, options = {}
164
167
  define_method(propName) do |value|
165
-
168
+
166
169
  if value.is_a?(Hash)
167
170
  name = value[:name]
168
171
 
@@ -177,7 +180,7 @@ module Glib
177
180
  json.text badge
178
181
  end
179
182
  end
180
-
183
+
181
184
  end
182
185
  else
183
186
  name = value
@@ -185,27 +188,27 @@ module Glib
185
188
  json.set!(propName) do
186
189
  json.name name
187
190
  end
188
- end
191
+ end
189
192
 
190
193
  instance_variable_set("@#{propName}", name) if options[:cache]
191
-
194
+
192
195
  end
193
196
  end
194
-
197
+
195
198
  def self.action propName
196
- define_method(propName) do |value|
197
- json.set!(propName) { value.call(page.action_builder) }
199
+ define_method(propName) do |value|
200
+ json.set!(propName) { value.call(page.action_builder) }
198
201
  end
199
202
  end
200
203
 
201
204
  def self.views propName
202
- define_method(propName) do |value|
203
- json.set!(propName) { value.call(page.view_builder) }
205
+ define_method(propName) do |value|
206
+ json.set!(propName) { value.call(page.view_builder) }
204
207
  end
205
208
  end
206
209
 
207
210
  def self.array propName
208
- define_method(propName) do |value|
211
+ define_method(propName) do |value|
209
212
  json.set! propName, value&.to_a
210
213
  end
211
214
  end
@@ -218,7 +221,7 @@ module Glib
218
221
 
219
222
  def self.singleton_array singletonName, arrayName
220
223
  array arrayName
221
-
224
+
222
225
  define_method(singletonName) do |value|
223
226
  json.set! arrayName, [value]
224
227
  end
File without changes
@@ -2,7 +2,7 @@ module Glib
2
2
  module JsonUi
3
3
  module ListBuilders
4
4
  class Template < AbstractBuilder
5
- def method_missing m, *args
5
+ def method_missing(m, *args)
6
6
  add_element_to_array 'template', m, *args
7
7
  end
8
8
 
@@ -23,6 +23,7 @@ module Glib
23
23
  string :subsubtitle
24
24
  string :imageUrl
25
25
  action :onClick
26
+ views :accessoryViews
26
27
  end
27
28
 
28
29
  class Featured < Thumbnail
@@ -30,7 +31,7 @@ module Glib
30
31
  end
31
32
 
32
33
  class Section < AbstractBuilder
33
- def initialize json, page, template
34
+ def initialize(json, page, template)
34
35
  super json, page
35
36
  @template = template
36
37
  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
@@ -137,6 +137,11 @@ class Glib::JsonUi::ViewBuilder
137
137
  end
138
138
  end
139
139
 
140
+ class DynamicGroup < AbstractField
141
+ string :groupTitlePrefix
142
+ views :groupTemplateViews
143
+ end
144
+
140
145
  class RadioGroup < View
141
146
  string :name
142
147
  string :value
@@ -163,6 +168,11 @@ class Glib::JsonUi::ViewBuilder
163
168
  class Date < AbstractField
164
169
  date :min
165
170
  date :max
171
+
172
+ # Override
173
+ def value(value)
174
+ super(value&.to_date)
175
+ end
166
176
  end
167
177
 
168
178
  # This doesn't use camel case to be consistent with the html input equivalent
@@ -176,5 +186,9 @@ class Glib::JsonUi::ViewBuilder
176
186
  hash :longitudeField
177
187
  end
178
188
 
189
+ class StripeToken < AbstractField
190
+ string :publicKey
191
+ end
192
+
179
193
  end
180
194
  end
@@ -31,7 +31,7 @@ class Glib::JsonUi::ViewBuilder
31
31
  def hint_label(prop, args)
32
32
  I18n.t("dt_models.#{@model_name}.#{prop}.hint", args.merge(default: nil))
33
33
  end
34
-
34
+
35
35
  def placeholder_label(prop, args)
36
36
  I18n.t("dt_models.#{@model_name}.#{prop}.placeholder", args.merge(default: nil))
37
37
  end
@@ -69,7 +69,7 @@ class Glib::JsonUi::ViewBuilder
69
69
 
70
70
  json.url @url
71
71
  json.method @method
72
-
72
+
73
73
  json.childViews do
74
74
  if @method != :get
75
75
  json.child! do
@@ -100,7 +100,7 @@ class Glib::JsonUi::ViewBuilder
100
100
  block.call page.list_section_builder
101
101
  end
102
102
  end
103
-
103
+
104
104
  def sections(blocks)
105
105
  json.sections do
106
106
  blocks.each do |block|
@@ -116,7 +116,7 @@ class Glib::JsonUi::ViewBuilder
116
116
  hash :nextPage
117
117
  hash :export
118
118
  hash :import
119
-
119
+
120
120
  def firstSection(block)
121
121
  json.sections [1] do
122
122
  block.call page.table_section_builder
@@ -181,10 +181,10 @@ class Glib::JsonUi::ViewBuilder
181
181
  string :distribution
182
182
  end
183
183
 
184
- # TODO: Deprecate in favour of styleClasses
185
- class Card < View
186
- views :childViews
187
- end
184
+ # # TODO: Deprecate in favour of styleClasses
185
+ # class Card < View
186
+ # views :childViews
187
+ # end
188
188
 
189
189
  class Custom < View
190
190
  string :template
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