glib-web 0.4.24 → 0.4.25

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 94f1a8366e5cece6ec76d5ea2bd1d540cbfc25aa
4
- data.tar.gz: 448751b5cedab8ced7afc9c1b532522528dbec37
3
+ metadata.gz: 6a78169ee4aa218427c3afb3fdb50fd77280f627
4
+ data.tar.gz: d86539782b4e6c0a50cbba7e5ac5b39565e9feb5
5
5
  SHA512:
6
- metadata.gz: '036089a9ccfc6432ec3d4197ae9037eddb049ac6d5fade3830b9e5b2a0b015ae1d9a3e4262ecbf4b5873d1f3441efe2e3f58af0038337f2867788540dae5cc11'
7
- data.tar.gz: b256a373e8443457af3a210898fe3277f618c573ba46d367c4a9c81a40c741c550b76d91135000d099ee52bfb3ef1634dd4134ff8b2c4e49b13d5659c1a49a2c
6
+ metadata.gz: 495d37ef44d6fbad0a970f0f3b3bf35effe81b5ceb866c5eeb1606d179f217f747365d1987caaf910d83c0f26cec6d50ee147bfdcfe0581df583dd367e154d6b
7
+ data.tar.gz: e8942b48722e047778a7bbb8ed9d84734b14ad048700efc05edf835e1770bbeb08e4e63ebe4e43e1212363f16748c51e93167a49332b06d6373f80872e0b4647
@@ -15,28 +15,38 @@ module Glib::Auth
15
15
  # after_action :verify_authorized
16
16
 
17
17
  helper_method :policy, :can?, :cannot?
18
-
19
18
  end
20
19
 
21
20
  module Overrides
21
+
22
22
  public # Override
23
- def policy(record)
23
+ def policy(record, policy_name = nil)
24
+ policy_name ||= record
25
+
24
26
  @__pundit_policies ||= {}
25
- return @__pundit_policies[record] if @__pundit_policies[record]
27
+ return @__pundit_policies[policy_name] if @__pundit_policies[policy_name]
26
28
 
27
- if record.is_a?(Symbol) && record.to_s.ends_with?('_admin')
29
+ if policy_name.is_a?(Symbol) && policy_name.to_s.ends_with?('_admin')
28
30
  policy_class = CommonAdminPolicy
29
31
  else
30
- policy_class = Pundit::PolicyFinder.new(record).policy
32
+ policy_class = Pundit::PolicyFinder.new(policy_name).policy
31
33
  end
32
- raise "Policy not found for #{record.class}" unless policy_class
33
- @__pundit_policies[record] = policy_class.new(current_user, record, self, request, params, *policy_class.args_builder.call(self))
34
+
35
+ raise "Policy not found for #{policy_name.is_a?(Symbol) || policy_name.is_a?(Class) ? policy_name : policy_name.class}" unless policy_class
36
+
37
+ @__pundit_policies[policy_name] = policy_class.new(current_user, record, policy_name, self, request, params, *policy_class.args_builder.call(self))
38
+ end
39
+
40
+ # Expose protected method
41
+ public # Override
42
+ def policy_scope(*args)
43
+ super
34
44
  end
35
45
  end
36
46
 
37
- public
38
- def raise_access_denied(record)
39
- raise UnauthorizedError.new(record: record, policy: policy(record), query: "#{action_name}?")
47
+ private
48
+ def raise_access_denied(record, policy)
49
+ raise UnauthorizedError.new(record: record, policy: policy, query: "#{action_name}?")
40
50
  end
41
51
 
42
52
  public
@@ -49,6 +59,34 @@ module Glib::Auth
49
59
  !policy(record).send("#{action}?")
50
60
  end
51
61
 
62
+ # Inspired from https://github.com/ryanb/cancan/wiki/Non-RESTful-Controllers
63
+ public
64
+ def glib_authorize_resource(*args)
65
+ options = args.extract_options!
66
+ resource_name = args.first
67
+
68
+ resource_name ||= controller_name.split('/').last.singularize
69
+
70
+ if (resource_key = options[:class]).nil?
71
+ policy_name = resource_name.camelize.constantize
72
+ else
73
+ policy_name = case resource_key
74
+ when false
75
+ resource_name.to_sym
76
+ when Symbol, Class
77
+ resource_key
78
+ else
79
+ raise "Invalid resource class: #{resource_key}"
80
+ end
81
+ end
82
+
83
+ resource_instance = instance_variable_get("@#{resource_name}") || policy_name
84
+
85
+ query = "#{action_name}?"
86
+ policy_instance = policy(resource_instance, policy_name)
87
+ raise_access_denied(resource_instance, policy_instance) unless policy_instance.public_send(query)
88
+ end
89
+
52
90
 
53
91
 
54
92
  class UnauthorizedError < Pundit::NotAuthorizedError
@@ -57,7 +95,19 @@ module Glib::Auth
57
95
 
58
96
 
59
97
  module ClassMethods
60
- # Inspired from https://github.com/ryanb/cancan/wiki/Non-RESTful-Controllers
98
+ def glib_auth_init
99
+ before_action :glib_load_resource
100
+ before_action :glib_authorize_resource
101
+ # glib_authorize_resource
102
+ end
103
+
104
+ # def __glib_load_resource
105
+ # case action_name.to_sym
106
+ # # glib_load_resource
107
+ # end
108
+ # end
109
+
110
+ # TODO: Consider deprecating
61
111
  public
62
112
  def authorize_resource(*args)
63
113
  options = args.extract_options!
@@ -1,5 +1,7 @@
1
1
  module Glib
2
2
  class HomeController < ApplicationController
3
+ skip_before_action :glib_load_resource
4
+ skip_before_action :glib_authorize_resource
3
5
 
4
6
  def json_ui_garage
5
7
  @path_prefix = 'json_ui/garage'
@@ -24,9 +24,15 @@ module Glib
24
24
  string :imageUrl
25
25
  action :onClick
26
26
 
27
- # NOTE: Experimental. Still deciding whether this needs to be a full blown panel or
28
- # an array of badges (with relevant properties, e.g. text, color, etc)
29
- views :accessoryViews
27
+ # # NOTE: Experimental. Still deciding whether this needs to be a full blown panel or
28
+ # # an array of badges (with relevant properties, e.g. text, color, etc)
29
+ # views :accessoryViews
30
+
31
+ def chips(block)
32
+ json.chips do
33
+ block.call page.menu_builder
34
+ end
35
+ end
30
36
  end
31
37
 
32
38
  class Featured < Thumbnail
@@ -13,6 +13,7 @@ module Glib
13
13
  icon :icon
14
14
  action :onClick
15
15
  bool :disabled
16
+ color :color
16
17
 
17
18
  def created
18
19
  json.type 'button'
@@ -75,7 +75,7 @@ module Glib
75
75
  # json.leftItems do
76
76
  # options[:leftItems]&.call @menu_builder
77
77
  # end
78
- json.logoUrl "http://localhost:3000/assets/logo_dark-02d9b6a91fdbf22515da7b921d31367b70696214415f6789d2f90232e4a287b7.svg"
78
+ # json.logoUrl "http://localhost:3000/assets/logo_dark-02d9b6a91fdbf22515da7b921d31367b70696214415f6789d2f90232e4a287b7.svg"
79
79
  json.rightItems do
80
80
  options[:rightItems]&.call @menu_builder
81
81
  end
@@ -1,148 +1,158 @@
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, :policy_name, :controller, :request, :params
6
+
7
+ private
8
+ def initialize(user, record, policy_name, 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
+ @policy_name = policy_name
17
+ end
18
+
19
+ class << self
20
+ attr_reader :catch_all
21
+
22
+ # This is to define the authorization logic for an action (or a group of actions). It's different from controller's
23
+ # authorize().
24
+ private # Used by child
25
+ def authorize(*actions, &block)
26
+ actions.each do |action|
27
+ if action == :manage
28
+ # Serve as a catch-all to all actions that have not been specified in the policy.
29
+ @catch_all = block
30
+ else
31
+ method_name = "#{action}?"
32
+ # Avoid accidentally redefining multiple times from child policies. But it's okay if the child policy
33
+ # wants to override the parent's authorization method.
34
+ raise "Action authorization has been declared: #{action}" if instance_methods(false).include?(method_name.to_sym)
35
+ define_method method_name, &block
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ private
42
+ def catch_all
43
+ self.class.catch_all
44
+ end
45
+
46
+ private
47
+ # To ensure the block is called on the policy's instance instead class.
48
+ def call_catch_all
49
+ instance_eval(&catch_all)
50
+ end
51
+
52
+ authorize :index do
53
+ # We need this line because in `index` action, this method will be called instead of method_missing().
54
+ # Having this line ensures that the catch_all behaviour works according to the priority below:
55
+ # - child_policy#index?
56
+ # - child_policy#manage? -- catch_all
57
+ # - application_policy@index?
58
+ return call_catch_all if catch_all
59
+
60
+ false
61
+ end
62
+
63
+ authorize :show do
64
+ return call_catch_all if catch_all
65
+
66
+ scope.where(id: record.id).exists?
67
+ end
68
+
69
+ authorize :create do
70
+ return call_catch_all if catch_all
71
+
72
+ false
73
+ end
74
+
75
+ authorize :new do
76
+ return call_catch_all if catch_all
77
+
78
+ create?
79
+ end
80
+
81
+ authorize :update do
82
+ return call_catch_all if catch_all
83
+
84
+ false
85
+ end
86
+
87
+ authorize :edit do
88
+ return call_catch_all if catch_all
89
+
90
+ update?
91
+ end
92
+
93
+ authorize :destroy do
94
+ return call_catch_all if catch_all
95
+
96
+ false
97
+ end
98
+
99
+ public
100
+ def method_missing(name, *args, &block)
101
+ if name.to_s.end_with?('?') && catch_all
102
+ call_catch_all
103
+ else
104
+ super
105
+ end
106
+ end
107
+
108
+ public
109
+ def scope
110
+ policy_scope_class = Pundit::PolicyFinder.new(@policy_name).scope
111
+ return unless policy_scope_class
112
+
113
+ controller.policy_scope(record.class, policy_scope_class: policy_scope_class)
114
+ end
115
+
116
+ # TODO: Remove. Deprecated
117
+ private # Used by child
118
+ def public?
119
+ true
120
+ end
121
+
122
+ private # Used by child
123
+ def everyone
124
+ true
125
+ end
126
+
127
+ # # 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
128
+ # private # Used by child
129
+ # def not_deleted_unless_owner_or_moderator?(&block)
130
+ # block ||= lambda { |unused_arg| @user.moderator? }
131
+ # !@record.deleted? || (@user && (@user.id == @record.user_owner_id || block.call(@record)))
132
+ # end
133
+
134
+ # private # Used by child
135
+ # def not_deleted_unless_moderator?(&block)
136
+ # block ||= lambda { |unused_arg| @user.moderator? }
137
+ # !@record.deleted? || (@user && block.call(@record))
138
+ # end
139
+
140
+ public
141
+ def self.args_builder
142
+ Proc.new { |controller| [] }
143
+ end
144
+
145
+ class Scope
146
+ attr_reader :user, :scope
147
+
148
+ def initialize(user, scope)
149
+ @user = user
150
+ @scope = scope
151
+ end
152
+
153
+ def resolve
154
+ scope.none
155
+ end
156
+ end
157
+ end
158
+ end
@@ -16,13 +16,14 @@ json_ui_page json do |page|
16
16
  template.thumbnail title: 'Item with thumbnail image', subtitle: 'Item subtitle', imageUrl: glib_json_image_standard_url
17
17
  template.featured title: 'Featured with featured image', subtitle: 'Item subtitle', imageUrl: glib_json_image_standard_url
18
18
 
19
- template.thumbnail title: 'Item with accessories (Experimental)', subtitle: 'Item subtitle', accessoryViews: ->(thumbnail) do
20
- thumbnail.panels_horizontal childViews: ->(horizontal) do
21
- horizontal.chip text: 'finished'
22
- horizontal.spacer width: 10
23
- horizontal.chip text: 'succeeded'
24
- end
25
- end
19
+ # TODO
20
+ # template.thumbnail title: 'Item with accessories (Experimental)', subtitle: 'Item subtitle', accessoryViews: ->(thumbnail) do
21
+ # thumbnail.panels_horizontal childViews: ->(horizontal) do
22
+ # horizontal.chip text: 'finished'
23
+ # horizontal.spacer width: 10
24
+ # horizontal.chip text: 'succeeded'
25
+ # end
26
+ # end
26
27
 
27
28
  end
28
29
  end
@@ -3,7 +3,8 @@ json.title 'Views'
3
3
  page = json_ui_page json
4
4
  render "#{@path_prefix}/nav_menu", json: json, page: page
5
5
 
6
- small_image_url = 'https://icons-for-free.com/iconfiles/png/128/of+thrones+game+thrones+series+character+avatar+jon+snow-1320568555745862611.png'
6
+ # small_image_url = 'https://icons-for-free.com/iconfiles/png/128/of+thrones+game+thrones+series+character+avatar+jon+snow-1320568555745862611.png'
7
+ small_image_url = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSGQpSWjtELISLBlmugOZ6wzl1JamYXQvbFeYywpfg3E8b8DrO0Kg&s'
7
8
 
8
9
  page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
9
10
  scroll.h2 text: 'Avatar'
@@ -33,7 +34,7 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
33
34
 
34
35
  scroll.spacer height: 60
35
36
  scroll.hr
36
-
37
+
37
38
  scroll.spacer height: 60
38
39
  scroll.h2 text: 'Original size'
39
40
  scroll.spacer height: 6
@@ -49,7 +50,7 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
49
50
  scroll.h2 text: 'fit: clip (default) to full width (scale down)'
50
51
  scroll.spacer height: 6
51
52
  scroll.image width: 'matchParent', url: glib_json_image_standard_url
52
-
53
+
53
54
  scroll.spacer height: 20
54
55
  scroll.h2 text: 'fit: clip (default) to full width (scale up)'
55
56
  scroll.spacer height: 6
@@ -58,35 +59,31 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
58
59
  scroll.spacer height: 20
59
60
  scroll.h2 text: 'fit: clip (default) to width (scale down)'
60
61
  scroll.spacer height: 6
61
- scroll.image width: 100, url: glib_json_image_standard_url
62
-
63
- # TODO: Make sure this is the same as https://docs.imgix.com/apis/url/size/fit#clip
62
+ scroll.image width: 320, url: glib_json_image_standard_url
63
+
64
64
  scroll.spacer height: 20
65
65
  scroll.h2 text: 'fit: clip (default) to height (scale down)'
66
66
  scroll.spacer height: 6
67
- scroll.image height: 100, url: glib_json_image_standard_url
68
-
67
+ scroll.image height: 320, url: glib_json_image_standard_url
68
+
69
69
  scroll.spacer height: 20
70
70
  scroll.h2 text: 'fit: clip (default) to width (scale up)'
71
71
  scroll.spacer height: 6
72
- scroll.image width: 240, url: small_image_url
73
-
74
- # TODO: Make sure this is the same as https://docs.imgix.com/apis/url/size/fit#clip
72
+ scroll.image width: 320, url: small_image_url
73
+
75
74
  scroll.spacer height: 20
76
75
  scroll.h2 text: 'fit: clip (default) to height (scale up)'
77
76
  scroll.spacer height: 6
78
- scroll.image height: 240, url: small_image_url
79
-
80
- # TODO: Make sure this is the same as https://docs.imgix.com/apis/url/size/fit#crop
77
+ scroll.image height: 320, url: small_image_url
78
+
81
79
  # Reference: https://docs.imgix.com/apis/url/size/fit#crop
82
80
  scroll.spacer height: 20
83
81
  scroll.h2 text: 'fit: crop to width'
84
82
  scroll.spacer height: 6
85
- scroll.image width: 100, url: glib_json_image_standard_url, fit: :crop
86
-
87
- # TODO: Make sure this is the same as https://docs.imgix.com/apis/url/size/fit#crop
83
+ scroll.image width: 200, url: glib_json_image_standard_url, fit: :crop
84
+
88
85
  scroll.spacer height: 20
89
86
  scroll.h2 text: 'fit: crop to height'
90
87
  scroll.spacer height: 6
91
- scroll.image height: 100, url: glib_json_image_standard_url, fit: :crop
88
+ scroll.image height: 200, url: glib_json_image_standard_url, fit: :crop
92
89
  end
@@ -10,4 +10,4 @@ module Glib
10
10
  end
11
11
  end
12
12
  end
13
- end
13
+ 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.24
4
+ version: 0.4.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''