bali 6.0.0rc1 → 6.0.0rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/bali.rb +4 -11
- data/lib/bali/authorizer.rb +1 -12
- data/lib/bali/judge.rb +54 -60
- data/lib/bali/printer.rb +5 -4
- data/lib/bali/rails/action_controller.rb +8 -0
- data/lib/bali/rails/action_view.rb +8 -0
- data/lib/bali/{activerecord.rb → rails/active_record.rb} +2 -0
- data/lib/bali/role.rb +13 -12
- data/lib/bali/ruler.rb +4 -14
- data/lib/bali/rules.rb +11 -5
- data/lib/bali/statics/active_record.rb +13 -0
- data/lib/bali/statics/authorizer.rb +9 -0
- data/lib/bali/version.rb +1 -1
- metadata +11 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc092b862d79cc3506ac33a12c09c11a7d79b9b9c91c6a3116b8e6f2d3217288
|
4
|
+
data.tar.gz: b8ee30857224a08cece951ccd5e615d62c2fc1b5888ac9ec77548736c859278d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7379abef2d029101733e7a7dcb1f4d1718adc07f40cb99f5df4e3ac4ec18ccfd8d5e64c6bbd091527186d9cd7b6ef3d17129c02afc46eaffce1e482ed049bc37
|
7
|
+
data.tar.gz: a5908ad1de7f4882eab302e17aab0c13f478bf2f665a43043ff1a62fdb3e7c99f1d41ecd62d6d17a5474f5a787a5efecbf1b4d5dede94d21d324c9ed2f5c1af9
|
data/lib/bali.rb
CHANGED
@@ -10,19 +10,10 @@ end
|
|
10
10
|
require "zeitwerk"
|
11
11
|
loader = Zeitwerk::Loader.for_gem
|
12
12
|
loader.ignore("#{__dir__}/generators")
|
13
|
-
loader.ignore("#{__dir__}/bali/
|
13
|
+
loader.ignore("#{__dir__}/bali/rails")
|
14
14
|
loader.setup
|
15
15
|
|
16
16
|
module Bali
|
17
|
-
# mapping class to a RuleClass
|
18
|
-
RULE_CLASS_MAP = {}
|
19
|
-
|
20
|
-
# {
|
21
|
-
# User: :roles,
|
22
|
-
# AdminUser: :admin_roles
|
23
|
-
# }
|
24
|
-
TRANSLATED_SUBTARGET_ROLES = {}
|
25
|
-
|
26
17
|
extend self
|
27
18
|
|
28
19
|
def config
|
@@ -35,7 +26,9 @@ module Bali
|
|
35
26
|
|
36
27
|
if defined? Rails
|
37
28
|
require "bali/railtie"
|
38
|
-
require "bali/
|
29
|
+
require "bali/rails/action_controller"
|
30
|
+
require "bali/rails/action_view"
|
31
|
+
require "bali/rails/active_record"
|
39
32
|
end
|
40
33
|
end
|
41
34
|
|
data/lib/bali/authorizer.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Bali::Authorizer
|
2
2
|
def self.included(base)
|
3
|
-
base.extend Bali::Authorizer
|
3
|
+
base.extend Bali::Statics::Authorizer
|
4
4
|
end
|
5
5
|
|
6
6
|
def can?(actor_or_roles, operation = nil)
|
@@ -11,14 +11,3 @@ module Bali::Authorizer
|
|
11
11
|
self.class.cant?(actor_or_roles, operation, self)
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
15
|
-
# to allow class-level objection
|
16
|
-
module Bali::Authorizer::Statics
|
17
|
-
def can?(actor_or_roles, operation, record = self)
|
18
|
-
Bali::Judge.check(:can, actor_or_roles, operation, record)
|
19
|
-
end
|
20
|
-
|
21
|
-
def cant?(actor_or_roles, operation, record = self)
|
22
|
-
Bali::Judge.check(:cant, actor_or_roles, operation, record)
|
23
|
-
end
|
24
|
-
end
|
data/lib/bali/judge.rb
CHANGED
@@ -27,6 +27,13 @@ class Bali::Judge
|
|
27
27
|
:should_cross_check
|
28
28
|
|
29
29
|
class << self
|
30
|
+
def default_judgement_value(term)
|
31
|
+
case term
|
32
|
+
when :can then false
|
33
|
+
when :cant then true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
30
37
|
def check(term, actor_or_roles, operation, record)
|
31
38
|
if operation.nil?
|
32
39
|
# eg: user.can? :sign_in
|
@@ -34,7 +41,7 @@ class Bali::Judge
|
|
34
41
|
actor_or_roles = nil
|
35
42
|
end
|
36
43
|
|
37
|
-
judgement_value = default_value = term
|
44
|
+
judgement_value = default_value = default_judgement_value(term)
|
38
45
|
roles = Bali::Role.formalize actor_or_roles
|
39
46
|
|
40
47
|
roles.each do |role|
|
@@ -70,81 +77,44 @@ class Bali::Judge
|
|
70
77
|
end
|
71
78
|
|
72
79
|
def judgement
|
73
|
-
|
80
|
+
judgement = natural_value if no_rule_group?
|
74
81
|
|
75
|
-
if
|
76
|
-
|
82
|
+
if judgement.nil? && rule.nil? && may_have_reservation?
|
83
|
+
judgement = cross_check_reverse_value(cross_check_judge.judgement)
|
77
84
|
end
|
78
85
|
|
79
|
-
if
|
86
|
+
if judgement.nil? && rule.nil?
|
80
87
|
cross_check_value = nil
|
81
88
|
# default if can? for undefined rule is false, after related clause
|
82
89
|
# cant be found in cant?
|
83
|
-
if should_cross_check
|
84
|
-
cross_check_value = cross_check_judge.judgement
|
85
|
-
end
|
90
|
+
cross_check_value = cross_check_judge.judgement if should_cross_check
|
86
91
|
|
87
92
|
# if cross check value nil, then the reverse rule is not defined,
|
88
93
|
# let's determine whether they can do anything or not
|
89
94
|
if cross_check_value.nil?
|
90
|
-
|
91
|
-
if rule_group
|
92
|
-
if rule_group.can_all?
|
93
|
-
our_holy_judgement = term == :cant ? DEFINITE_FALSE : DEFINITE_TRUE
|
94
|
-
elsif rule_group.cant_all?
|
95
|
-
our_holy_judgement = term == :cant ? DEFINITE_TRUE : DEFINITE_FALSE
|
96
|
-
end
|
97
|
-
|
98
|
-
end # if rule_group exist
|
95
|
+
judgement = deduce_from_defined_disposition
|
99
96
|
else
|
100
97
|
# process value from cross checking
|
101
|
-
|
102
98
|
if otherly_rule && (cross_check_value == FUZY_FALSE || cross_check_value == FUZY_TRUE)
|
103
99
|
# give chance to check at others block
|
104
100
|
@rule = otherly_rule
|
105
101
|
else
|
106
|
-
|
102
|
+
judgement = cross_check_reverse_value(cross_check_value)
|
107
103
|
end
|
108
104
|
end
|
109
|
-
end # if our judgement nil and rule is nil
|
110
|
-
|
111
|
-
# if our holy judgement is still nil, but rule is defined
|
112
|
-
if our_holy_judgement.nil? && rule
|
113
|
-
if rule.conditional?
|
114
|
-
our_holy_judgement = run_condition(rule, actor, record)
|
115
|
-
else
|
116
|
-
our_holy_judgement = DEFINITE_TRUE
|
117
|
-
end
|
118
105
|
end
|
119
106
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
# don't overwrite our holy judgement with fuzy value if rule group
|
124
|
-
# zeus/plant, because zeus/plant is more definite than any fuzy values
|
125
|
-
# eventhough the rule is abstractly defined
|
126
|
-
else
|
127
|
-
our_holy_judgement = term == :cant ? FUZY_TRUE : FUZY_FALSE
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
# if at this point still nil, well,
|
132
|
-
# return the natural value for this judge
|
133
|
-
if our_holy_judgement.nil?
|
134
|
-
if otherly_rule
|
135
|
-
our_holy_judgement = FUZY_TRUE
|
136
|
-
else
|
137
|
-
our_holy_judgement = natural_value
|
138
|
-
end
|
139
|
-
end
|
107
|
+
judgement ||= deduce_by_evaluation ||
|
108
|
+
deduce_from_fuzy_rules ||
|
109
|
+
natural_value
|
140
110
|
|
141
111
|
return !should_cross_check ?
|
142
|
-
|
112
|
+
judgement :
|
143
113
|
|
144
114
|
# translate response for value above to traditional true/false
|
145
115
|
# holy judgement refer to non-standard true/false being used inside Bali
|
146
116
|
# which need to be translated from other beings to know
|
147
|
-
|
117
|
+
judgement > 0
|
148
118
|
end
|
149
119
|
|
150
120
|
private
|
@@ -214,17 +184,15 @@ class Bali::Judge
|
|
214
184
|
(rule_group && rule_group.can_all?)
|
215
185
|
end
|
216
186
|
|
217
|
-
def
|
218
|
-
# must test first
|
187
|
+
def evaluate(rule, actor, record)
|
219
188
|
conditional = rule.conditional
|
220
|
-
case conditional.arity
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
end
|
189
|
+
evaluation = case conditional.arity
|
190
|
+
when 0 then conditional.()
|
191
|
+
when 1 then conditional.(record)
|
192
|
+
when 2 then conditional.(record, actor)
|
193
|
+
end
|
194
|
+
|
195
|
+
evaluation ? DEFINITE_TRUE : DEFINITE_FALSE
|
228
196
|
end
|
229
197
|
|
230
198
|
def cross_check_reverse_value(cross_check_value)
|
@@ -236,4 +204,30 @@ class Bali::Judge
|
|
236
204
|
end
|
237
205
|
end
|
238
206
|
|
207
|
+
def deduce_by_evaluation
|
208
|
+
return unless rule
|
209
|
+
|
210
|
+
rule.conditional? ?
|
211
|
+
evaluate(rule, actor, record) :
|
212
|
+
judgement = DEFINITE_TRUE
|
213
|
+
end
|
214
|
+
|
215
|
+
def deduce_from_defined_disposition
|
216
|
+
return unless rule_group
|
217
|
+
|
218
|
+
if rule_group.can_all?
|
219
|
+
term == :cant ? DEFINITE_FALSE : DEFINITE_TRUE
|
220
|
+
elsif rule_group.cant_all?
|
221
|
+
term == :cant ? DEFINITE_TRUE : DEFINITE_FALSE
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def deduce_from_fuzy_rules
|
226
|
+
reversed_otherly_rule = other_rule_group.find_rule(reversed_term, operation)
|
227
|
+
|
228
|
+
if reversed_otherly_rule
|
229
|
+
term == :cant ? FUZY_TRUE : FUZY_FALSE
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
239
233
|
end
|
data/lib/bali/printer.rb
CHANGED
@@ -12,10 +12,11 @@ module Bali::Printer
|
|
12
12
|
output = StringIO.new
|
13
13
|
|
14
14
|
# build up the string for pretty printing rules
|
15
|
-
|
16
|
-
|
15
|
+
rule_classes = ObjectSpace.each_object(Class).select { |cls| cls < Bali::Rules }
|
16
|
+
rule_classes.each do |rule_class|
|
17
|
+
output << "===== #{rule_class.model_class} =====\n\n"
|
17
18
|
|
18
|
-
rule_class.roles.each do |subtarget, role|
|
19
|
+
rule_class.ruler.roles.each do |subtarget, role|
|
19
20
|
print_role role, output
|
20
21
|
end
|
21
22
|
|
@@ -28,7 +29,7 @@ module Bali::Printer
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def print_role role, target_io
|
31
|
-
subtarget = role.
|
32
|
+
subtarget = role.name.to_s.capitalize
|
32
33
|
subtarget = "By default" if subtarget.blank?
|
33
34
|
can_all = role.can_all?
|
34
35
|
counter = 0
|
@@ -5,4 +5,6 @@ require 'active_support/lazy_load_hooks'
|
|
5
5
|
ActiveSupport.on_load :active_record do
|
6
6
|
require "bali"
|
7
7
|
::ActiveRecord::Base.send :include, Bali::Authorizer
|
8
|
+
::ActiveRecord::Base.send :extend, Bali::Statics::Authorizer
|
9
|
+
::ActiveRecord::Base.send :extend, Bali::Statics::ActiveRecord
|
8
10
|
end
|
data/lib/bali/role.rb
CHANGED
@@ -5,7 +5,7 @@ class Bali::Role
|
|
5
5
|
DEFAULT_ALLOW = :default_allow
|
6
6
|
].freeze
|
7
7
|
|
8
|
-
attr_accessor :
|
8
|
+
attr_accessor :name
|
9
9
|
attr_accessor :cans, :cants
|
10
10
|
|
11
11
|
attr_accessor :can_all
|
@@ -15,21 +15,22 @@ class Bali::Role
|
|
15
15
|
|
16
16
|
def self.formalize(object)
|
17
17
|
case object
|
18
|
-
when String then [object]
|
19
|
-
when Symbol then [object]
|
20
|
-
when NilClass then [object]
|
18
|
+
when String, Symbol, NilClass then [object]
|
21
19
|
when Array then object
|
22
|
-
else
|
23
|
-
kls_name = object.class.to_s
|
24
|
-
method_name = Bali::TRANSLATED_SUBTARGET_ROLES[kls_name]
|
25
|
-
roles = method_name ? formalize(object.send(method_name)) : formalize(nil)
|
26
|
-
|
27
|
-
roles
|
20
|
+
else formalize(extract_roles_from_object(object))
|
28
21
|
end
|
29
22
|
end
|
30
23
|
|
31
|
-
def
|
32
|
-
|
24
|
+
def self.extract_roles_from_object(object)
|
25
|
+
method_name = object.class.role_field_for_authorization
|
26
|
+
|
27
|
+
method_name ?
|
28
|
+
formalize(object.send(method_name)) :
|
29
|
+
formalize(nil)
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(name)
|
33
|
+
@name = name&.to_sym
|
33
34
|
@right_level = INHERIT
|
34
35
|
|
35
36
|
@cans = {}
|
data/lib/bali/ruler.rb
CHANGED
@@ -6,19 +6,9 @@ class Bali::Ruler
|
|
6
6
|
private :model_class
|
7
7
|
|
8
8
|
def self.for(record_class)
|
9
|
-
|
10
|
-
|
11
|
-
if rule_class
|
12
|
-
rule_class_maker_str = record_class.to_s + Bali.config.suffix
|
13
|
-
rule_class_maker = rule_class_maker_str.safe_constantize
|
14
|
-
|
15
|
-
if rule_class_maker && rule_class_maker.ancestors.include?(Bali::Rules)
|
16
|
-
rule_class = rule_class_maker.ruler
|
17
|
-
Bali::RULE_CLASS_MAP[record_class.to_s] = rule_class
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
rule_class
|
9
|
+
rule_maker_cls_str = "#{record_class}#{Bali.config.suffix}"
|
10
|
+
rule_class = rule_maker_cls_str.safe_constantize
|
11
|
+
rule_class.ruler if rule_class
|
22
12
|
end
|
23
13
|
|
24
14
|
def initialize(model_class)
|
@@ -27,7 +17,7 @@ class Bali::Ruler
|
|
27
17
|
end
|
28
18
|
|
29
19
|
def << role
|
30
|
-
@roles[role.
|
20
|
+
@roles[role.name] = role
|
31
21
|
end
|
32
22
|
|
33
23
|
def [] role
|
data/lib/bali/rules.rb
CHANGED
@@ -4,6 +4,16 @@ class Bali::Rules
|
|
4
4
|
attr_reader :ruler
|
5
5
|
end
|
6
6
|
|
7
|
+
def self.inherited(subcls)
|
8
|
+
# Every rule class has the inherited block even if it's never
|
9
|
+
# used/formally defined, so it's easier to work with or make
|
10
|
+
# assumption/checking on the inherited block. As we treat
|
11
|
+
# rules defined in the inherited scope, as default value,
|
12
|
+
# this decision makes sense.
|
13
|
+
|
14
|
+
subcls.set_role nil
|
15
|
+
end
|
16
|
+
|
7
17
|
def self.model_class
|
8
18
|
class_name = to_s
|
9
19
|
suffix = Bali.config.suffix
|
@@ -44,11 +54,7 @@ class Bali::Rules
|
|
44
54
|
end
|
45
55
|
|
46
56
|
def self.ruler
|
47
|
-
@ruler ||=
|
48
|
-
rule_class = Bali::Ruler.new(model_class)
|
49
|
-
Bali::RULE_CLASS_MAP[model_class.to_s] = rule_class
|
50
|
-
rule_class
|
51
|
-
end
|
57
|
+
@ruler ||= Bali::Ruler.new(model_class)
|
52
58
|
end
|
53
59
|
|
54
60
|
def self.set_role(role)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Bali::Statics::ActiveRecord
|
2
|
+
def self.extended(cls)
|
3
|
+
cls.class_eval do
|
4
|
+
class << self
|
5
|
+
attr_accessor :role_field_for_authorization
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.extract_roles_from method_name
|
9
|
+
@role_field_for_authorization = method_name
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Bali::Statics::Authorizer
|
2
|
+
def can?(actor_or_roles, operation, record = self)
|
3
|
+
Bali::Judge.check(:can, actor_or_roles, operation, record)
|
4
|
+
end
|
5
|
+
|
6
|
+
def cant?(actor_or_roles, operation, record = self)
|
7
|
+
Bali::Judge.check(:cant, actor_or_roles, operation, record)
|
8
|
+
end
|
9
|
+
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: 6.0.
|
4
|
+
version: 6.0.0rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Notodikromo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-04-
|
11
|
+
date: 2020-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: zeitwerk
|
@@ -62,16 +62,16 @@ dependencies:
|
|
62
62
|
name: rake
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
|
-
- - "
|
65
|
+
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
67
|
+
version: '0'
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- - "
|
72
|
+
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: '
|
74
|
+
version: '0'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
76
|
name: rspec
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,18 +131,22 @@ files:
|
|
131
131
|
- bin/console
|
132
132
|
- bin/setup
|
133
133
|
- lib/bali.rb
|
134
|
-
- lib/bali/activerecord.rb
|
135
134
|
- lib/bali/authorizer.rb
|
136
135
|
- lib/bali/config.rb
|
137
136
|
- lib/bali/dsl_error.rb
|
138
137
|
- lib/bali/error.rb
|
139
138
|
- lib/bali/judge.rb
|
140
139
|
- lib/bali/printer.rb
|
140
|
+
- lib/bali/rails/action_controller.rb
|
141
|
+
- lib/bali/rails/action_view.rb
|
142
|
+
- lib/bali/rails/active_record.rb
|
141
143
|
- lib/bali/railtie.rb
|
142
144
|
- lib/bali/role.rb
|
143
145
|
- lib/bali/rule.rb
|
144
146
|
- lib/bali/ruler.rb
|
145
147
|
- lib/bali/rules.rb
|
148
|
+
- lib/bali/statics/active_record.rb
|
149
|
+
- lib/bali/statics/authorizer.rb
|
146
150
|
- lib/bali/tasks/bali/print_rules.rake
|
147
151
|
- lib/bali/version.rb
|
148
152
|
- lib/generators/rails/USAGE
|