bali 6.0.0rc1 → 6.0.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/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
|