glib-web 0.4.24 → 0.4.25

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