bali 1.1.0rc1 → 1.1.0rc2
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 +55 -14
- data/lib/bali/dsl/map_rules_dsl.rb +4 -0
- data/lib/bali/dsl/rules_for_dsl.rb +53 -28
- data/lib/bali/foundations/rule_group.rb +2 -0
- data/lib/bali/objector.rb +32 -7
- data/lib/bali/version.rb +1 -1
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd5c0fb2638885502b2fdb39ecaba159b90dac24
|
4
|
+
data.tar.gz: 2d6308b4df6d3d363bed7d2ce4b72ec9b7368e57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f675d90ac77a7558ce6cb545a3dbf3aa5c05bf6856df44b50331b34ed3c786200453efa371c13ac13b3b3eaef7d38a9b1d3d8ee05cfadb473246a0982e9224e
|
7
|
+
data.tar.gz: 33919e7f7c83e50aee8afb59704bef97f902d257099f3af799a947ab955353b4144f7df3243623dee88d9d3f37ba298216b65313ae1638ad5a6a513f7649fc78
|
data/README.md
CHANGED
@@ -24,9 +24,9 @@ And then execute:
|
|
24
24
|
|
25
25
|
## Usage
|
26
26
|
|
27
|
-
###
|
27
|
+
### Defining access rules
|
28
28
|
|
29
|
-
Rule in Bali is the law determining whether a user (called `subtarget`) can do or perform specific operation on a target (which is your resource/model).
|
29
|
+
Rule in Bali is the law determining whether a user (called `subtarget`) can do or perform a specific operation on a target (which is your resource/model).
|
30
30
|
|
31
31
|
```ruby
|
32
32
|
Bali.map_rules do
|
@@ -53,7 +53,20 @@ Rule in Bali is the law determining whether a user (called `subtarget`) can do o
|
|
53
53
|
|
54
54
|
You may or may not assign an alias name (`as`). Make sure to keep it unique had you decided to give alias name to your rules group.
|
55
55
|
|
56
|
-
|
56
|
+
It is also possible for a rule to be defined for multiple subtarget at once:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
Bali.map_rules do
|
60
|
+
rules_for My::Transaction do
|
61
|
+
# rules described bellow will affect both :general_user and :finance_user
|
62
|
+
describe :general_user, :finance_user do
|
63
|
+
can :update, :edit
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
### Can and Cant? testing
|
57
70
|
|
58
71
|
Say:
|
59
72
|
|
@@ -105,30 +118,54 @@ My::Employee.can?(:undefined_subtarget, :new) # => false, rule class for this i
|
|
105
118
|
|
106
119
|
As we have never define the `rules_for` My::Employee before, any attempt to `can?` for `My::Employee` will return `false`, so does any attempt to object `cant?` on which will only return `true` for any given subtarget and operation.
|
107
120
|
|
121
|
+
### Can and Cant testing with multiple-roles subtarget
|
122
|
+
|
123
|
+
A subtarget may have multiple roles. For eg., a user may have a role of `finance_user` and `general_user`. A general user normally by itself cannot `delete`, or `cancel`; but a `finance_user` does can, so long the condition is met. But, if a subtarget has role of both `finance_user` and `general_user`, he/she can perform `delete` or `cancel` (so far that the condition is met.)
|
124
|
+
|
125
|
+
Thus, if we have:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
txn = My::Transaction.new
|
129
|
+
txn.process_transaction(from_user_input)
|
130
|
+
|
131
|
+
# delete or cancel can only happen when a transaction is settled
|
132
|
+
# as per rule definition
|
133
|
+
txn.is_settled = true
|
134
|
+
txn.save
|
135
|
+
|
136
|
+
subtarget = User.new
|
137
|
+
subtarget.roles = [:finance_user, :general_user]
|
138
|
+
|
139
|
+
txn.can?(subtarget.roles, :delete) # => true
|
140
|
+
txn.cant?(subtarget.roles, :delete) # => false
|
141
|
+
txn.can?(:general_user, :delete) # => false
|
142
|
+
```
|
143
|
+
|
144
|
+
That is, we can check `can?` and `cant?` with multiple roles by passing array of roles to it.
|
145
|
+
|
108
146
|
## Contributing
|
109
147
|
|
110
148
|
Bug reports and pull requests are welcome on GitHub at https://github.com/saveav/bali. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
111
149
|
|
112
|
-
|
113
150
|
## License
|
114
151
|
|
115
152
|
Bali is proudly available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
116
153
|
|
117
|
-
|
154
|
+
## Changelog
|
118
155
|
|
119
|
-
|
156
|
+
### Version 1.0.0beta1
|
120
157
|
1. Initial version
|
121
158
|
|
122
|
-
|
159
|
+
### Version 1.0.0rc1
|
123
160
|
1. Fix bug where user can't check on class
|
124
161
|
2. Adding new clause: cant_all
|
125
162
|
|
126
|
-
|
163
|
+
### Version 1.0.0rc2
|
127
164
|
1. [Fix bug when class's name, as a constant, is reloaded](http://stackoverflow.com/questions/2509350/rails-class-object-id-changes-after-i-make-a-request) (re-allocated to different address in the memory)
|
128
165
|
2. Allow describing rule for `nil`, useful if user is not authenticated thus role is probably `nil`
|
129
166
|
3. Remove pry from development dependency
|
130
167
|
|
131
|
-
|
168
|
+
### Version 1.0.0rc3
|
132
169
|
1. Each target class should includes `Bali::Objector`, for the following reasons:
|
133
170
|
- Makes it clear that class do want to include the Bali::Objector
|
134
171
|
- Transparant, and thus less confusing as to where "can?" and "cant" come from
|
@@ -136,11 +173,15 @@ Bali is proudly available as open source under the terms of the [MIT License](ht
|
|
136
173
|
2. Return `true` to any `can?` for undefined target/subtarget alike
|
137
174
|
3. Return `false` to any `cant?` for undefined target/subtarget alike
|
138
175
|
|
139
|
-
|
176
|
+
### Version 1.0.0
|
140
177
|
1. Released the stable version of this gem
|
141
178
|
|
142
|
-
|
143
|
-
1. Ability for rule class to be parsed later by
|
144
|
-
2. Add `Bali.parse` and `Bali.parse!` (Bali.parse
|
179
|
+
### Version 1.1.0rc1
|
180
|
+
1. Ability for rule class to be parsed later by passing `later: true` to rule class definition
|
181
|
+
2. Add `Bali.parse` and `Bali.parse!` (`Bali.parse!` executes "later"-tagged rule class, Bali.parse executes automatically after all rules are defined)
|
145
182
|
3. Added more thorough testing specs
|
146
|
-
4. Proc can be served under `unless` for defining the rule's decider
|
183
|
+
4. Proc can be served under `unless` for defining the rule's decider
|
184
|
+
|
185
|
+
### Version 1.1.0rc2
|
186
|
+
1. Ability to check `can?` and `cant?` for subtarget with multiple roles
|
187
|
+
2. Describe multiple rules at once for multiple subtarget
|
@@ -9,38 +9,63 @@ class Bali::RulesForDsl
|
|
9
9
|
self.map_rules_dsl = map_rules_dsl
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
12
|
+
def current_rule_class
|
13
|
+
self.map_rules_dsl.current_rule_class
|
14
|
+
end
|
15
|
+
|
16
|
+
def describe(*params)
|
17
|
+
|
18
|
+
subtargets = []
|
19
|
+
rules = {}
|
20
|
+
|
21
|
+
params.each do |passed_argument|
|
22
|
+
if passed_argument.is_a?(Symbol) || passed_argument.is_a?(String)
|
23
|
+
subtargets << passed_argument
|
24
|
+
elsif passed_argument.is_a?(NilClass)
|
25
|
+
subtargets << passed_argument
|
26
|
+
elsif passed_argument.is_a?(Array)
|
27
|
+
subtargets += passed_argument
|
28
|
+
elsif passed_argument.is_a?(Hash)
|
29
|
+
rules = passed_argument
|
30
|
+
else
|
31
|
+
raise Bali::DslError, "Allowed argument: symbol, string, nil and hash"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
13
35
|
target_class = self.map_rules_dsl.current_rule_class.target_class
|
14
36
|
target_alias = self.map_rules_dsl.current_rule_class.alias_name
|
15
37
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
38
|
+
subtargets.each do |subtarget|
|
39
|
+
@@lock.synchronize do
|
40
|
+
rule_group = self.current_rule_class.rules_for(subtarget)
|
41
|
+
if rule_group.nil?
|
42
|
+
rule_group = Bali::RuleGroup.new(target_class, target_alias, subtarget)
|
43
|
+
end
|
44
|
+
|
45
|
+
self.current_rule_group = rule_group
|
46
|
+
|
47
|
+
if block_given?
|
48
|
+
yield
|
49
|
+
else
|
50
|
+
# auth_val is either can or cant
|
51
|
+
rules.each do |auth_val, operations|
|
52
|
+
if operations.is_a?(Array)
|
53
|
+
operations.each do |op|
|
54
|
+
rule = Bali::Rule.new(auth_val, op)
|
55
|
+
self.current_rule_group.add_rule(rule)
|
56
|
+
end
|
57
|
+
else
|
58
|
+
operation = operations # well, basically is 1 only
|
59
|
+
rule = Bali::Rule.new(auth_val, operation)
|
60
|
+
self.current_rule_group.add_rule(rule)
|
32
61
|
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
# add current_rule_group
|
42
|
-
self.map_rules_dsl.current_rule_class.add_rule_group(rule_group)
|
43
|
-
end # mutex synchronize
|
62
|
+
end # each rules
|
63
|
+
end # block_given?
|
64
|
+
|
65
|
+
# add current_rule_group
|
66
|
+
self.map_rules_dsl.current_rule_class.add_rule_group(self.current_rule_group)
|
67
|
+
end # mutex synchronize
|
68
|
+
end # each subtarget
|
44
69
|
end # describe
|
45
70
|
|
46
71
|
# to define can and cant is basically using this method
|
data/lib/bali/objector.rb
CHANGED
@@ -5,17 +5,23 @@ module Bali::Objector
|
|
5
5
|
base.extend Bali::Objector::Statics
|
6
6
|
end
|
7
7
|
|
8
|
-
def can?(
|
9
|
-
self.class.can?(
|
8
|
+
def can?(subtargets, operation)
|
9
|
+
self.class.can?(subtargets, operation, self)
|
10
10
|
end
|
11
11
|
|
12
|
-
def cant?(
|
13
|
-
self.class.cant?(
|
12
|
+
def cant?(subtargets, operation)
|
13
|
+
self.class.cant?(subtargets, operation, self)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
module Bali::Objector::Statics
|
18
|
-
|
18
|
+
|
19
|
+
### options passable to __can__? and __cant__? are:
|
20
|
+
### cross_action: if set to true wouldn't call its counterpart so as to prevent
|
21
|
+
### overflowing stack
|
22
|
+
###
|
23
|
+
|
24
|
+
def __can__?(subtarget, operation, record = self, options = {})
|
19
25
|
# if performed on a class-level, don't call its class or it will return
|
20
26
|
# Class. That's not what is expected.
|
21
27
|
if self.is_a?(Class)
|
@@ -67,10 +73,9 @@ module Bali::Objector::Statics
|
|
67
73
|
return true
|
68
74
|
end
|
69
75
|
end
|
70
|
-
|
71
76
|
end
|
72
77
|
|
73
|
-
def
|
78
|
+
def __cant__?(subtarget, operation, record = self, options = {})
|
74
79
|
if self.is_a?(Class)
|
75
80
|
rule_group = Bali.rule_group_for(self, subtarget)
|
76
81
|
else
|
@@ -119,4 +124,24 @@ module Bali::Objector::Statics
|
|
119
124
|
end # if rule has decider
|
120
125
|
end # if rule is nil
|
121
126
|
end
|
127
|
+
|
128
|
+
def can?(subtargets, operation, record = self, options = {})
|
129
|
+
subs = (subtargets.is_a?(Array)) ? subtargets : [subtargets]
|
130
|
+
|
131
|
+
subs.each do |subtarget|
|
132
|
+
can_value = __can__?(subtarget, operation, record, options)
|
133
|
+
return true if can_value == true
|
134
|
+
end
|
135
|
+
false
|
136
|
+
end
|
137
|
+
|
138
|
+
def cant?(subtargets, operation, record = self, options = {})
|
139
|
+
subs = (subtargets.is_a?(Array)) ? subtargets : [subtargets]
|
140
|
+
|
141
|
+
subs.each do |subtarget|
|
142
|
+
cant_value = __cant__?(subtarget, operation, record, options)
|
143
|
+
return false if cant_value == false
|
144
|
+
end
|
145
|
+
true
|
146
|
+
end
|
122
147
|
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: 1.1.
|
4
|
+
version: 1.1.0rc2
|
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-
|
11
|
+
date: 2015-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.3'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: pry
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
55
|
description: "Bali (Bulwark Authorization Library) is a universal authorization library,
|
70
56
|
in the sense that \n it does not assume you to use specific
|
71
57
|
Ruby library/gem/framework."
|