glib-web 0.4.2 → 0.4.3
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 +4 -4
- data/app/controllers/concerns/glib/auth/policy.rb +98 -0
- data/app/controllers/concerns/glib/json/dynamic_text.rb +10 -6
- data/app/helpers/glib/json_ui/action_builder.rb +1 -0
- data/app/policies/glib/application_policy.rb +148 -0
- data/app/views/json_ui/garage/notifications/index.json.jbuilder +3 -1
- data/app/views/json_ui/garage/panels/responsive.json.jbuilder +22 -10
- metadata +31 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38b5751f1b2684f0d68bacb791098fc4aab5ab6b42cb25f1891a1f27bbdbbc8f
|
4
|
+
data.tar.gz: eed1f00a5ccd846f36d7291620f45f8702a63f80ffe8b94364243a5f1ce3cb55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a464dbf43a08c5f9b131c5e18b48bda98d40ef29e0298827b78e901f667df0901f227be11809feb39be6d55aa1b9b09133cfa119d06829f5dd663a569ef2e6eb
|
7
|
+
data.tar.gz: ca3b4567e5344a9d057c66d772aded64ba86b810d650837b1581eb40a3a981eed7e646c58e5915964f3a612088b0451a8cd490542e51d288bd5e4f30ba5d28a3
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Glib::Auth
|
2
|
+
module Policy
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
include Pundit
|
7
|
+
include Overrides
|
8
|
+
extend ClassMethods
|
9
|
+
|
10
|
+
# TODO: Ultimately we want to uncomment this line, but:
|
11
|
+
# - Need to be able to set aside some time to run rspec tests to ensure nothing gets broken
|
12
|
+
# - Need to find a solution where we can reuse a single public policy
|
13
|
+
# after_action :verify_authorized
|
14
|
+
|
15
|
+
helper_method :policy, :can?, :cannot?
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
module Overrides
|
20
|
+
public # Override
|
21
|
+
def policy(record)
|
22
|
+
return @__pundit_policy if defined? @__pundit_policy
|
23
|
+
|
24
|
+
if record.is_a?(Symbol) && record.to_s.ends_with?('_admin')
|
25
|
+
policy_class = CommonAdminPolicy
|
26
|
+
else
|
27
|
+
policy_class = Pundit::PolicyFinder.new(record).policy
|
28
|
+
end
|
29
|
+
raise "Policy not found for #{record.class}" unless policy_class
|
30
|
+
@__pundit_policy = policy_class.new(current_user, record, self, request, params, *policy_class.args_builder.call(self))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
public
|
35
|
+
def raise_access_denied(record)
|
36
|
+
# raise Pundit::NotAuthorizedError.new(record: record, policy: policy(record), query: "#{action_name}?")
|
37
|
+
raise UnauthorizedError.new(record: record, policy: policy(record), query: "#{action_name}?")
|
38
|
+
end
|
39
|
+
|
40
|
+
public
|
41
|
+
def can?(action, record)
|
42
|
+
policy(record).send("#{action}?")
|
43
|
+
end
|
44
|
+
|
45
|
+
public
|
46
|
+
def cannot?(action, record)
|
47
|
+
!policy(record).send("#{action}?")
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
class UnauthorizedError < Pundit::NotAuthorizedError
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
module ClassMethods
|
58
|
+
# Inspired from https://github.com/ryanb/cancan/wiki/Non-RESTful-Controllers
|
59
|
+
public
|
60
|
+
def authorize_resource(*args)
|
61
|
+
options = args.extract_options!
|
62
|
+
resource_name = args.first
|
63
|
+
|
64
|
+
self.before_action(options.slice(:only, :except, :if, :unless)) do |controller|
|
65
|
+
resource_name ||= resource_name_from_controller
|
66
|
+
|
67
|
+
if !(resource_key = options[:class]).nil?
|
68
|
+
resource = case resource_key
|
69
|
+
when false
|
70
|
+
resource_name.to_sym
|
71
|
+
when Symbol, Class
|
72
|
+
resource_key
|
73
|
+
else
|
74
|
+
raise "Invalid resource class: #{resource_key}"
|
75
|
+
end
|
76
|
+
|
77
|
+
authorize resource
|
78
|
+
# if (policy = policy(resource)) && policy.class.instance_variable_defined?(:@manage_permission)
|
79
|
+
# skip_authorization if policy.manage?
|
80
|
+
# else
|
81
|
+
# authorize resource
|
82
|
+
# end
|
83
|
+
elsif (resource_instance = controller.instance_variable_get("@#{resource_name}"))
|
84
|
+
authorize resource_instance
|
85
|
+
else
|
86
|
+
authorize resource_name.camelize.constantize
|
87
|
+
end
|
88
|
+
|
89
|
+
verify_authorized
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def resource_name_from_controller
|
95
|
+
params[:controller].split('/').last.singularize
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -2,15 +2,14 @@ module Glib::Json::DynamicText
|
|
2
2
|
def __json_dynamic_text_perform
|
3
3
|
if (hash = json_transformation_start).is_a?(Hash)
|
4
4
|
@__specs = {}
|
5
|
-
|
5
|
+
|
6
6
|
crawl hash['header']&.[]('childViews')
|
7
7
|
crawl hash['body']&.[]('childViews')
|
8
8
|
crawl hash['footer']&.[]('childViews')
|
9
9
|
|
10
|
-
|
11
|
-
# translated_texts = retrieve_remote_texts(@__specs.keys)
|
10
|
+
translated_texts = retrieve_remote_texts(@__specs.keys)
|
12
11
|
|
13
|
-
translated_texts = retrieve_example_texts(@__specs.keys)
|
12
|
+
# translated_texts = retrieve_example_texts(@__specs.keys)
|
14
13
|
translated_texts.each do |key, value|
|
15
14
|
@__specs[key].each do |spec|
|
16
15
|
spec.substitute_with(value)
|
@@ -32,6 +31,11 @@ module Glib::Json::DynamicText
|
|
32
31
|
translated_texts
|
33
32
|
end
|
34
33
|
|
34
|
+
def retrieve_remote_texts(keys)
|
35
|
+
response = RestClient.get(ENV['DTR_URL'], { params: { keys: keys } })
|
36
|
+
JSON.parse(response)
|
37
|
+
end
|
38
|
+
|
35
39
|
def crawl views
|
36
40
|
Glib::Json::DynamicText::crawl_multiple views, ->(view) do
|
37
41
|
extract_spec(view, 'text')
|
@@ -52,7 +56,7 @@ module Glib::Json::DynamicText
|
|
52
56
|
view[prop] = text.gsub(/\{\{(\w+)\}\}/) { args.fetch($1, "{{#{$1}}}") }
|
53
57
|
end
|
54
58
|
end
|
55
|
-
|
59
|
+
|
56
60
|
def self.crawl_multiple views, block
|
57
61
|
if views.is_a? Array
|
58
62
|
views.each do |view|
|
@@ -85,7 +89,7 @@ module Glib::Json::DynamicText
|
|
85
89
|
# panels/split
|
86
90
|
# crawl_multiple view['leftViews'], block
|
87
91
|
# crawl_multiple view['rightViews'], block
|
88
|
-
|
92
|
+
|
89
93
|
# Split panel
|
90
94
|
crawl_vertical_content view['left'], block
|
91
95
|
crawl_vertical_content view['center'], block
|
@@ -0,0 +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
|
@@ -6,7 +6,9 @@ json_ui_page json do |page|
|
|
6
6
|
page.list firstSection: ->(section) do
|
7
7
|
section.rows builder: ->(template) do
|
8
8
|
template.thumbnail title: 'Send Desktop Notification', onClick: ->(action) do
|
9
|
-
action.dialogs_notification title: 'Hello World', body: 'Body Message'
|
9
|
+
action.dialogs_notification title: 'Hello World', body: 'Body Message', onClick: ->(action) do
|
10
|
+
action.dialogs_alert message: 'TODO'
|
11
|
+
end
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
json.title 'Panels'
|
1
|
+
json.title 'Responsive Panels'
|
2
2
|
|
3
3
|
json_ui_page json do |page|
|
4
4
|
render "#{@path_prefix}/nav_menu", json: json, page: page
|
@@ -7,37 +7,49 @@ json_ui_page json do |page|
|
|
7
7
|
scroll.label text: 'Shrink the browser\'s width to see how the column panels are rearranged. On mobile screens, they are always arranged vertically'
|
8
8
|
|
9
9
|
scroll.spacer height: 20
|
10
|
-
scroll.h2 text: '
|
10
|
+
scroll.h2 text: 'With 12 columns'
|
11
11
|
scroll.spacer height: 6
|
12
12
|
scroll.panels_responsive width: 'matchParent', childViews: ->(horizontal) do
|
13
|
-
horizontal.panels_column lg: 8, backgroundColor: '#c3cad2', childViews: ->(column) do
|
13
|
+
horizontal.panels_column lg: { cols: 8 }, backgroundColor: '#c3cad2', childViews: ->(column) do
|
14
14
|
column.button text: '1'
|
15
15
|
end
|
16
|
-
horizontal.panels_column lg: 4, backgroundColor: '#b3bac2', childViews: ->(column) do
|
16
|
+
horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#b3bac2', childViews: ->(column) do
|
17
17
|
column.button text: '2'
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
scroll.spacer height: 20
|
22
|
-
scroll.h2 text: '
|
22
|
+
scroll.h2 text: 'With more than 12 columns'
|
23
23
|
scroll.spacer height: 6
|
24
24
|
scroll.panels_responsive width: 'matchParent', childViews: ->(horizontal) do
|
25
|
-
horizontal.panels_column lg: 4, backgroundColor: '#c3cad2', childViews: ->(column) do
|
25
|
+
horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#c3cad2', childViews: ->(column) do
|
26
26
|
column.button text: '1'
|
27
27
|
end
|
28
|
-
horizontal.panels_column lg: 4, backgroundColor: '#b3bac2', childViews: ->(column) do
|
28
|
+
horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#b3bac2', childViews: ->(column) do
|
29
29
|
column.button text: '2'
|
30
30
|
end
|
31
|
-
horizontal.panels_column lg: 4, backgroundColor: '#c3cad2', childViews: ->(column) do
|
31
|
+
horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#c3cad2', childViews: ->(column) do
|
32
32
|
column.button text: '3'
|
33
33
|
end
|
34
|
-
horizontal.panels_column lg: 4, backgroundColor: '#b3bac2', childViews: ->(column) do
|
34
|
+
horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#b3bac2', childViews: ->(column) do
|
35
35
|
column.button text: '4'
|
36
36
|
end
|
37
|
-
horizontal.panels_column lg: 4, backgroundColor: '#c3cad2', childViews: ->(column) do
|
37
|
+
horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#c3cad2', childViews: ->(column) do
|
38
38
|
column.button text: '5'
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
scroll.spacer height: 20
|
43
|
+
scroll.h2 text: 'With responsive paddings'
|
44
|
+
scroll.spacer height: 6
|
45
|
+
scroll.panels_responsive width: 'matchParent', childViews: ->(horizontal) do
|
46
|
+
horizontal.panels_column lg: { cols: 8, padding: { right: 20 } }, childViews: ->(column) do
|
47
|
+
column.button width: 'matchParent', text: '1'
|
48
|
+
end
|
49
|
+
horizontal.panels_column lg: { cols: 4 }, childViews: ->(column) do
|
50
|
+
column.button width: 'matchParent', text: '2'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
42
54
|
end
|
43
55
|
end
|
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.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ''
|
@@ -30,6 +30,34 @@ dependencies:
|
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 6.1.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: pundit
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 2.1.0
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.1.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rest-client
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.1'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '2.1'
|
33
61
|
description:
|
34
62
|
email: ''
|
35
63
|
executables: []
|
@@ -40,6 +68,7 @@ files:
|
|
40
68
|
- app/controllers/concerns/application/json/transformation.rb
|
41
69
|
- app/controllers/concerns/application/json/ui.rb
|
42
70
|
- app/controllers/concerns/application/json/validation.rb
|
71
|
+
- app/controllers/concerns/glib/auth/policy.rb
|
43
72
|
- app/controllers/concerns/glib/json/dynamic_text.rb
|
44
73
|
- app/controllers/concerns/glib/json/libs.rb
|
45
74
|
- app/controllers/concerns/glib/json/transformation.rb
|
@@ -63,6 +92,7 @@ files:
|
|
63
92
|
- app/helpers/glib/json_ui/view_builder/panels.rb
|
64
93
|
- app/models/glib/dynamic_text_record.rb
|
65
94
|
- app/models/glib/text.rb
|
95
|
+
- app/policies/glib/application_policy.rb
|
66
96
|
- app/views/app/views/json_ui/vue/renderer.html.erb
|
67
97
|
- app/views/json_ui/garage/_nav_menu.json.jbuilder
|
68
98
|
- app/views/json_ui/garage/actions/index.json.jbuilder
|