isomorfeus-policy 1.0.0.zeta22 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,42 +1,42 @@
1
- module LucidAuthorization
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
-
16
- def authorized?(target_class, target_method = nil, props = nil)
17
- begin
18
- class_name = self.class.name
19
- class_name = class_name.split('>::').last if class_name.start_with?('#<')
20
- policy_class = Isomorfeus.cached_policy_class("#{class_name}Policy")
21
- rescue ::NameError
22
- policy_class = nil
23
- end
24
- return false unless policy_class
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
29
- end
30
-
31
- def authorized!(target_class, target_method = nil, props = nil)
32
- class_name = self.class.name
33
- class_name = class_name.split('>::').last if class_name.start_with?('#<')
34
- policy_class = Isomorfeus.cached_policy_class("#{class_name}Policy")
35
- Isomorfeus.raise_error(error_class: LucidPolicy::Exception, message: "#{self}: policy class #{class_name}Policy not found!") unless policy_class
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
40
- end
41
- end
42
- end
1
+ module LucidAuthorization
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
+
16
+ def authorized?(target_class, target_method = nil, props = nil)
17
+ begin
18
+ class_name = self.class.name
19
+ class_name = class_name.split('>::').last if class_name.start_with?('#<')
20
+ policy_class = Isomorfeus.cached_policy_class("#{class_name}Policy")
21
+ rescue ::NameError
22
+ policy_class = nil
23
+ end
24
+ return false unless policy_class
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
29
+ end
30
+
31
+ def authorized!(target_class, target_method = nil, props = nil)
32
+ class_name = self.class.name
33
+ class_name = class_name.split('>::').last if class_name.start_with?('#<')
34
+ policy_class = Isomorfeus.cached_policy_class("#{class_name}Policy")
35
+ Isomorfeus.raise_error(error_class: LucidPolicy::Exception, message: "#{self}: policy class #{class_name}Policy not found!") unless policy_class
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
40
+ end
41
+ end
42
+ end
@@ -1,11 +1,10 @@
1
- module LucidPolicy
2
- class Base
3
- include LucidPolicy::Mixin
4
-
5
- if RUBY_ENGINE != 'opal'
6
- def self.inherited(base)
7
- Isomorfeus.add_valid_policy_class(base)
8
- end
9
- end
10
- end
11
- end
1
+ module LucidPolicy
2
+ class Base
3
+ def self.inherited(base)
4
+ base.include LucidPolicy::Mixin
5
+ if RUBY_ENGINE != 'opal'
6
+ Isomorfeus.add_valid_policy_class(base)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -1,4 +1,4 @@
1
- module LucidPolicy
2
- class Exception < ::Exception
3
- end
4
- end
1
+ module LucidPolicy
2
+ class Exception < ::Exception
3
+ end
4
+ end
@@ -1,18 +1,18 @@
1
- module LucidPolicy
2
- class Helper < BasicObject
3
- attr_reader :result
4
-
5
- def initialize
6
- @result = :deny
7
- end
8
-
9
- def allow
10
- @result = :allow
11
- nil
12
- end
13
-
14
- def deny
15
- nil
16
- end
17
- end
18
- end
1
+ module LucidPolicy
2
+ class Helper < BasicObject
3
+ attr_reader :result
4
+
5
+ def initialize
6
+ @result = :deny
7
+ end
8
+
9
+ def allow
10
+ @result = :allow
11
+ nil
12
+ end
13
+
14
+ def deny
15
+ nil
16
+ end
17
+ end
18
+ end
@@ -1,195 +1,191 @@
1
- module LucidPolicy
2
- module Mixin
3
- def self.included(base)
4
- base.instance_exec do
5
- if RUBY_ENGINE != 'opal'
6
- Isomorfeus.add_valid_policy_class(base) unless base == LucidPolicy::Base
7
- end
8
-
9
- def authorization_rules
10
- @authorization_rules ||= { rules: {}.dup, policies: {}.dup, others: :deny }.dup
11
- end
12
-
13
- def all
14
- :others
15
- end
16
-
17
- def allow(*classes_and_methods_and_options)
18
- _allow_or_deny(:allow, *classes_and_methods_and_options)
19
- end
20
-
21
- def deny(*classes_and_methods_and_options)
22
- _allow_or_deny(:deny, *classes_and_methods_and_options)
23
- end
24
-
25
- def others
26
- :others
27
- end
28
-
29
- def rule(*classes_and_methods, &block)
30
- _allow_or_deny(:rule, *classes_and_methods, &block)
31
- end
32
-
33
- def combine_with(policy_class, **options)
34
- authorization_rules[:policies] = { policy_class => options }
35
- end
36
-
37
- private
38
-
39
- def _allow_or_deny(thing, *classes_methods_options, &block)
40
- rules = authorization_rules
41
-
42
- if %i[allow deny].include?(thing) && classes_methods_options.first == :others
43
- rules[:others] = thing
44
- return
45
- end
46
-
47
- target_classes = []
48
- target_methods = []
49
- target_options = {}
50
-
51
- classes_methods_options.each do |class_method_option|
52
- if class_method_option.class == Hash
53
- target_options = class_method_option
54
- else
55
- class_or_method_s = class_method_option.to_s
56
- if class_method_option.class == Symbol && class_or_method_s[0].downcase == class_or_method_s[0]
57
- target_methods << class_method_option
58
- else
59
- class_method_option = class_or_method_s unless class_method_option.class == String
60
- target_classes << class_method_option
61
- end
62
- end
63
- end
64
-
65
- thing_or_block = block_given? ? block : thing
66
-
67
- target_classes.each do |target_class|
68
- target_class = target_class.split('>::').last if target_class.start_with?('#<')
69
- rules[:rules][target_class] = {} unless rules[:rules].key?(target_class)
70
-
71
- if target_methods.empty?
72
- rules[:rules][target_class][:rule] = thing_or_block
73
- rules[:rules][target_class][:options] = target_options unless target_options.empty?
74
- else
75
- rules[:rules][target_class][:rule] = :deny unless rules[:rules][target_class].key?(:rule)
76
- rules[:rules][target_class][:methods] = {} unless rules[:rules][target_class].key?(:methods)
77
- target_methods.each do |target_method|
78
- rules[:rules][target_class][:methods][target_method] = { rule: thing_or_block }
79
- rules[:rules][target_class][:methods][target_method][:options] = target_options unless target_options.empty?
80
- end
81
- end
82
- end
83
- end
84
- end
85
-
86
- attr_reader :reason
87
-
88
- def initialize(object, record_reason = nil)
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
96
- end
97
-
98
- def authorized?(target_class, target_method = nil, props = nil)
99
- Isomorfeus.raise_error(error_class: LucidPolicy::Exception, message: "#{self}: At least the class or class name must be given!") unless target_class
100
-
101
- target_class = target_class.to_s unless target_class.class == String
102
- target_class = target_class.split('>::').last if target_class.start_with?('#<')
103
-
104
- rules = self.class.authorization_rules
105
-
106
- result = if rules[:rules].key?(target_class)
107
- if target_method && rules[:rules][target_class].key?(:methods) && rules[:rules][target_class][:methods].key?(target_method)
108
- options = rules[:rules][target_class][:methods][target_method][:options]
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
111
- else
112
- options = rules[:rules][target_class][:options]
113
- rule = rules[:rules][target_class][:rule]
114
- @reason = { policy_class: @class_name, class_name: target_class, rule: rule } if @record_reason
115
- end
116
-
117
- if rule.class == Symbol || rule.class == String
118
- if options
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
124
- rule if (condition == :if && method_result == true) || (condition == :if_not && method_result == false)
125
- else
126
- rule
127
- end
128
- else
129
- props = LucidProps.new(props) unless props.class == LucidProps
130
- policy_helper = LucidPolicy::Helper.new
131
- policy_helper.instance_exec(@object, target_class, target_method, props, &rule)
132
- r = policy_helper.result
133
- @reason[:rule_result] = r if @record_reason
134
- r
135
- end
136
- else
137
- r = rules[:others]
138
- @reason = { policy_class: @class_name, class_name: target_class, others: r } if @record_reason
139
- r
140
- end
141
-
142
- return true if result == :allow
143
-
144
- rules[:policies].each do |policy_class, options|
145
- combined_policy_result = nil
146
- if options.empty?
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
150
- else
151
- condition, method_result = __get_condition_and_result(options)
152
- if (condition == :if && method_result == true) || (condition == :if_not && method_result == false)
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
156
- end
157
- end
158
- return true if combined_policy_result == true
159
- end
160
-
161
- result == :allow ? true : false
162
- end
163
-
164
- def authorized!(target_class, target_method = nil, props = nil)
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}!")
169
- end
170
-
171
- private
172
-
173
- def __get_condition_and_result(options)
174
- condition = nil
175
- method_name_or_block = if options.key?(:if)
176
- condition = :if
177
- options[:if]
178
- elsif options.key?(:if_not)
179
- condition = :if_not
180
- options[:if_not]
181
- elsif options.key?(:unless)
182
- condition = :if_not
183
- options[:unless]
184
- end
185
- method_result = if method_name_or_block && method_name_or_block.class == Symbol
186
- @object.__send__(method_name_or_block)
187
- else
188
- props = LucidProps.new(props) unless props.class == LucidProps
189
- method_name_or_block.call(@object, props)
190
- end
191
- [condition, method_result]
192
- end
193
- end
194
- end
195
- end
1
+ module LucidPolicy
2
+ module Mixin
3
+ def self.included(base)
4
+ base.instance_exec do
5
+ if RUBY_ENGINE != 'opal'
6
+ Isomorfeus.add_valid_policy_class(base) unless base == LucidPolicy::Base
7
+ end
8
+
9
+ def authorization_rules
10
+ @authorization_rules ||= { rules: {}.dup, policies: {}.dup, others: :deny }.dup
11
+ end
12
+
13
+ def all
14
+ :others
15
+ end
16
+
17
+ def allow(*classes_and_methods_and_options)
18
+ _allow_or_deny(:allow, *classes_and_methods_and_options)
19
+ end
20
+
21
+ def deny(*classes_and_methods_and_options)
22
+ _allow_or_deny(:deny, *classes_and_methods_and_options)
23
+ end
24
+
25
+ def others
26
+ :others
27
+ end
28
+
29
+ def rule(*classes_and_methods, &block)
30
+ _allow_or_deny(:rule, *classes_and_methods, &block)
31
+ end
32
+
33
+ def combine_with(policy_class, **options)
34
+ authorization_rules[:policies] = { policy_class => options }
35
+ end
36
+
37
+ def _allow_or_deny(thing, *classes_methods_options, &block)
38
+ rules = authorization_rules
39
+
40
+ if %i[allow deny].include?(thing) && classes_methods_options.first == :others
41
+ rules[:others] = thing
42
+ return
43
+ end
44
+
45
+ target_classes = []
46
+ target_methods = []
47
+ target_options = {}
48
+
49
+ classes_methods_options.each do |class_method_option|
50
+ if class_method_option.class == Hash
51
+ target_options = class_method_option
52
+ else
53
+ class_or_method_s = class_method_option.to_s
54
+ if class_method_option.class == Symbol && class_or_method_s[0].downcase == class_or_method_s[0]
55
+ target_methods << class_method_option
56
+ else
57
+ class_method_option = class_or_method_s unless class_method_option.class == String
58
+ target_classes << class_method_option
59
+ end
60
+ end
61
+ end
62
+
63
+ thing_or_block = block_given? ? block : thing
64
+
65
+ target_classes.each do |target_class|
66
+ target_class = target_class.split('>::').last if target_class.start_with?('#<')
67
+ rules[:rules][target_class] = {} unless rules[:rules].key?(target_class)
68
+
69
+ if target_methods.empty?
70
+ rules[:rules][target_class][:rule] = thing_or_block
71
+ rules[:rules][target_class][:options] = target_options unless target_options.empty?
72
+ else
73
+ rules[:rules][target_class][:rule] = :deny unless rules[:rules][target_class].key?(:rule)
74
+ rules[:rules][target_class][:methods] = {} unless rules[:rules][target_class].key?(:methods)
75
+ target_methods.each do |target_method|
76
+ rules[:rules][target_class][:methods][target_method] = { rule: thing_or_block }
77
+ rules[:rules][target_class][:methods][target_method][:options] = target_options unless target_options.empty?
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ attr_reader :reason
85
+
86
+ def initialize(object, record_reason = nil)
87
+ @object = object
88
+ @reason = nil
89
+ @record_reason = record_reason
90
+ if @record_reason
91
+ @class_name = self.class.name
92
+ @class_name = @class_name.split('>::').last if @class_name.start_with?('#<')
93
+ end
94
+ end
95
+
96
+ def authorized?(target_class, target_method = nil, props = nil)
97
+ Isomorfeus.raise_error(error_class: LucidPolicy::Exception, message: "#{self}: At least the class or class name must be given!") unless target_class
98
+
99
+ target_class = target_class.to_s unless target_class.class == String
100
+ target_class = target_class.split('>::').last if target_class.start_with?('#<')
101
+
102
+ rules = self.class.authorization_rules
103
+
104
+ result = if rules[:rules].key?(target_class)
105
+ if target_method && rules[:rules][target_class].key?(:methods) && rules[:rules][target_class][:methods].key?(target_method)
106
+ options = rules[:rules][target_class][:methods][target_method][:options]
107
+ rule = rules[:rules][target_class][:methods][target_method][:rule]
108
+ @reason = { policy_class: @class_name, class_name: target_class, method: target_method, rule: rule } if @record_reason
109
+ else
110
+ options = rules[:rules][target_class][:options]
111
+ rule = rules[:rules][target_class][:rule]
112
+ @reason = { policy_class: @class_name, class_name: target_class, rule: rule } if @record_reason
113
+ end
114
+
115
+ if rule.class == Symbol || rule.class == String
116
+ if options
117
+ condition, method_result = _get_condition_and_result(options)
118
+ if @record_reason
119
+ @reason[:condition] = condition
120
+ @reason[:condition_result] = method_result
121
+ end
122
+ rule if (condition == :if && method_result == true) || (condition == :if_not && method_result == false)
123
+ else
124
+ rule
125
+ end
126
+ else
127
+ props = LucidProps.new(props) unless props.class == LucidProps
128
+ policy_helper = LucidPolicy::Helper.new
129
+ policy_helper.instance_exec(@object, target_class, target_method, props, &rule)
130
+ r = policy_helper.result
131
+ @reason[:rule_result] = r if @record_reason
132
+ r
133
+ end
134
+ else
135
+ r = rules[:others]
136
+ @reason = { policy_class: @class_name, class_name: target_class, others: r } if @record_reason
137
+ r
138
+ end
139
+
140
+ return true if result == :allow
141
+
142
+ rules[:policies].each do |policy_class, options|
143
+ combined_policy_result = nil
144
+ if options.empty?
145
+ policy_instance = policy_class.new(@object, @record_reason)
146
+ combined_policy_result = policy_instance.authorized?(target_class, target_method, props)
147
+ @reason = @reason = { policy_class: @class_name, combined: policy_instance.reason } if @record_reason
148
+ else
149
+ condition, method_result = _get_condition_and_result(options)
150
+ if (condition == :if && method_result == true) || (condition == :if_not && method_result == false)
151
+ policy_instance = policy_class.new(@object, @record_reason)
152
+ combined_policy_result = policy_instance.authorized?(target_class, target_method, props)
153
+ @reason = { policy_class: @class_name, combined: policy_instance.reason, condition: condition, condition_result: method_result } if @record_reason
154
+ end
155
+ end
156
+ return true if combined_policy_result == true
157
+ end
158
+
159
+ result == :allow ? true : false
160
+ end
161
+
162
+ def authorized!(target_class, target_method = nil, props = nil)
163
+ result = authorized?(target_class, target_method, props)
164
+ reason_message = reason ? ", reason: #{reason}" : ''
165
+ return true if result
166
+ Isomorfeus.raise_error(error_class: LucidPolicy::Exception, message: "#{@object}: not authorized to call #{target_class}#{}#{target_method} #{props} #{reason_message}!")
167
+ end
168
+
169
+ def _get_condition_and_result(options)
170
+ condition = nil
171
+ method_name_or_block = if options.key?(:if)
172
+ condition = :if
173
+ options[:if]
174
+ elsif options.key?(:if_not)
175
+ condition = :if_not
176
+ options[:if_not]
177
+ elsif options.key?(:unless)
178
+ condition = :if_not
179
+ options[:unless]
180
+ end
181
+ method_result = if method_name_or_block && method_name_or_block.class == Symbol
182
+ @object.__send__(method_name_or_block)
183
+ else
184
+ props = LucidProps.new(props) unless props.class == LucidProps
185
+ method_name_or_block.call(@object, props)
186
+ end
187
+ [condition, method_result]
188
+ end
189
+ end
190
+ end
191
+ end