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 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