glib-web 0.4.16 → 0.4.17
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.
- checksums.yaml +5 -5
- data/app/controllers/concerns/application/json/libs.rb +0 -0
- data/app/controllers/concerns/application/json/transformation.rb +0 -0
- data/app/controllers/concerns/application/json/ui.rb +0 -0
- data/app/controllers/concerns/application/json/validation.rb +0 -0
- data/app/controllers/concerns/glib/auth/policy.rb +0 -0
- data/app/controllers/concerns/glib/json/new_dynamic_text.rb +1 -1
- data/app/controllers/concerns/glib/json/traversal.rb +0 -0
- data/app/controllers/glib/home_controller.rb +0 -0
- data/app/helpers/glib/dynamic_images_helper.rb +64 -0
- data/app/helpers/glib/dynamic_texts_helper.rb +36 -36
- data/app/helpers/glib/json_ui/abstract_builder.rb +0 -0
- data/app/helpers/glib/json_ui/action_builder.rb +1 -0
- data/app/helpers/glib/json_ui/list_builders.rb +0 -0
- data/app/helpers/glib/json_ui/menu_builder.rb +0 -0
- data/app/helpers/glib/json_ui/page_helper.rb +0 -0
- data/app/helpers/glib/json_ui/response_helper.rb +0 -0
- data/app/helpers/glib/json_ui/split_builders.rb +0 -0
- data/app/helpers/glib/json_ui/styling_helper.rb +4 -0
- data/app/helpers/glib/json_ui/table_builders.rb +0 -0
- data/app/helpers/glib/json_ui/view_builder.rb +1 -0
- data/app/helpers/glib/json_ui/view_builder/banners.rb +0 -0
- data/app/helpers/glib/json_ui/view_builder/fields.rb +9 -7
- data/app/helpers/glib/json_ui/view_builder/panels.rb +0 -0
- data/app/models/glib/active_storage/attachment.rb +0 -0
- data/app/models/glib/active_storage/blob.rb +0 -0
- data/app/models/glib/dynamic_text_record.rb +0 -0
- data/app/models/glib/text.rb +0 -0
- data/app/policies/glib/application_policy.rb +148 -148
- data/app/views/app/views/json_ui/vue/renderer.html.erb +0 -0
- data/app/views/json_ui/garage/_nav_menu.json.jbuilder +14 -14
- data/app/views/json_ui/garage/actions/index.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/basic.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/basic_post.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/checkboxes.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/dynamic_select.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/floating_submit.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/generic_post.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/get_request.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/index.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/pickers.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/rich_text.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/selects.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/submission_flow.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/submission_flow_post.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/submission_indicator.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/submission_indicator_post.json.jbuilder +0 -0
- data/app/views/json_ui/garage/forms/text_validation.json.jbuilder +0 -0
- data/app/views/json_ui/garage/home/blank.json.jbuilder +0 -0
- data/app/views/json_ui/garage/home/index.json.jbuilder +0 -0
- data/app/views/json_ui/garage/lists/_infinite_scroll_section.json.jbuilder +0 -0
- data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +0 -0
- data/app/views/json_ui/garage/lists/fab.json.jbuilder +0 -0
- data/app/views/json_ui/garage/lists/index.json.jbuilder +0 -0
- data/app/views/json_ui/garage/lists/infinite_scroll.json.jbuilder +0 -0
- data/app/views/json_ui/garage/lists/templating.json.jbuilder +0 -0
- data/app/views/json_ui/garage/pages/flat_centered.json.jbuilder +0 -0
- data/app/views/json_ui/garage/pages/full_width.json.jbuilder +0 -0
- data/app/views/json_ui/garage/pages/full_width_height.json.jbuilder +0 -0
- data/app/views/json_ui/garage/pages/index.json.jbuilder +0 -0
- data/app/views/json_ui/garage/pages/layout.json.jbuilder +0 -0
- data/app/views/json_ui/garage/pages/nav_buttons.json.jbuilder +0 -0
- data/app/views/json_ui/garage/pages/tab_bar.json.jbuilder +0 -0
- data/app/views/json_ui/garage/panels/card.json.jbuilder +0 -0
- data/app/views/json_ui/garage/panels/carousel.json.jbuilder +0 -0
- data/app/views/json_ui/garage/panels/custom.json.jbuilder +0 -0
- data/app/views/json_ui/garage/panels/horizontal.json.jbuilder +0 -0
- data/app/views/json_ui/garage/panels/index.json.jbuilder +0 -0
- data/app/views/json_ui/garage/panels/responsive.json.jbuilder +0 -0
- data/app/views/json_ui/garage/panels/split.json.jbuilder +0 -0
- data/app/views/json_ui/garage/panels/vertical.json.jbuilder +0 -0
- data/app/views/json_ui/garage/{dynamic_texts/basic.json.jbuilder → services/dynamic_text.json.jbuilder} +0 -0
- data/app/views/json_ui/garage/services/image.json.jbuilder +25 -0
- data/app/views/json_ui/garage/services/index.json.jbuilder +18 -0
- data/app/views/json_ui/garage/tables/_autoload_section.json.jbuilder +0 -0
- data/app/views/json_ui/garage/tables/autoload_all.json.jbuilder +0 -0
- data/app/views/json_ui/garage/tables/export_import.json.jbuilder +0 -0
- data/app/views/json_ui/garage/tables/horizontal_scroll.json.jbuilder +0 -0
- data/app/views/json_ui/garage/tables/index.json.jbuilder +0 -0
- data/app/views/json_ui/garage/views/banners.json.jbuilder +0 -0
- data/app/views/json_ui/garage/views/calendar_data.json.jbuilder +0 -0
- data/app/views/json_ui/garage/views/carousels.json.jbuilder +0 -0
- data/app/views/json_ui/garage/views/charts.json.jbuilder +0 -0
- data/app/views/json_ui/garage/views/images.json.jbuilder +0 -0
- data/app/views/json_ui/garage/views/index.json.jbuilder +0 -0
- data/app/views/json_ui/garage/views/links.json.jbuilder +0 -0
- data/app/views/json_ui/garage/views/map_data.json.jbuilder +0 -0
- data/app/views/json_ui/garage/views/misc.json.jbuilder +0 -0
- data/app/views/json_ui/garage/views/texts.json.jbuilder +0 -0
- data/config/routes.rb +0 -0
- data/lib/generators/glib/install_generator.rb +0 -0
- data/lib/generators/templates/20191017062519_create_texts.rb +0 -0
- data/lib/generators/templates/20191024063257_add_scope_to_texts.rb +0 -0
- data/lib/generators/templates/20191112095018_add_lang_to_texts.rb +0 -0
- data/lib/generators/templates/20191126071051_create_active_storage_tables.active_storage.rb +0 -0
- data/lib/generators/templates/database.yml +0 -0
- data/lib/generators/templates/dynamic_text.rb +0 -0
- data/lib/glib-web.rb +0 -0
- data/lib/glib/dynamic_text.rb +0 -0
- data/lib/glib/dynamic_text/config.rb +0 -0
- data/lib/glib/engine.rb +0 -0
- data/lib/glib/json_crawler.rb +0 -0
- data/lib/glib/json_crawler/action_crawler.rb +0 -0
- data/lib/glib/json_crawler/action_crawlers/action_http.rb +0 -0
- data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +0 -0
- data/lib/glib/json_crawler/action_crawlers/nav_initiate.rb +0 -0
- data/lib/glib/json_crawler/action_crawlers/windows_open.rb +0 -0
- data/lib/glib/json_crawler/http.rb +0 -0
- data/lib/glib/json_crawler/router.rb +0 -0
- data/lib/glib/value.rb +0 -0
- data/lib/glib/version.rb +0 -0
- metadata +6 -4
- data/app/views/json_ui/garage/dynamic_texts/index.json.jbuilder +0 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: '025681707e771829fc38ade19531b445614fea32'
|
|
4
|
+
data.tar.gz: d5e74fcf7a3de0baa2f2c7235ac42eb2fe6e5921
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 11c6a435ea67d48b288843d7013a10fc8b8a00fde30f5c739ced1d4b7896f69ce0e17020fdbd8ff756675e33ecb961aacd61ed0ead0bd54fef9f2d6741ca0d95
|
|
7
|
+
data.tar.gz: 2d275ae65c9d6e0bdee4bf2cd5eb940115d5cc82d09de72d2cd2fca217f62ba7507494c00354decaa688e9d376c5fd61a5cb1fb12694a1bb4ebdb9e5184d9551
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -112,7 +112,7 @@ module Glib::Json::NewDynamicText
|
|
|
112
112
|
def substitute_image_with(images)
|
|
113
113
|
view[prop] = view[prop].gsub(/\{\{image(\d)\}\}/) {
|
|
114
114
|
if image = images[$1.to_i - 1]
|
|
115
|
-
ApplicationController.helpers.
|
|
115
|
+
ApplicationController.helpers.dynamic_image_url(image.blob.key)
|
|
116
116
|
else
|
|
117
117
|
"{{image#{$1}}}"
|
|
118
118
|
end
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Glib
|
|
2
|
+
module DynamicImagesHelper
|
|
3
|
+
# # TODO: The bucket should probably be set as a parameter for json_libs
|
|
4
|
+
# def dynamic_image_url(blob_key, w: 100, h: 100, fit: 'clip', bucket: Rails.application.config.try(:aws_s3_bucket))
|
|
5
|
+
# return unless blob_key.present?
|
|
6
|
+
|
|
7
|
+
# uri = URI::HTTPS.build(
|
|
8
|
+
# host: 'imageserver-demo.herokuapp.com',
|
|
9
|
+
# path: "/image/#{bucket}/#{blob_key}",
|
|
10
|
+
# query: { w: w, h: h, fit: fit }.to_param
|
|
11
|
+
# )
|
|
12
|
+
|
|
13
|
+
# uri.to_s
|
|
14
|
+
# end
|
|
15
|
+
|
|
16
|
+
def dynamic_image_url(blob_key, w: 100, h: 100, fit: 'clip', bucket: Rails.application.config.try(:aws_s3_bucket))
|
|
17
|
+
return unless blob_key.present?
|
|
18
|
+
|
|
19
|
+
full_params_hash = {
|
|
20
|
+
bucket_name: bucket,
|
|
21
|
+
blob_key: blob_key,
|
|
22
|
+
w: w,
|
|
23
|
+
h: h,
|
|
24
|
+
fit: fit,
|
|
25
|
+
expires: 1.hours.from_now.to_i
|
|
26
|
+
}
|
|
27
|
+
request_params_hash = full_params_hash.except(:bucket_name, :blob_key)
|
|
28
|
+
|
|
29
|
+
if (private_key = ENV['PRIVATE_API_KEY'])
|
|
30
|
+
encryption_service = EncryptionService.new(bucket, private_key)
|
|
31
|
+
signature = encryption_service.encrypt(full_params_hash)
|
|
32
|
+
request_params_hash = request_params_hash.merge(signature: signature)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# TODO: This should probably be set as a parameter for json_libs
|
|
36
|
+
uri = URI::HTTPS.build(
|
|
37
|
+
host: 'imageserver-demo.herokuapp.com',
|
|
38
|
+
path: "/image/#{bucket}/#{blob_key}",
|
|
39
|
+
query: request_params_hash.to_param
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
uri.to_s
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
EncryptionService = Struct.new(:salt, :private_key) do
|
|
46
|
+
def encrypt(value)
|
|
47
|
+
encryptor.encrypt_and_sign(value)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def decrypt(value)
|
|
51
|
+
encryptor.decrypt_and_verify(value)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
def encryptor
|
|
56
|
+
@encryptor ||= begin
|
|
57
|
+
key_len = ActiveSupport::MessageEncryptor.key_len
|
|
58
|
+
key = ActiveSupport::KeyGenerator.new(private_key).generate_key(salt, key_len)
|
|
59
|
+
ActiveSupport::MessageEncryptor.new(key)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -17,7 +17,7 @@ module Glib
|
|
|
17
17
|
if text_object.images.attached?
|
|
18
18
|
content = content.gsub(/\{\{image(\d)\}\}/) {
|
|
19
19
|
if image = text_object.images[$1.to_i - 1]
|
|
20
|
-
|
|
20
|
+
dynamic_image_url(image.blob.key)
|
|
21
21
|
else
|
|
22
22
|
"{{image#{$1}}}"
|
|
23
23
|
end
|
|
@@ -39,46 +39,46 @@ module Glib
|
|
|
39
39
|
}.merge(args)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
def dt_image_server_url(blob_key, w: 100, h: 100)
|
|
43
|
-
|
|
42
|
+
# def dt_image_server_url(blob_key, w: 100, h: 100)
|
|
43
|
+
# return unless blob_key.present?
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
# encryption_service = EncryptionService.new(ENV['AWS_S3_BUCKET'], ENV['PRIVATE_API_KEY'])
|
|
46
|
+
# params_hash = {
|
|
47
|
+
# bucket_name: ENV['AWS_S3_BUCKET'],
|
|
48
|
+
# blob_key: blob_key,
|
|
49
|
+
# w: w,
|
|
50
|
+
# h: h,
|
|
51
|
+
# expires: 1.hours.from_now.to_i
|
|
52
|
+
# }
|
|
53
|
+
# signature = encryption_service.encrypt(params_hash)
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
# # TODO: This should probably be set as a parameter for json_libs
|
|
56
|
+
# uri = URI::HTTPS.build(
|
|
57
|
+
# host: 'imageserver-demo.herokuapp.com',
|
|
58
|
+
# path: "/image/#{ENV['AWS_S3_BUCKET']}/#{blob_key}",
|
|
59
|
+
# query: params_hash.except(:bucket_name, :blob_key).merge(signature: signature).to_param
|
|
60
|
+
# )
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
end
|
|
62
|
+
# uri.to_s
|
|
63
|
+
# end
|
|
64
64
|
|
|
65
|
-
EncryptionService = Struct.new(:salt, :private_key) do
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
# EncryptionService = Struct.new(:salt, :private_key) do
|
|
66
|
+
# def encrypt(value)
|
|
67
|
+
# encryptor.encrypt_and_sign(value)
|
|
68
|
+
# end
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
# def decrypt(value)
|
|
71
|
+
# encryptor.decrypt_and_verify(value)
|
|
72
|
+
# end
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
end
|
|
74
|
+
# private
|
|
75
|
+
# def encryptor
|
|
76
|
+
# encryptor ||= begin
|
|
77
|
+
# key_len = ActiveSupport::MessageEncryptor.key_len
|
|
78
|
+
# key = ActiveSupport::KeyGenerator.new(private_key).generate_key(salt, key_len)
|
|
79
|
+
# ActiveSupport::MessageEncryptor.new(key)
|
|
80
|
+
# end
|
|
81
|
+
# end
|
|
82
|
+
# end
|
|
83
83
|
end
|
|
84
84
|
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
|
|
@@ -44,7 +44,7 @@ class Glib::JsonUi::ViewBuilder
|
|
|
44
44
|
|
|
45
45
|
# Override
|
|
46
46
|
def created
|
|
47
|
-
if
|
|
47
|
+
if @prop && (form = page.current_form)
|
|
48
48
|
@name ||= form.field_name(@prop, @multiple || false)
|
|
49
49
|
@value ||= form.field_value(@prop)
|
|
50
50
|
@label ||= form.field_label(@prop, @label_args || {})
|
|
@@ -85,7 +85,7 @@ class Glib::JsonUi::ViewBuilder
|
|
|
85
85
|
|
|
86
86
|
class Hidden < Text
|
|
87
87
|
end
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
# Benefits of using `fields/submit` over `button`
|
|
90
90
|
# - On the web, it translates to input[type=submit] which provides builtin functionality such as
|
|
91
91
|
# submitting upon pressing enter on a field and remembering values for autofill.
|
|
@@ -105,7 +105,7 @@ class Glib::JsonUi::ViewBuilder
|
|
|
105
105
|
bool :checked
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
-
# This doesn't use camel case because some terms have become single words (e.g. snackbar)
|
|
108
|
+
# This doesn't use camel case because some terms have become single words (e.g. snackbar)
|
|
109
109
|
class Textarea < Text
|
|
110
110
|
bool :readOnly
|
|
111
111
|
end
|
|
@@ -123,16 +123,17 @@ class Glib::JsonUi::ViewBuilder
|
|
|
123
123
|
bool :readOnly
|
|
124
124
|
bool :multiple, cache: true
|
|
125
125
|
bool :manualEntry
|
|
126
|
+
hash :append
|
|
126
127
|
end
|
|
127
128
|
|
|
128
129
|
class DynamicSelect < AbstractField
|
|
129
130
|
array :selectedOptions
|
|
130
131
|
string :url
|
|
131
132
|
bool :multiple, cache: true
|
|
132
|
-
|
|
133
|
+
|
|
133
134
|
# Override
|
|
134
135
|
def value(value)
|
|
135
|
-
raise
|
|
136
|
+
raise 'Use selectedOptions instead (for clarity)'
|
|
136
137
|
end
|
|
137
138
|
end
|
|
138
139
|
|
|
@@ -140,7 +141,7 @@ class Glib::JsonUi::ViewBuilder
|
|
|
140
141
|
string :name
|
|
141
142
|
string :value
|
|
142
143
|
views :childViews
|
|
143
|
-
|
|
144
|
+
|
|
144
145
|
string :iconOfBeforeSelected
|
|
145
146
|
string :iconOfSelected
|
|
146
147
|
string :iconOfAfterSelected
|
|
@@ -156,6 +157,7 @@ class Glib::JsonUi::ViewBuilder
|
|
|
156
157
|
string :directUploadUrl
|
|
157
158
|
string :fileUrl
|
|
158
159
|
string :fileTitle
|
|
160
|
+
hash :placeholderView
|
|
159
161
|
end
|
|
160
162
|
|
|
161
163
|
class Date < AbstractField
|
|
@@ -168,7 +170,7 @@ class Glib::JsonUi::ViewBuilder
|
|
|
168
170
|
date_time :min
|
|
169
171
|
date_time :max
|
|
170
172
|
end
|
|
171
|
-
|
|
173
|
+
|
|
172
174
|
class LatLong < AbstractField
|
|
173
175
|
hash :latitudeField
|
|
174
176
|
hash :longitudeField
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/app/models/glib/text.rb
CHANGED
|
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
|
|
@@ -7,29 +7,29 @@ if local_assigns[:top_nav] || json_ui_app_is_web?
|
|
|
7
7
|
action.windows_open url: root_url
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
drawer.rows builder: ->(menu) do
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
menu.button text: 'Pages', onClick: ->(action) do
|
|
14
14
|
action.windows_open url: json_ui_garage_url(path: 'pages/index')
|
|
15
15
|
end
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
menu.button text: 'Panels', onClick: ->(action) do
|
|
18
18
|
action.windows_open url: json_ui_garage_url(path: 'panels/index')
|
|
19
19
|
end
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
menu.button text: 'Lists', onClick: ->(action) do
|
|
22
22
|
action.windows_open url: json_ui_garage_url(path: 'lists/index')
|
|
23
23
|
end
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
menu.button text: 'Forms', onClick: ->(action) do
|
|
26
26
|
action.windows_open url: json_ui_garage_url(path: 'forms/index')
|
|
27
27
|
end
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
menu.button text: 'Views', onClick: ->(action) do
|
|
30
30
|
action.windows_open url: json_ui_garage_url(path: 'views/index')
|
|
31
31
|
end
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
menu.button text: 'Actions', onClick: ->(action) do
|
|
34
34
|
action.windows_open url: json_ui_garage_url(path: 'actions/index')
|
|
35
35
|
end
|
|
@@ -38,21 +38,21 @@ if local_assigns[:top_nav] || json_ui_app_is_web?
|
|
|
38
38
|
action.windows_open url: json_ui_garage_url(path: 'tables/index')
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
menu.button text: '
|
|
42
|
-
action.windows_open url: json_ui_garage_url(path: '
|
|
41
|
+
menu.button text: 'Services', onClick: ->(action) do
|
|
42
|
+
action.windows_open url: json_ui_garage_url(path: 'services/index')
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
menu.divider
|
|
46
46
|
menu.label text: 'Misc Menu'
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
menu.button icon: 'notifications', text: 'Notifications', onClick: ->(action) do
|
|
49
49
|
action.windows_open url: json_ui_garage_url(path: 'notifications/index')
|
|
50
50
|
end
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
menu.button icon: 'list', text: 'UI Elements', onClick: ->(action) do
|
|
53
53
|
action.windows_open url: json_ui_garage_url
|
|
54
54
|
end
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
menu.button icon: { name: 'zoom_in', badge: '!' }, text: 'Diagnostics', onClick: ->(action) do
|
|
57
57
|
action.dialogs_alert message: %{
|
|
58
58
|
Bundle ID: #{json_ui_app_bundle_id || '<unknown>'}
|
|
@@ -60,8 +60,8 @@ if local_assigns[:top_nav] || json_ui_app_is_web?
|
|
|
60
60
|
Device OS: #{json_ui_app_device_os}
|
|
61
61
|
}
|
|
62
62
|
end
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
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
|
|
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
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
json.title 'Dynamic Texts'
|
|
2
|
+
|
|
3
|
+
json_ui_page json do |page|
|
|
4
|
+
render "#{@path_prefix}/nav_menu", json: json, page: page
|
|
5
|
+
|
|
6
|
+
page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
7
|
+
bucket = 'itinerarybuilder-demo'
|
|
8
|
+
|
|
9
|
+
# NOTE: The current implementation does not follow the exact behaviour described in https://docs.imgix.com/apis/url/size/fit#clip
|
|
10
|
+
scroll.h1 text: 'fit: clip (default)'
|
|
11
|
+
scroll.spacer height: 6
|
|
12
|
+
scroll.image url: dynamic_image_url(glib_json_image_blob_key, bucket: bucket)
|
|
13
|
+
|
|
14
|
+
scroll.spacer height: 20
|
|
15
|
+
scroll.h1 text: 'fit: crop'
|
|
16
|
+
scroll.spacer height: 6
|
|
17
|
+
scroll.image url: dynamic_image_url(glib_json_image_blob_key, bucket: bucket, fit: 'crop')
|
|
18
|
+
|
|
19
|
+
scroll.spacer height: 20
|
|
20
|
+
scroll.h1 text: 'fit: fill'
|
|
21
|
+
scroll.spacer height: 6
|
|
22
|
+
scroll.image url: dynamic_image_url(glib_json_image_blob_key, bucket: bucket, fit: 'fill')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
json.title 'Dynamic Texts'
|
|
2
|
+
|
|
3
|
+
json_ui_page json do |page|
|
|
4
|
+
render "#{@path_prefix}/nav_menu", json: json, page: page, top_nav: true
|
|
5
|
+
|
|
6
|
+
page.list firstSection: ->(section) do
|
|
7
|
+
section.rows builder: ->(template) do
|
|
8
|
+
template.thumbnail title: 'Dynamic Text', onClick: ->(action) do
|
|
9
|
+
action.windows_open url: json_ui_garage_url(path: 'services/dynamic_text')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
template.thumbnail title: 'Image', onClick: ->(action) do
|
|
13
|
+
action.windows_open url: json_ui_garage_url(path: 'services/image')
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
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
|
data/config/routes.rb
CHANGED
|
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/lib/glib-web.rb
CHANGED
|
File without changes
|
data/lib/glib/dynamic_text.rb
CHANGED
|
File without changes
|
|
File without changes
|
data/lib/glib/engine.rb
CHANGED
|
File without changes
|
data/lib/glib/json_crawler.rb
CHANGED
|
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/lib/glib/value.rb
CHANGED
|
File without changes
|
data/lib/glib/version.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.
|
|
4
|
+
version: 0.4.17
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ''
|
|
@@ -77,6 +77,7 @@ files:
|
|
|
77
77
|
- app/controllers/concerns/glib/json/ui.rb
|
|
78
78
|
- app/controllers/concerns/glib/json/validation.rb
|
|
79
79
|
- app/controllers/glib/home_controller.rb
|
|
80
|
+
- app/helpers/glib/dynamic_images_helper.rb
|
|
80
81
|
- app/helpers/glib/dynamic_texts_helper.rb
|
|
81
82
|
- app/helpers/glib/json_ui/abstract_builder.rb
|
|
82
83
|
- app/helpers/glib/json_ui/action_builder.rb
|
|
@@ -100,8 +101,6 @@ files:
|
|
|
100
101
|
- app/views/app/views/json_ui/vue/renderer.html.erb
|
|
101
102
|
- app/views/json_ui/garage/_nav_menu.json.jbuilder
|
|
102
103
|
- app/views/json_ui/garage/actions/index.json.jbuilder
|
|
103
|
-
- app/views/json_ui/garage/dynamic_texts/basic.json.jbuilder
|
|
104
|
-
- app/views/json_ui/garage/dynamic_texts/index.json.jbuilder
|
|
105
104
|
- app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder
|
|
106
105
|
- app/views/json_ui/garage/forms/basic.json.jbuilder
|
|
107
106
|
- app/views/json_ui/garage/forms/basic_post.json.jbuilder
|
|
@@ -145,6 +144,9 @@ files:
|
|
|
145
144
|
- app/views/json_ui/garage/panels/responsive.json.jbuilder
|
|
146
145
|
- app/views/json_ui/garage/panels/split.json.jbuilder
|
|
147
146
|
- app/views/json_ui/garage/panels/vertical.json.jbuilder
|
|
147
|
+
- app/views/json_ui/garage/services/dynamic_text.json.jbuilder
|
|
148
|
+
- app/views/json_ui/garage/services/image.json.jbuilder
|
|
149
|
+
- app/views/json_ui/garage/services/index.json.jbuilder
|
|
148
150
|
- app/views/json_ui/garage/tables/_autoload_section.json.jbuilder
|
|
149
151
|
- app/views/json_ui/garage/tables/autoload_all.json.jbuilder
|
|
150
152
|
- app/views/json_ui/garage/tables/export_import.json.jbuilder
|
|
@@ -203,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
203
205
|
version: '0'
|
|
204
206
|
requirements: []
|
|
205
207
|
rubyforge_project:
|
|
206
|
-
rubygems_version: 2.
|
|
208
|
+
rubygems_version: 2.6.8
|
|
207
209
|
signing_key:
|
|
208
210
|
specification_version: 4
|
|
209
211
|
summary: ''
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
json.title 'Dynamic Texts'
|
|
2
|
-
|
|
3
|
-
json_ui_page json do |page|
|
|
4
|
-
render "#{@path_prefix}/nav_menu", json: json, page: page, top_nav: true
|
|
5
|
-
|
|
6
|
-
page.list firstSection: ->(section) do
|
|
7
|
-
section.rows builder: ->(template) do
|
|
8
|
-
template.thumbnail title: 'Basic', onClick: ->(action) do
|
|
9
|
-
action.windows_open url: json_ui_garage_url(path: 'dynamic_texts/basic')
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
end
|
|
14
|
-
end
|