bali 1.2.0 → 2.0.0rc1
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 +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
|