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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bfdb9274e88935206ba786522f65dba0cb1ddfb4
4
- data.tar.gz: f3dc6a29a69a526540bfd1fab705acdade594773
3
+ metadata.gz: cf53e89889a8f3f41843b1e46cb4da90c0d76121
4
+ data.tar.gz: 6fc380eb95bb66723ae74851a796ead78b1f44bd
5
5
  SHA512:
6
- metadata.gz: 4801d9b6dc47bd70b75689663485487533c82d1de7ae2cb37c8657972837f5894d03cc7598fad9f87adea0312672ccd81ce00458012ae7aa157d95895bba17a0
7
- data.tar.gz: 1a0597385c6bded708cba7d9bac719921706465df49d9a29b445910e086859e3da5b0b9e123da4ce38d63d11b1c3dae033854ca76c539d5b57077da57243c709
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.rb"
11
- require_relative "bali/dsl/rules_for_dsl.rb"
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
- # exception classes
16
- require_relative "bali/exceptions/bali_error"
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
- process_auth_rules(:cant, operations)
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 cant_all
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
@@ -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 :cant
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
- if aval == :can || aval == :cant
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 :cant"
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
- self.auth_val == :cant
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?
@@ -59,7 +59,7 @@ class Bali::RuleGroup
59
59
  case auth_val
60
60
  when :can, "can"
61
61
  rule = self.cans[operation.to_sym]
62
- when :cant, "cant"
62
+ when :cannot, "cannot"
63
63
  rule = self.cants[operation.to_sym]
64
64
  else
65
65
  raise Bali::DslError, "Undefined operation: #{auth_val}"
@@ -0,0 +1,4 @@
1
+ module Bali::Integrators
2
+ end
3
+
4
+ require_relative "rules_integrator"
@@ -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 = Bali.rule_class_for(target_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
- def can?(subtargets, operation)
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
- self.class.cant?(subtargets, operation, self)
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 __translate_subtarget_roles__(_subtarget_roles)
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 __can__? and __cant__? are:
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 cant? before
58
- ### processed by __translate_subtarget_roles__
83
+ ### original_subtarget: the original passed to can? and cannot? before
84
+ ### processed by bali_translate_subtarget_roles
59
85
 
60
- def __can__?(subtarget, operation, record = self, options = {})
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.cant?(subtarget, operation, record, cross_check: true)
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 cant?
121
+ # cannot be found in cannot?
96
122
  return false if options[:cross_check]
97
123
  options[:cross_check] = true
98
- return !self.cant?(subtarget, operation, record, options)
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 __cant__?(subtarget, operation, record = self, options = {})
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 cant? is true whenever RuleClass for that class is undefined
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(:cant, operation)
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 cant? unless
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 = __translate_subtarget_roles__(subtarget_roles)
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
- can_value = __can__?(subtarget, operation, record, options)
253
- return true if can_value == true
281
+ next if can_value
282
+ role = subtarget
283
+ can_value = bali_can?(role, operation, record, options)
254
284
  end
255
- false
285
+
286
+ yield options[:original_subtarget], role, can_value if can_value == false && block_given?
287
+ can_value
256
288
  rescue => e
257
- raise Bali::ObjectionError, e.message
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
- subs = __translate_subtarget_roles__ subtarget_roles
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 = __cant__?(subtarget, operation, record, options)
266
- return false if cant_value == false
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
- raise Bali::ObjectionError, e.message
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
@@ -1,3 +1,3 @@
1
1
  module Bali
2
- VERSION = "1.2.0"
2
+ VERSION = "2.0.0rc1"
3
3
  end
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: 1.2.0
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-08-25 00:00:00.000000000 Z
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/exceptions/bali_error.rb
79
- - lib/bali/exceptions/dsl_error.rb
80
- - lib/bali/exceptions/objection_error.rb
81
- - lib/bali/foundations/bali_statics.rb
82
- - lib/bali/foundations/rule.rb
83
- - lib/bali/foundations/rule_class.rb
84
- - lib/bali/foundations/rule_group.rb
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: '0'
107
+ version: 1.3.1
105
108
  requirements: []
106
109
  rubyforge_project:
107
110
  rubygems_version: 2.4.5