bali 1.2.0 → 2.0.0rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -8
- data/lib/bali.rb +7 -12
- data/lib/bali/dsl/map_rules_dsl.rb +12 -2
- data/lib/bali/dsl/rules_for_dsl.rb +15 -5
- data/lib/bali/foundations/all_foundations.rb +11 -0
- data/lib/bali/foundations/exceptions/authorization_error.rb +17 -0
- data/lib/bali/{exceptions → foundations/exceptions}/bali_error.rb +0 -0
- data/lib/bali/{exceptions → foundations/exceptions}/dsl_error.rb +0 -0
- data/lib/bali/{exceptions → foundations/exceptions}/objection_error.rb +0 -0
- data/lib/bali/foundations/{rule.rb → rule/rule.rb} +8 -4
- data/lib/bali/foundations/{rule_class.rb → rule/rule_class.rb} +0 -0
- data/lib/bali/foundations/{rule_group.rb → rule/rule_group.rb} +1 -1
- data/lib/bali/integrators/all_integrators.rb +4 -0
- data/lib/bali/{foundations/bali_statics.rb → integrators/rules_integrator.rb} +3 -3
- data/lib/bali/objector.rb +156 -60
- data/lib/bali/version.rb +1 -1
- metadata +14 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf53e89889a8f3f41843b1e46cb4da90c0d76121
|
4
|
+
data.tar.gz: 6fc380eb95bb66723ae74851a796ead78b1f44bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92b8ed097eccd7c929de0617a1359055e4b5fdcccee2d2e3e3af09781b03210ba5c50c76d67281db61e95167f506fbcaa915c6e24e5779d202005133a8566e84
|
7
|
+
data.tar.gz: cc8c1ed6a7e2381d9b41639c2d6d3e4a8250cebc4d3cef2ff50a8f6a22ba066c2bb4f05a5a868f12428a6a566a7583581895986d30b963d9d8e79b53c02a60ce
|
data/README.md
CHANGED
@@ -22,6 +22,11 @@ And then execute:
|
|
22
22
|
|
23
23
|
$ bundle
|
24
24
|
|
25
|
+
## Deprecation notice
|
26
|
+
|
27
|
+
1. `cant` and `cant_all` which are used to declare rules will be deprecated on version 3.0, in favor of `cannot` and `cannot_all`. The reason behind this is that `can` and `cant` only differ by 1 letter, it is thought to be better to make it less ambiguous.
|
28
|
+
2. `cant?` and subsequently new-introduced `cant!` will be deprecated on version 3.0, in favor of `cannot?` and `cannot!` for the same reason as above.
|
29
|
+
|
25
30
|
## Usage
|
26
31
|
|
27
32
|
### Defining access rules
|
@@ -35,8 +40,8 @@ Rule in Bali is the law determining whether a user (called `subtarget`) can do o
|
|
35
40
|
describe :admin_user do
|
36
41
|
can_all
|
37
42
|
# a more specific rule would be executed even if can_all is present
|
38
|
-
can :cancel,
|
39
|
-
if: proc { |record| record.payment_channel == "CREDIT_CARD" &&
|
43
|
+
can :cancel,
|
44
|
+
if: proc { |record| record.payment_channel == "CREDIT_CARD" &&
|
40
45
|
!record.is_settled? }
|
41
46
|
end
|
42
47
|
describe "general user", can: [:update, :edit], cant: [:delete]
|
@@ -148,16 +153,16 @@ That is, we can check `can?` and `cant?` with multiple roles by passing array of
|
|
148
153
|
|
149
154
|
### Using subtarget's instance for Can and Cant testing
|
150
155
|
|
151
|
-
You may pass in real subtarget instance rather than (1) a symbol, (2) string or (3) array of string/symbol for can/cant testing.
|
156
|
+
You may pass in real subtarget instance rather than (1) a symbol, (2) string or (3) array of string/symbol for can/cant testing.
|
152
157
|
|
153
158
|
In order to do so, you need to specify the field/method in the subtarget that will be used to evaluating the subtarget's role(s). To do that, we define `roles_for` as follow inside `Bali.map_rules` block:
|
154
159
|
|
155
160
|
```ruby
|
156
|
-
Bali.map_rules do
|
161
|
+
Bali.map_rules do
|
157
162
|
roles_for My::Employee, :roles
|
158
163
|
roles_for My::AdminUser, :admin_roles
|
159
164
|
roles_for My::BankUser, :roles
|
160
|
-
|
165
|
+
|
161
166
|
# rules definition
|
162
167
|
# may follow
|
163
168
|
end
|
@@ -173,6 +178,22 @@ By doing so, we can now perform authorisation testing as follow:
|
|
173
178
|
txn.can?(current_employee, :print)
|
174
179
|
```
|
175
180
|
|
181
|
+
### Raises error on unauthorized access
|
182
|
+
|
183
|
+
`can?` and `cant?` just return boolean values on whether access is granted or not. If you want to raise an exception when an operation is inappropriate, use its variant: `can!` and `cant!`
|
184
|
+
|
185
|
+
When `can!` result in denied operation, it will raise `Bali::AuthorizationError`. In the other hand, `cant!` will raise `Bali::AuthorizationError` if it allows an operation.
|
186
|
+
|
187
|
+
`can!` and `cant` are invoked with a similar fashion as you would invoke `can?` and `cant?`
|
188
|
+
|
189
|
+
`Bali::AuthorizationError` is more than an exception, it also store information regarding:
|
190
|
+
|
191
|
+
1. `auth_level`: whether it is can, or cant testing.
|
192
|
+
2. `role`: the role under which authorisation is performed
|
193
|
+
3. `subtarget`: the object (if passing an object), or string/symbol representing the role
|
194
|
+
4. `operation`: the action
|
195
|
+
5. `target`: targeted object/class of the authorization
|
196
|
+
|
176
197
|
### Rule clause if/unless
|
177
198
|
|
178
199
|
Rule clause may contain `if` and `unless` (decider) proc as already seen before. This `if` and `unless` `proc` have three variants that can be used to express your rule in sufficient detail:
|
@@ -184,7 +205,7 @@ Rule clause may contain `if` and `unless` (decider) proc as already seen before.
|
|
184
205
|
When rule is very brief, use zero-arity rule clause as below:
|
185
206
|
|
186
207
|
```ruby
|
187
|
-
Bali.map_rules do
|
208
|
+
Bali.map_rules do
|
188
209
|
rules_for My::Transaction do
|
189
210
|
describe(:staff) { can :cancel }
|
190
211
|
describe(:finance) { can :cancel }
|
@@ -200,7 +221,7 @@ describe :staff do
|
|
200
221
|
end
|
201
222
|
```
|
202
223
|
|
203
|
-
Good, but, in addition to that, how to allow transaction cancellation only to staff who has 3 years or so experience in working with the company?
|
224
|
+
Good, but, in addition to that, how to allow transaction cancellation only to staff who has 3 years or so experience in working with the company?
|
204
225
|
|
205
226
|
In order to do that, we need to resort to 2-arity decider, as follow:
|
206
227
|
|
@@ -265,4 +286,10 @@ Bali is proudly available as open source under the terms of the [MIT License](ht
|
|
265
286
|
== Version 1.2.0
|
266
287
|
|
267
288
|
1. Passing real object as subtarget's role, instead of symbol or array of symbol
|
268
|
-
2. Clause can also yielding user, along with the object in question
|
289
|
+
2. Clause can also yielding user, along with the object in question
|
290
|
+
|
291
|
+
== Version 2.0.0rc1
|
292
|
+
|
293
|
+
1. `Bali::AuthorizationError` subclass of `StandardError` tailored for raising error regarding with authorisation
|
294
|
+
2. Deprecating `cant`, `cant?`, and `cant_all` in favor of `cannot`, `cannot?` and `cannot_all`
|
295
|
+
3. new objectors `can!` and `cannot!` to raise error on inappropriate access
|
data/lib/bali.rb
CHANGED
@@ -1,21 +1,13 @@
|
|
1
1
|
require_relative "bali/version"
|
2
2
|
|
3
|
-
# foundations, onto which good-purposed gem is developed upon
|
4
|
-
require_relative "bali/foundations/bali_statics"
|
5
|
-
require_relative "bali/foundations/rule_class"
|
6
|
-
require_relative "bali/foundations/rule_group"
|
7
|
-
require_relative "bali/foundations/rule"
|
8
|
-
|
9
3
|
# load the DSL syntax maker definition, ordered by proper order of invocation
|
10
|
-
require_relative "bali/dsl/map_rules_dsl
|
11
|
-
require_relative "bali/dsl/rules_for_dsl
|
4
|
+
require_relative "bali/dsl/map_rules_dsl"
|
5
|
+
require_relative "bali/dsl/rules_for_dsl"
|
12
6
|
|
13
7
|
require_relative "bali/objector"
|
14
8
|
|
15
|
-
|
16
|
-
require_relative "bali/
|
17
|
-
require_relative "bali/exceptions/dsl_error"
|
18
|
-
require_relative "bali/exceptions/objection_error"
|
9
|
+
require_relative "bali/foundations/all_foundations"
|
10
|
+
require_relative "bali/integrators/all_integrators"
|
19
11
|
|
20
12
|
module Bali
|
21
13
|
# mapping class to a RuleClass
|
@@ -32,6 +24,9 @@ module Bali
|
|
32
24
|
# AdminUser: :admin_roles
|
33
25
|
# }
|
34
26
|
TRANSLATED_SUBTARGET_ROLES = {}
|
27
|
+
|
28
|
+
# pub/sub for plugin that extend bali
|
29
|
+
LISTENABLE_EVENTS = {}
|
35
30
|
end
|
36
31
|
|
37
32
|
module Bali
|
@@ -15,7 +15,7 @@ class Bali::MapRulesDsl
|
|
15
15
|
Bali::RulesForDsl.new(self).instance_eval(&block)
|
16
16
|
|
17
17
|
# done processing the block, now add the rule class
|
18
|
-
Bali.add_rule_class(self.current_rule_class)
|
18
|
+
Bali::Integrators::Rule.add_rule_class(self.current_rule_class)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -25,7 +25,7 @@ class Bali::MapRulesDsl
|
|
25
25
|
raise Bali::DslError, "Subtarget must be a class" unless subtarget_class.is_a?(Class)
|
26
26
|
raise Bali::DslError, "Field name must be a symbol/string" if !(field_name.is_a?(Symbol) || field_name.is_a?(String))
|
27
27
|
|
28
|
-
Bali::TRANSLATED_SUBTARGET_ROLES[subtarget_class.to_s] = field_name
|
28
|
+
Bali::TRANSLATED_SUBTARGET_ROLES[subtarget_class.to_s] = field_name
|
29
29
|
nil
|
30
30
|
end
|
31
31
|
|
@@ -38,6 +38,11 @@ class Bali::MapRulesDsl
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def cant(*params)
|
41
|
+
puts "Deprecation Warning: declaring rules with cant will be deprecated on major release 3.0, use cannot instead"
|
42
|
+
cannot *params
|
43
|
+
end
|
44
|
+
|
45
|
+
def cannot(*params)
|
41
46
|
raise Bali::DslError, "cant block must be within describe block"
|
42
47
|
end
|
43
48
|
|
@@ -46,6 +51,11 @@ class Bali::MapRulesDsl
|
|
46
51
|
end
|
47
52
|
|
48
53
|
def cant_all(*params)
|
54
|
+
puts "Deprecation Warning: declaring rules with cant_all will be deprecated on major release 3.0, use cannot instead"
|
55
|
+
cannot_all *params
|
56
|
+
end
|
57
|
+
|
58
|
+
def cannot_all(*params)
|
49
59
|
raise Bali::DslError, "cant_all block must be within describe block"
|
50
60
|
end
|
51
61
|
end
|
@@ -27,7 +27,7 @@ class Bali::RulesForDsl
|
|
27
27
|
subtargets += passed_argument
|
28
28
|
elsif passed_argument.is_a?(Hash)
|
29
29
|
rules = passed_argument
|
30
|
-
else
|
30
|
+
else
|
31
31
|
raise Bali::DslError, "Allowed argument: symbol, string, nil and hash"
|
32
32
|
end
|
33
33
|
end
|
@@ -56,7 +56,7 @@ class Bali::RulesForDsl
|
|
56
56
|
end
|
57
57
|
else
|
58
58
|
operation = operations # well, basically is 1 only
|
59
|
-
rule = Bali::Rule.new(auth_val, operation)
|
59
|
+
rule = Bali::Rule.new(auth_val, operation)
|
60
60
|
self.current_rule_group.add_rule(rule)
|
61
61
|
end
|
62
62
|
end # each rules
|
@@ -71,7 +71,7 @@ class Bali::RulesForDsl
|
|
71
71
|
# to define can and cant is basically using this method
|
72
72
|
def process_auth_rules(auth_val, operations)
|
73
73
|
conditional_hash = nil
|
74
|
-
|
74
|
+
|
75
75
|
# scan operations for options
|
76
76
|
operations.each do |elm|
|
77
77
|
if elm.is_a?(Hash)
|
@@ -103,8 +103,13 @@ class Bali::RulesForDsl
|
|
103
103
|
process_auth_rules(:can, operations)
|
104
104
|
end
|
105
105
|
|
106
|
+
def cannot(*operations)
|
107
|
+
process_auth_rules(:cannot, operations)
|
108
|
+
end
|
109
|
+
|
106
110
|
def cant(*operations)
|
107
|
-
|
111
|
+
puts "Deprecation Warning: declaring rules with cant will be deprecated on major release 3.0, use cannot instead"
|
112
|
+
cannot(*operations)
|
108
113
|
end
|
109
114
|
|
110
115
|
def can_all
|
@@ -112,8 +117,13 @@ class Bali::RulesForDsl
|
|
112
117
|
self.current_rule_group.plant = false
|
113
118
|
end
|
114
119
|
|
115
|
-
def
|
120
|
+
def cannot_all
|
116
121
|
self.current_rule_group.plant = true
|
117
122
|
self.current_rule_group.zeus = false
|
118
123
|
end
|
124
|
+
|
125
|
+
def cant_all
|
126
|
+
puts "Deprecation Warning: declaring rules with cant_all will be deprecated on major release 3.0, use cannot_all instead"
|
127
|
+
cannot_all
|
128
|
+
end
|
119
129
|
end # class
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# ./exceptions
|
2
|
+
require_relative "exceptions/bali_error"
|
3
|
+
require_relative "exceptions/dsl_error"
|
4
|
+
require_relative "exceptions/objection_error"
|
5
|
+
require_relative "exceptions/authorization_error"
|
6
|
+
|
7
|
+
# rule
|
8
|
+
require_relative "rule/rule"
|
9
|
+
require_relative "rule/rule_class"
|
10
|
+
require_relative "rule/rule_group"
|
11
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Error that will be raised when subtarget cannot do something he wanted to do,
|
2
|
+
# or when subtarget do something he should not be allowed to do.
|
3
|
+
class Bali::AuthorizationError < Bali::Error
|
4
|
+
attr_accessor :operation
|
5
|
+
attr_accessor :auth_level
|
6
|
+
attr_accessor :role
|
7
|
+
|
8
|
+
# it may be nil, depends on whether rule checking is using symbol/user
|
9
|
+
attr_accessor :subtarget
|
10
|
+
|
11
|
+
# whether a class or an object
|
12
|
+
attr_accessor :target
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"Role #{role} is performing #{operation} using precedence #{auth_level}"
|
16
|
+
end
|
17
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# for internal use, representing one, single, atomic rule
|
2
2
|
class Bali::Rule
|
3
|
-
# auth_val is either :can or :
|
3
|
+
# auth_val is either :can or :cannot
|
4
4
|
attr_reader :auth_val
|
5
5
|
|
6
6
|
# what is the operation: create, update, delete, or any other
|
@@ -18,10 +18,13 @@ class Bali::Rule
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def auth_val=(aval)
|
21
|
-
|
21
|
+
# TODO: in version 3 remove :cant
|
22
|
+
if aval == :can || aval == :cannot
|
22
23
|
@auth_val = aval
|
24
|
+
elsif aval == :cant
|
25
|
+
@auth_val = :cannot
|
23
26
|
else
|
24
|
-
raise Bali::DslError, "auth_val can only either be :can or :
|
27
|
+
raise Bali::DslError, "auth_val can only either be :can or :cannot"
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
@@ -34,7 +37,8 @@ class Bali::Rule
|
|
34
37
|
end
|
35
38
|
|
36
39
|
def is_discouragement?
|
37
|
-
|
40
|
+
# TODO: in version 3.0 remove :cant
|
41
|
+
self.auth_val == :cannot || self.auth_val == :cant
|
38
42
|
end
|
39
43
|
|
40
44
|
def has_decider?
|
File without changes
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Bali
|
1
|
+
module Bali::Integrators::Rule
|
2
2
|
extend self
|
3
3
|
|
4
4
|
def rule_classes
|
@@ -18,7 +18,7 @@ module Bali
|
|
18
18
|
|
19
19
|
# attempt to search the rule group, but if not exist, will return nil
|
20
20
|
def rule_group_for(target_class, subtarget)
|
21
|
-
rule_class =
|
21
|
+
rule_class = rule_class_for(target_class)
|
22
22
|
if rule_class
|
23
23
|
rule_group = rule_class.rules_for(subtarget)
|
24
24
|
return rule_group
|
@@ -35,7 +35,7 @@ module Bali
|
|
35
35
|
raise Bali::DslError, "Target must be a class" unless target.is_a?(Class)
|
36
36
|
|
37
37
|
# remove any previous association of rule
|
38
|
-
begin
|
38
|
+
begin
|
39
39
|
last_associated_alias = Bali::REVERSE_ALIASED_RULE_CLASS_MAP[target]
|
40
40
|
if last_associated_alias
|
41
41
|
Bali::ALIASED_RULE_CLASS_MAP.delete(last_associated_alias)
|
data/lib/bali/objector.rb
CHANGED
@@ -5,19 +5,45 @@ module Bali::Objector
|
|
5
5
|
base.extend Bali::Objector::Statics
|
6
6
|
end
|
7
7
|
|
8
|
-
|
8
|
+
# check whether user can/cant perform an operation, return true when positive
|
9
|
+
# or false otherwise
|
10
|
+
def can?(subtargets, operation)
|
9
11
|
self.class.can?(subtargets, operation, self)
|
10
12
|
end
|
11
13
|
|
14
|
+
# check whether user can/cant perform an operation, raise an error when access
|
15
|
+
# is denied
|
16
|
+
def can!(subtargets, operation)
|
17
|
+
self.class.can!(subtargets, operation, self)
|
18
|
+
end
|
19
|
+
|
20
|
+
# check whether user can/cant perform an operation, return true when negative
|
21
|
+
# or false otherwise
|
22
|
+
def cannot?(subtargets, operation)
|
23
|
+
self.class.cannot?(subtargets, operation, self)
|
24
|
+
end
|
25
|
+
|
26
|
+
# check whether user can/cant perform an operation, raise an error when access
|
27
|
+
# is given
|
28
|
+
def cannot!(subtargets, operation)
|
29
|
+
self.class.cannot!(subtargets, operation, self)
|
30
|
+
end
|
31
|
+
|
12
32
|
def cant?(subtargets, operation)
|
13
|
-
|
33
|
+
puts "Deprecation Warning: please use cannot? instead, cant? will be deprecated on major release 3.0"
|
34
|
+
cannot?(subtargets, operation)
|
35
|
+
end
|
36
|
+
|
37
|
+
def cant!(subtargets, operation)
|
38
|
+
puts "Deprecation Warning: please use cannot! instead, cant! will be deprecated on major release 3.0"
|
39
|
+
cannot!(subtargets, operation)
|
14
40
|
end
|
15
41
|
end
|
16
42
|
|
17
43
|
module Bali::Objector::Statics
|
18
44
|
|
19
45
|
# will return array
|
20
|
-
def
|
46
|
+
def bali_translate_subtarget_roles(_subtarget_roles)
|
21
47
|
if _subtarget_roles.is_a?(String) || _subtarget_roles.is_a?(Symbol) || _subtarget_roles.is_a?(NilClass)
|
22
48
|
return [_subtarget_roles]
|
23
49
|
elsif _subtarget_roles.is_a?(Array)
|
@@ -28,7 +54,7 @@ module Bali::Objector::Statics
|
|
28
54
|
|
29
55
|
_subtarget = _subtarget_roles
|
30
56
|
_subtarget_class = _subtarget.class.to_s
|
31
|
-
|
57
|
+
|
32
58
|
# variable to hold deducted role of the passed object
|
33
59
|
deducted_roles = nil
|
34
60
|
|
@@ -51,19 +77,19 @@ module Bali::Objector::Statics
|
|
51
77
|
end # if
|
52
78
|
end
|
53
79
|
|
54
|
-
### options passable to
|
80
|
+
### options passable to bali_can? and bali_cannot? are:
|
55
81
|
### cross_action: if set to true wouldn't call its counterpart so as to prevent
|
56
82
|
### overflowing stack
|
57
|
-
### original_subtarget: the original passed to can? and
|
58
|
-
### processed by
|
83
|
+
### original_subtarget: the original passed to can? and cannot? before
|
84
|
+
### processed by bali_translate_subtarget_roles
|
59
85
|
|
60
|
-
def
|
86
|
+
def bali_can?(subtarget, operation, record = self, options = {})
|
61
87
|
# if performed on a class-level, don't call its class or it will return
|
62
88
|
# Class. That's not what is expected.
|
63
89
|
if self.is_a?(Class)
|
64
|
-
rule_group = Bali.rule_group_for(self, subtarget)
|
90
|
+
rule_group = Bali::Integrators::Rule.rule_group_for(self, subtarget)
|
65
91
|
else
|
66
|
-
rule_group = Bali.rule_group_for(self.class, subtarget)
|
92
|
+
rule_group = Bali::Integrators::Rule.rule_group_for(self.class, subtarget)
|
67
93
|
end
|
68
94
|
|
69
95
|
# default of can? is false whenever RuleClass for that class is undefined
|
@@ -82,20 +108,20 @@ module Bali::Objector::Statics
|
|
82
108
|
if rule_group.zeus?
|
83
109
|
if rule.nil?
|
84
110
|
# check further whether cant is defined to overwrite this can_all
|
85
|
-
if self.
|
111
|
+
if self.cannot?(subtarget, operation, record, cross_check: true)
|
86
112
|
return false
|
87
113
|
else
|
88
114
|
return true
|
89
115
|
end
|
90
116
|
end
|
91
117
|
end
|
92
|
-
|
118
|
+
|
93
119
|
if rule.nil?
|
94
120
|
# default if can? for undefined rule is false, after related clause
|
95
|
-
# cannot be found in
|
121
|
+
# cannot be found in cannot?
|
96
122
|
return false if options[:cross_check]
|
97
123
|
options[:cross_check] = true
|
98
|
-
return !self.
|
124
|
+
return !self.cannot?(subtarget, operation, record, options)
|
99
125
|
else
|
100
126
|
if rule.has_decider?
|
101
127
|
# must test first
|
@@ -105,43 +131,43 @@ module Bali::Objector::Statics
|
|
105
131
|
when 0
|
106
132
|
if rule.decider_type == :if
|
107
133
|
if decider.()
|
108
|
-
return true
|
109
|
-
else
|
134
|
+
return true
|
135
|
+
else
|
110
136
|
return false
|
111
137
|
end
|
112
138
|
elsif rule.decider_type == :unless
|
113
139
|
unless decider.()
|
114
|
-
return true
|
115
|
-
else
|
116
|
-
return false
|
140
|
+
return true
|
141
|
+
else
|
142
|
+
return false
|
117
143
|
end
|
118
144
|
end
|
119
145
|
when 1
|
120
146
|
if rule.decider_type == :if
|
121
147
|
if decider.(record)
|
122
|
-
return true
|
123
|
-
else
|
148
|
+
return true
|
149
|
+
else
|
124
150
|
return false
|
125
151
|
end
|
126
152
|
elsif rule.decider_type == :unless
|
127
153
|
unless decider.(record)
|
128
|
-
return true
|
129
|
-
else
|
130
|
-
return false
|
154
|
+
return true
|
155
|
+
else
|
156
|
+
return false
|
131
157
|
end
|
132
158
|
end
|
133
159
|
when 2
|
134
160
|
if rule.decider_type == :if
|
135
161
|
if decider.(record, original_subtarget)
|
136
|
-
return true
|
137
|
-
else
|
162
|
+
return true
|
163
|
+
else
|
138
164
|
return false
|
139
165
|
end
|
140
166
|
elsif rule.decider_type == :unless
|
141
167
|
unless decider.(record, original_subtarget)
|
142
|
-
return true
|
143
|
-
else
|
144
|
-
return false
|
168
|
+
return true
|
169
|
+
else
|
170
|
+
return false
|
145
171
|
end
|
146
172
|
end
|
147
173
|
end
|
@@ -152,18 +178,18 @@ module Bali::Objector::Statics
|
|
152
178
|
end
|
153
179
|
end
|
154
180
|
|
155
|
-
def
|
181
|
+
def bali_cannot?(subtarget, operation, record = self, options = {})
|
156
182
|
if self.is_a?(Class)
|
157
|
-
rule_group = Bali.rule_group_for(self, subtarget)
|
183
|
+
rule_group = Bali::Integrators::Rule.rule_group_for(self, subtarget)
|
158
184
|
else
|
159
|
-
rule_group = Bali.rule_group_for(self.class, subtarget)
|
185
|
+
rule_group = Bali::Integrators::Rule.rule_group_for(self.class, subtarget)
|
160
186
|
end
|
161
187
|
|
162
|
-
# default of
|
188
|
+
# default of cannot? is true whenever RuleClass for that class is undefined
|
163
189
|
# or RuleGroup for that subtarget is not defined
|
164
190
|
return true if rule_group.nil?
|
165
191
|
|
166
|
-
rule = rule_group.get_rule(:
|
192
|
+
rule = rule_group.get_rule(:cannot, operation)
|
167
193
|
|
168
194
|
# godly subtarget is not to be prohibited in his endeavours
|
169
195
|
# so long that no specific rule about this operation is defined
|
@@ -183,7 +209,7 @@ module Bali::Objector::Statics
|
|
183
209
|
end
|
184
210
|
end
|
185
211
|
|
186
|
-
# if rule cannot be found, then true is returned for
|
212
|
+
# if rule cannot be found, then true is returned for cannot? unless
|
187
213
|
# can? is defined exactly for the same target, and subtarget, and record (if given)
|
188
214
|
if rule.nil?
|
189
215
|
return true if options[:cross_check]
|
@@ -197,43 +223,43 @@ module Bali::Objector::Statics
|
|
197
223
|
when 0
|
198
224
|
if rule.decider_type == :if
|
199
225
|
if decider.()
|
200
|
-
return true
|
201
|
-
else
|
226
|
+
return true
|
227
|
+
else
|
202
228
|
return false
|
203
229
|
end
|
204
230
|
elsif rule.decider_type == :unless
|
205
231
|
unless decider.()
|
206
|
-
return true
|
207
|
-
else
|
208
|
-
return false
|
232
|
+
return true
|
233
|
+
else
|
234
|
+
return false
|
209
235
|
end
|
210
236
|
end
|
211
237
|
when 1
|
212
238
|
if rule.decider_type == :if
|
213
239
|
if decider.(record)
|
214
|
-
return true
|
215
|
-
else
|
240
|
+
return true
|
241
|
+
else
|
216
242
|
return false
|
217
243
|
end
|
218
244
|
elsif rule.decider_type == :unless
|
219
245
|
unless decider.(record)
|
220
|
-
return true
|
221
|
-
else
|
222
|
-
return false
|
246
|
+
return true
|
247
|
+
else
|
248
|
+
return false
|
223
249
|
end
|
224
250
|
end
|
225
251
|
when 2
|
226
252
|
if rule.decider_type == :if
|
227
253
|
if decider.(record, original_subtarget)
|
228
|
-
return true
|
229
|
-
else
|
254
|
+
return true
|
255
|
+
else
|
230
256
|
return false
|
231
257
|
end
|
232
258
|
elsif rule.decider_type == :unless
|
233
259
|
unless decider.(record, original_subtarget)
|
234
|
-
return true
|
235
|
-
else
|
236
|
-
return false
|
260
|
+
return true
|
261
|
+
else
|
262
|
+
return false
|
237
263
|
end
|
238
264
|
end
|
239
265
|
end
|
@@ -244,29 +270,99 @@ module Bali::Objector::Statics
|
|
244
270
|
end
|
245
271
|
|
246
272
|
def can?(subtarget_roles, operation, record = self, options = {})
|
247
|
-
subs =
|
273
|
+
subs = bali_translate_subtarget_roles(subtarget_roles)
|
248
274
|
# well, it is largely not used unless decider's is 2 arity
|
249
275
|
options[:original_subtarget] = options[:original_subtarget].nil? ? subtarget_roles : options[:original_subtarget]
|
250
276
|
|
277
|
+
can_value = false
|
278
|
+
role = nil
|
279
|
+
|
251
280
|
subs.each do |subtarget|
|
252
|
-
|
253
|
-
|
281
|
+
next if can_value
|
282
|
+
role = subtarget
|
283
|
+
can_value = bali_can?(role, operation, record, options)
|
254
284
|
end
|
255
|
-
|
285
|
+
|
286
|
+
yield options[:original_subtarget], role, can_value if can_value == false && block_given?
|
287
|
+
can_value
|
256
288
|
rescue => e
|
257
|
-
|
289
|
+
if e.is_a?(Bali::AuthorizationError)
|
290
|
+
raise e
|
291
|
+
else
|
292
|
+
raise Bali::ObjectionError, e.message
|
293
|
+
end
|
258
294
|
end
|
259
295
|
|
260
296
|
def cant?(subtarget_roles, operation, record = self, options = {})
|
261
|
-
|
297
|
+
puts "Deprecation Warning: please use cannot? instead, cant? will be deprecated on major release 3.0"
|
298
|
+
cannot?(subtarget_roles, operation, record, options)
|
299
|
+
end
|
300
|
+
|
301
|
+
def cannot?(subtarget_roles, operation, record = self, options = {})
|
302
|
+
subs = bali_translate_subtarget_roles subtarget_roles
|
262
303
|
options[:original_subtarget] = options[:original_subtarget].nil? ? subtarget_roles : options[:original_subtarget]
|
263
304
|
|
264
305
|
subs.each do |subtarget|
|
265
|
-
cant_value =
|
266
|
-
|
306
|
+
cant_value = bali_cannot?(subtarget, operation, record, options)
|
307
|
+
if cant_value == false
|
308
|
+
role = subtarget
|
309
|
+
if block_given?
|
310
|
+
yield options[:original_subtarget], role, false
|
311
|
+
else
|
312
|
+
return false
|
313
|
+
end
|
314
|
+
end
|
267
315
|
end
|
316
|
+
|
268
317
|
true
|
269
|
-
rescue => e
|
270
|
-
|
318
|
+
rescue => e
|
319
|
+
if e.is_a?(Bali::AuthorizationError)
|
320
|
+
raise e
|
321
|
+
else
|
322
|
+
raise Bali::ObjectionError, e.message
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def can!(subtarget_roles, operation, record = self, options = {})
|
327
|
+
can?(subtarget_roles, operation, record, options) do |original_subtarget, role, can_value|
|
328
|
+
if !can_value
|
329
|
+
auth_error = Bali::AuthorizationError.new
|
330
|
+
auth_error.auth_level = :can
|
331
|
+
auth_error.operation = operation
|
332
|
+
auth_error.role = role
|
333
|
+
auth_error.target = record
|
334
|
+
auth_error.subtarget = original_subtarget
|
335
|
+
|
336
|
+
if role
|
337
|
+
auth_error.subtarget = original_subtarget if !(original_subtarget.is_a?(Symbol) || original_subtarget.is_a?(String) || original_subtarget.is_a?(Array))
|
338
|
+
end
|
339
|
+
|
340
|
+
raise auth_error
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def cant!(subtarget_roles, operation, record = self, options = {})
|
346
|
+
puts "Deprecation Warning: please use cannot! instead, cant! will be deprecated on major release 3.0"
|
347
|
+
cannot!(subtarget_roles, operation, record, options)
|
348
|
+
end
|
349
|
+
|
350
|
+
def cannot!(subtarget_roles, operation, record = self, options = {})
|
351
|
+
cannot?(subtarget_roles, operation, record, options) do |original_subtarget, role, cant_value|
|
352
|
+
if cant_value == false
|
353
|
+
auth_error = Bali::AuthorizationError.new
|
354
|
+
auth_error.auth_level = :cannot
|
355
|
+
auth_error.operation = operation
|
356
|
+
auth_error.role = role
|
357
|
+
auth_error.target = record
|
358
|
+
auth_error.subtarget = original_subtarget
|
359
|
+
|
360
|
+
if role
|
361
|
+
auth_error.subtarget = original_subtarget if !(original_subtarget.is_a?(Symbol) || original_subtarget.is_a?(String) || original_subtarget.is_a?(Array))
|
362
|
+
end
|
363
|
+
|
364
|
+
raise auth_error
|
365
|
+
end
|
366
|
+
end
|
271
367
|
end
|
272
368
|
end
|
data/lib/bali/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bali
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Pahlevi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -75,13 +75,16 @@ files:
|
|
75
75
|
- lib/bali.rb
|
76
76
|
- lib/bali/dsl/map_rules_dsl.rb
|
77
77
|
- lib/bali/dsl/rules_for_dsl.rb
|
78
|
-
- lib/bali/
|
79
|
-
- lib/bali/exceptions/
|
80
|
-
- lib/bali/exceptions/
|
81
|
-
- lib/bali/foundations/
|
82
|
-
- lib/bali/foundations/
|
83
|
-
- lib/bali/foundations/
|
84
|
-
- lib/bali/foundations/
|
78
|
+
- lib/bali/foundations/all_foundations.rb
|
79
|
+
- lib/bali/foundations/exceptions/authorization_error.rb
|
80
|
+
- lib/bali/foundations/exceptions/bali_error.rb
|
81
|
+
- lib/bali/foundations/exceptions/dsl_error.rb
|
82
|
+
- lib/bali/foundations/exceptions/objection_error.rb
|
83
|
+
- lib/bali/foundations/rule/rule.rb
|
84
|
+
- lib/bali/foundations/rule/rule_class.rb
|
85
|
+
- lib/bali/foundations/rule/rule_group.rb
|
86
|
+
- lib/bali/integrators/all_integrators.rb
|
87
|
+
- lib/bali/integrators/rules_integrator.rb
|
85
88
|
- lib/bali/objector.rb
|
86
89
|
- lib/bali/version.rb
|
87
90
|
homepage: https://github.com/saveav/bali
|
@@ -99,9 +102,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
102
|
version: '0'
|
100
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
104
|
requirements:
|
102
|
-
- - "
|
105
|
+
- - ">"
|
103
106
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
107
|
+
version: 1.3.1
|
105
108
|
requirements: []
|
106
109
|
rubyforge_project:
|
107
110
|
rubygems_version: 2.4.5
|