glib-web 0.4.16 → 0.4.17
Sign up to get free protection for your applications and to get access to all the features.
- 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
|