glib-web 0.4.20 → 0.4.21

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 (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