isomorfeus-policy 1.0.0.zeta20 → 1.0.0.zeta21

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
  SHA256:
3
- metadata.gz: 48fea48dd7bc63c0bd8c1465c98df1bcac727dfa208599af0c2fe0fafa3ddc8a
4
- data.tar.gz: 7e942d873d4061c5e6527b9d65665037a1ce4917afaad776d8eb95ef0ee31beb
3
+ metadata.gz: 6890b7e65d0609f7d51e451f859d06cd9529981f5881516e1b8e6fc0ca0357a4
4
+ data.tar.gz: 239b6f38293b8ffbe611dd799608f59aa1048fc74fcd556976ccbf8ae3123d49
5
5
  SHA512:
6
- metadata.gz: 7c72b02fa4541d0f699b3c53d2fd41f5cd737b011526135bb339b0db57926e60b6c31f0803246772b8ff881cff21213a1ec26384a6c385ca04fd7d7d2f8925ad
7
- data.tar.gz: c73d600b37534bfd2aa23c211a55f3a6bdcdfd239178530b1d80711335358b1049fcfb5c78a8eb1024084a8f6e6026332280c6faf5fda818dc1a83a2e755580f
6
+ metadata.gz: 57dac119ade4a91c632531ad8ef673af0fc9d3ca270471b7cc85e9a0bfa1c2114fa86f96ed8fc6ebfdd799dee7a4516efb2aeddc9223fc66759b9bee3c99b1f8
7
+ data.tar.gz: 79e70b82d2f08fe7e5347e09f6650f82969e10a8dc25ea8149efd7b95e731fafe30d1940251ff9f1e39186d5f6ba7ce04dfd7f716475b2fb84c5f05da5fdbd47
data/README.md CHANGED
@@ -153,3 +153,30 @@ class MyUserPolicy < LucidPolicy::Base
153
153
  deny others
154
154
  end
155
155
  ```
156
+ ### Debugging Policies or finding out the winning rule
157
+ Its possible to start recording the reason for a authorization result:
158
+ ```ruby
159
+ my_user.record_authorization_reason
160
+ ```
161
+ When then authorizing:
162
+ ```ruby
163
+ my_user.authorized?(BlaGraph, :load)
164
+ ```
165
+ the reason for access aor denied access, the winning rule, cen be inspected:
166
+ ```ruby
167
+ my_user.authozation_reason
168
+ ```
169
+
170
+ It will be a Hash and show the responsible policy class, condition, condition result, etc. Example:
171
+ ```ruby
172
+ { combined:
173
+ { class_name: "Resource",
174
+ others: :deny,
175
+ policy_class: "CombinedPolicy" },
176
+ policy_class: "UserPolicy" }
177
+ ```
178
+
179
+ Recording can be stopped again, for better performance:
180
+ ```ruby
181
+ my_user.stop_to_record_authorization_reason
182
+ ```
@@ -1,5 +1,5 @@
1
1
  module Isomorfeus
2
2
  module Policy
3
- VERSION = '1.0.0.zeta20'
3
+ VERSION = '1.0.0.zeta21'
4
4
  end
5
5
  end
@@ -1,5 +1,18 @@
1
1
  module LucidAuthorization
2
2
  module Mixin
3
+ def record_authorization_reason
4
+ @_isomorfeus_record_authorization_reason = true
5
+ end
6
+
7
+ def stop_to_record_authorization_reason
8
+ @_isomorfeus_record_authorization_reason = false
9
+ @_isomorfeus_authorization_reason = nil
10
+ end
11
+
12
+ def authorization_reason
13
+ @_isomorfeus_authorization_reason
14
+ end
15
+
3
16
  def authorized?(target_class, target_method = nil, props = nil)
4
17
  begin
5
18
  class_name = self.class.name
@@ -9,7 +22,10 @@ module LucidAuthorization
9
22
  policy_class = nil
10
23
  end
11
24
  return false unless policy_class
12
- policy_class.new(self).authorized?(target_class, target_method, props)
25
+ policy_instance = policy_class.new(self, @_isomorfeus_record_authorization_reason)
26
+ result = policy_instance.authorized?(target_class, target_method, props)
27
+ @_isomorfeus_authorization_reason = policy_instance.reason
28
+ result
13
29
  end
14
30
 
15
31
  def authorized!(target_class, target_method = nil, props = nil)
@@ -17,7 +33,10 @@ module LucidAuthorization
17
33
  class_name = class_name.split('>::').last if class_name.start_with?('#<')
18
34
  policy_class = Isomorfeus.cached_policy_class("#{class_name}Policy")
19
35
  Isomorfeus.raise_error(error_class: LucidPolicy::Exception, message: "#{self}: policy class #{class_name}Policy not found!") unless policy_class
20
- policy_class.new(self).authorized!(target_class, target_method, props)
36
+ policy_instance = policy_class.new(self, @_isomorfeus_record_authorization_reason)
37
+ result = policy_instance.authorized!(target_class, target_method, props)
38
+ @_isomorfeus_authorization_reason = policy_instance.reason
39
+ result
21
40
  end
22
41
  end
23
42
  end
@@ -56,7 +56,7 @@ module LucidPolicy
56
56
  if class_method_option.class == Symbol && class_or_method_s[0].downcase == class_or_method_s[0]
57
57
  target_methods << class_method_option
58
58
  else
59
- class_method_option = class_method_option.to_s unless class_method_option.class == String
59
+ class_method_option = class_or_method_s unless class_method_option.class == String
60
60
  target_classes << class_method_option
61
61
  end
62
62
  end
@@ -65,6 +65,7 @@ module LucidPolicy
65
65
  thing_or_block = block_given? ? block : thing
66
66
 
67
67
  target_classes.each do |target_class|
68
+ target_class = target_class.split('>::').last if target_class.start_with?('#<')
68
69
  rules[:rules][target_class] = {} unless rules[:rules].key?(target_class)
69
70
 
70
71
  if target_methods.empty?
@@ -82,14 +83,23 @@ module LucidPolicy
82
83
  end
83
84
  end
84
85
 
85
- def initialize(object)
86
+ attr_reader :reason
87
+
88
+ def initialize(object, record_reason = nil)
86
89
  @object = object
90
+ @reason = nil
91
+ @record_reason = record_reason
92
+ if @record_reason
93
+ @class_name = self.class.name
94
+ @class_name = @class_name.split('>::').last if @class_name.start_with?('#<')
95
+ end
87
96
  end
88
97
 
89
98
  def authorized?(target_class, target_method = nil, props = nil)
90
- Isomorfeus.raise_error(error_class: LucidPolicy::Exception, message: "#{self}: At least the class must be given!") unless target_class
99
+ Isomorfeus.raise_error(error_class: LucidPolicy::Exception, message: "#{self}: At least the class or class name must be given!") unless target_class
91
100
 
92
101
  target_class = target_class.to_s unless target_class.class == String
102
+ target_class = target_class.split('>::').last if target_class.start_with?('#<')
93
103
 
94
104
  rules = self.class.authorization_rules
95
105
 
@@ -97,14 +107,20 @@ module LucidPolicy
97
107
  if target_method && rules[:rules][target_class].key?(:methods) && rules[:rules][target_class][:methods].key?(target_method)
98
108
  options = rules[:rules][target_class][:methods][target_method][:options]
99
109
  rule = rules[:rules][target_class][:methods][target_method][:rule]
110
+ @reason = { policy_class: @class_name, class_name: target_class, method: target_method, rule: rule } if @record_reason
100
111
  else
101
112
  options = rules[:rules][target_class][:options]
102
113
  rule = rules[:rules][target_class][:rule]
114
+ @reason = { policy_class: @class_name, class_name: target_class, rule: rule } if @record_reason
103
115
  end
104
116
 
105
- if rule.class == Symbol
117
+ if rule.class == Symbol || rule.class == String
106
118
  if options
107
119
  condition, method_result = __get_condition_and_result(options)
120
+ if @record_reason
121
+ @reason[:condition] = condition
122
+ @reason[:condition_result] = method_result
123
+ end
108
124
  rule if (condition == :if && method_result == true) || (condition == :if_not && method_result == false)
109
125
  else
110
126
  rule
@@ -113,10 +129,14 @@ module LucidPolicy
113
129
  props = LucidProps.new(props) unless props.class == LucidProps
114
130
  policy_helper = LucidPolicy::Helper.new
115
131
  policy_helper.instance_exec(@object, target_class, target_method, props, &rule)
116
- policy_helper.result
132
+ r = policy_helper.result
133
+ @reason[:rule_result] = r if @record_reason
134
+ r
117
135
  end
118
136
  else
119
- rules[:others]
137
+ r = rules[:others]
138
+ @reason = { policy_class: @class_name, class_name: target_class, others: r } if @record_reason
139
+ r
120
140
  end
121
141
 
122
142
  return true if result == :allow
@@ -124,11 +144,15 @@ module LucidPolicy
124
144
  rules[:policies].each do |policy_class, options|
125
145
  combined_policy_result = nil
126
146
  if options.empty?
127
- combined_policy_result = policy_class.new(@object).authorized?(target_class, target_method, props)
147
+ policy_instance = policy_class.new(@object, @record_reason)
148
+ combined_policy_result = policy_instance.authorized?(target_class, target_method, props)
149
+ @reason = @reason = { policy_class: @class_name, combined: policy_instance.reason } if @record_reason
128
150
  else
129
151
  condition, method_result = __get_condition_and_result(options)
130
152
  if (condition == :if && method_result == true) || (condition == :if_not && method_result == false)
131
- combined_policy_result = policy_class.new(@object).authorized?(target_class, target_method, props)
153
+ policy_instance = policy_class.new(@object, @record_reason)
154
+ combined_policy_result = policy_instance.authorized?(target_class, target_method, props)
155
+ @reason = { policy_class: @class_name, combined: policy_instance.reason, condition: condition, condition_result: method_result } if @record_reason
132
156
  end
133
157
  end
134
158
  return true if combined_policy_result == true
@@ -138,8 +162,10 @@ module LucidPolicy
138
162
  end
139
163
 
140
164
  def authorized!(target_class, target_method = nil, props = nil)
141
- return true if authorized?(target_class, target_method, props)
142
- Isomorfeus.raise_error(error_class: LucidPolicy::Exception, message: "#{@object}: not authorized to call #{target_class}.#{target_method}(#{props})!")
165
+ result = authorized?(target_class, target_method, props)
166
+ reason_message = reason ? ", reason: #{reason}" : ''
167
+ return true if result
168
+ Isomorfeus.raise_error(error_class: LucidPolicy::Exception, message: "#{@object}: not authorized to call #{target_class}#{}#{target_method} #{props} #{reason_message}!")
143
169
  end
144
170
 
145
171
  private
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isomorfeus-policy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.zeta20
4
+ version: 1.0.0.zeta21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Biedermann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-20 00:00:00.000000000 Z
11
+ date: 2020-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 1.0.0.zeta20
61
+ version: 1.0.0.zeta21
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 1.0.0.zeta20
68
+ version: 1.0.0.zeta21
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: opal-webpack-loader
71
71
  requirement: !ruby/object:Gem::Requirement