bali 2.4.0 → 6.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.
Files changed (41) hide show
  1. checksums.yaml +5 -13
  2. data/.rspec +1 -0
  3. data/lib/bali.rb +23 -14
  4. data/lib/bali/activerecord.rb +8 -0
  5. data/lib/bali/authorizer.rb +24 -0
  6. data/lib/bali/config.rb +12 -0
  7. data/lib/bali/dsl_error.rb +3 -0
  8. data/lib/bali/{foundations/exceptions/bali_error.rb → error.rb} +0 -0
  9. data/lib/bali/judge.rb +239 -0
  10. data/lib/bali/printer.rb +16 -26
  11. data/lib/bali/railtie.rb +13 -0
  12. data/lib/bali/role.rb +79 -0
  13. data/lib/bali/rule.rb +17 -0
  14. data/lib/bali/ruler.rb +36 -0
  15. data/lib/bali/rules.rb +68 -0
  16. data/lib/bali/tasks/bali/print_rules.rake +9 -0
  17. data/lib/bali/version.rb +1 -1
  18. data/lib/generators/rails/USAGE +8 -0
  19. data/lib/generators/rails/rules_generator.rb +17 -0
  20. data/lib/generators/rails/templates/rules.rb +4 -0
  21. data/lib/generators/rspec/rules_generator.rb +12 -0
  22. data/lib/generators/rspec/templates/rules_spec.rb +7 -0
  23. metadata +104 -47
  24. data/lib/bali/dsl/map_rules_dsl.rb +0 -75
  25. data/lib/bali/dsl/rules_for_dsl.rb +0 -130
  26. data/lib/bali/foundations/all_foundations.rb +0 -17
  27. data/lib/bali/foundations/exceptions/authorization_error.rb +0 -38
  28. data/lib/bali/foundations/exceptions/dsl_error.rb +0 -3
  29. data/lib/bali/foundations/exceptions/objection_error.rb +0 -3
  30. data/lib/bali/foundations/judger/judge.rb +0 -329
  31. data/lib/bali/foundations/judger/negative_judge.rb +0 -40
  32. data/lib/bali/foundations/judger/positive_judge.rb +0 -41
  33. data/lib/bali/foundations/role_extractor.rb +0 -61
  34. data/lib/bali/foundations/rule/rule.rb +0 -55
  35. data/lib/bali/foundations/rule/rule_class.rb +0 -54
  36. data/lib/bali/foundations/rule/rule_group.rb +0 -91
  37. data/lib/bali/integrators/all_integrators.rb +0 -8
  38. data/lib/bali/integrators/rule_class_integrator.rb +0 -27
  39. data/lib/bali/integrators/rule_group_integrator.rb +0 -29
  40. data/lib/bali/integrators/rule_integrator.rb +0 -56
  41. data/lib/bali/objector.rb +0 -173
@@ -1,40 +0,0 @@
1
- module Bali::Judger
2
- class NegativeJudge < Judge
3
- def initialize
4
- super(false)
5
- end
6
-
7
- def auth_level
8
- :cannot
9
- end
10
-
11
- def reverse_auth_level
12
- :can
13
- end
14
-
15
- def zeus_return_value
16
- BALI_FALSE
17
- end
18
-
19
- def plant_return_value
20
- BALI_TRUE
21
- end
22
-
23
- def default_positive_return_value
24
- BALI_TRUE
25
- end
26
-
27
- def default_negative_fuzy_return_value
28
- BALI_FUZY_TRUE
29
- end
30
-
31
- # cannot? by default return true when
32
- def natural_value
33
- BALI_TRUE
34
- end
35
-
36
- def need_to_check_for_intervention?
37
- rule_group && rule_group.plant?
38
- end
39
- end
40
- end
@@ -1,41 +0,0 @@
1
- module Bali::Judger
2
- class PositiveJudge < Judge
3
- def initialize
4
- super(false)
5
- end
6
-
7
- def auth_level
8
- :can
9
- end
10
-
11
- def reverse_auth_level
12
- :cannot
13
- end
14
-
15
- def zeus_return_value
16
- BALI_TRUE
17
- end
18
-
19
- def plant_return_value
20
- BALI_FALSE
21
- end
22
-
23
- def default_positive_return_value
24
- BALI_TRUE
25
- end
26
-
27
- def default_negative_fuzy_return_value
28
- BALI_FUZY_FALSE
29
- end
30
-
31
- # value that is natural to be returned by the jury
32
- # can? by default return false
33
- def natural_value
34
- BALI_FALSE
35
- end
36
-
37
- def need_to_check_for_intervention?
38
- rule_group && rule_group.zeus?
39
- end
40
- end # positive judger
41
- end # module judger
@@ -1,61 +0,0 @@
1
- class Bali::RoleExtractor
2
- attr_reader :arg
3
-
4
- # argument can be anything, as long as role extractor know how to extract
5
- def initialize(arg)
6
- @arg = arg
7
- end
8
-
9
- def get_roles(object = @arg)
10
- case object
11
- when String; get_role_string(object)
12
- when Symbol; get_role_symbol(object)
13
- when NilClass; get_role_nil(object)
14
- when Array; get_role_array(object)
15
- else
16
- get_role_object(object)
17
- end
18
- end
19
-
20
- private
21
- def get_role_string(object)
22
- [object]
23
- end
24
-
25
- def get_role_symbol(object)
26
- [object]
27
- end
28
-
29
- def get_role_nil(object)
30
- [object]
31
- end
32
-
33
- def get_role_array(object)
34
- object
35
- end
36
-
37
- # this case, _subtarget_roles is an object but not a symbol or a string
38
- # let's try to deduct subtarget's roles
39
- def get_role_object(object)
40
- object_class = object.class.to_s
41
-
42
- # variable to hold deducted role of the passed object
43
- deducted_roles = nil
44
- role_extracted = false
45
-
46
- Bali::TRANSLATED_SUBTARGET_ROLES.each do |current_subtarget_class, roles_field_name|
47
- if object_class == current_subtarget_class
48
- deducted_roles = object.send(roles_field_name)
49
- deducted_roles = get_roles(deducted_roles)
50
- role_extracted = true
51
- break
52
- end # if matching class
53
- end # each TRANSLATED_SUBTARGET_ROLES
54
-
55
- unless role_extracted
56
- raise Bali::AuthorizationError, "Bali does not know how to process roles: #{object}"
57
- end
58
-
59
- deducted_roles
60
- end
61
- end
@@ -1,55 +0,0 @@
1
- # for internal use, representing one, single, atomic rule
2
- class Bali::Rule
3
- # auth_val is either :can or :cannot
4
- attr_reader :auth_val
5
-
6
- # what is the operation: create, update, delete, or any other
7
- attr_reader :operation
8
-
9
- # if decider is defined, a rule is executed only if decider evaluates to true
10
- attr_accessor :decider
11
- # either unless or if
12
- attr_reader :decider_type
13
-
14
- def initialize(auth_val, operation)
15
- self.auth_val = auth_val
16
- @operation = operation
17
- self
18
- end
19
-
20
- def clone
21
- cloned_rule = Bali::Rule.new(auth_val, operation)
22
- cloned_rule.decider = decider if decider
23
- cloned_rule.decider_type = decider_type if decider_type
24
-
25
- cloned_rule
26
- end
27
-
28
- def auth_val=(aval)
29
- # TODO: in version 3 remove :cant
30
- if aval == :can || aval == :cannot
31
- @auth_val = aval
32
- elsif aval == :cant
33
- @auth_val = :cannot
34
- else
35
- fail Bali::DslError, "auth_val can only either be :can or :cannot"
36
- end
37
- end
38
-
39
- def decider_type=(dectype)
40
- if dectype == :if || dectype == :unless
41
- @decider_type = dectype
42
- else
43
- fail Bali::DslError, "decider type not allowed"
44
- end
45
- end
46
-
47
- def is_discouragement?
48
- # TODO: in version 3.0 remove :cant
49
- self.auth_val == :cannot || self.auth_val == :cant
50
- end
51
-
52
- def has_decider?
53
- self.decider.is_a?(Proc) && !self.decider_type.nil?
54
- end
55
- end
@@ -1,54 +0,0 @@
1
- # the parent of all Bali::RuleGroup.
2
- class Bali::RuleClass
3
- attr_reader :target_class
4
-
5
- # consist of canonised subtarget and its rule group, eg:
6
- # {
7
- # general_user: RuleGroup
8
- # }
9
- attr_accessor :rule_groups
10
-
11
- # rule group for "other" subtargets, always checked the last time
12
- # after the "more proper" rule groups are checked
13
- attr_accessor :others_rule_group
14
-
15
- def initialize(target_class)
16
- @target_class = target_class
17
- self.rule_groups = {}
18
- self.others_rule_group = Bali::RuleGroup.new(target_class, "__*__")
19
- end
20
-
21
- def add_rule_group(rule_group)
22
- target_user = rule_group.subtarget
23
- if target_user == "__*__" || target_user == :"__*__"
24
- self.others_rule_group = rule_group
25
- else
26
- self.rule_groups[rule_group.subtarget] = rule_group
27
- end
28
- end
29
-
30
- def rules_for(subtarget)
31
- return others_rule_group if subtarget == "__*__"
32
- subtarget = Bali::RuleGroup.canon_name(subtarget)
33
- self.rule_groups[subtarget]
34
- end
35
-
36
- # options can contains:
37
- # :target_class => identifying the target class on which the clone will be applied
38
- def clone(options = {})
39
- target_class = options.fetch(:target_class)
40
- cloned_rc = Bali::RuleClass.new(target_class)
41
-
42
- rule_groups.each do |subtarget, rule_group|
43
- rule_group_clone = rule_group.clone
44
- rule_group_clone.target = target_class
45
- cloned_rc.add_rule_group(rule_group_clone)
46
- end
47
-
48
- others_rule_group_clone = others_rule_group.clone
49
- others_rule_group_clone.target = target_class
50
- cloned_rc.others_rule_group = others_rule_group_clone
51
-
52
- cloned_rc
53
- end
54
- end
@@ -1,91 +0,0 @@
1
- class Bali::RuleGroup
2
- # the target class
3
- attr_accessor :target
4
-
5
- # the user to which this rule group is applied
6
- attr_accessor :subtarget
7
-
8
- # what can be done and what cannot be done
9
- attr_accessor :cans, :cants
10
-
11
- # if set to true then the subtarget can do anything
12
- attr_accessor :zeus
13
- alias :zeus? :zeus
14
-
15
- # if set to true, well, cannot do anything
16
- attr_accessor :plant
17
- alias :plant? :plant
18
-
19
- # allowing "general user" and :general_user to route to the same rule group
20
- def self.canon_name(subtarget)
21
- if subtarget.is_a?(String)
22
- return subtarget.gsub(" ", "_").to_sym
23
- else
24
- return subtarget
25
- end
26
- end
27
-
28
- def initialize(target, subtarget)
29
- self.target = target
30
- self.subtarget = Bali::RuleGroup.canon_name(subtarget)
31
-
32
- self.cans = {}
33
- self.cants = {}
34
-
35
- # by default, rule group is neither zeus nor plant
36
- # it is neutral.
37
- # meaning, it is neither allowed to do everything, nor it is
38
- # prohibited to do anything. neutral.
39
- self.zeus = false
40
- self.plant = false
41
- end
42
-
43
- def clone
44
- cloned_rg = Bali::RuleGroup.new(target, subtarget)
45
- cans.each_value { |can_rule| cloned_rg.add_rule(can_rule.clone) }
46
- cants.each_value { |cant_rule| cloned_rg.add_rule(cant_rule.clone) }
47
- cloned_rg.zeus = zeus
48
- cloned_rg.plant = plant
49
-
50
- cloned_rg
51
- end
52
-
53
- def add_rule(rule)
54
- # operation cannot be defined twice
55
- operation = rule.operation.to_sym
56
-
57
- return if self.cants[operation] && self.cans[operation]
58
-
59
- if rule.is_discouragement?
60
- self.cants[operation] = rule
61
- self.cans.delete operation
62
- else
63
- self.cans[operation] = rule
64
- self.cants.delete operation
65
- end
66
- end
67
-
68
- def clear_rules
69
- self.cans = {}
70
- self.cants = {}
71
- end
72
-
73
- def get_rule(auth_val, operation)
74
- rule = nil
75
- case auth_val
76
- when :can, "can"
77
- rule = self.cans[operation.to_sym]
78
- when :cannot, "cannot"
79
- rule = self.cants[operation.to_sym]
80
- else
81
- fail Bali::DslError, "Undefined operation: #{auth_val}"
82
- end
83
-
84
- rule
85
- end
86
-
87
- # all rules
88
- def rules
89
- self.cans.values + self.cants.values
90
- end
91
- end
@@ -1,8 +0,0 @@
1
- module Bali
2
- module Integrator
3
- end
4
- end
5
-
6
- require_relative "rule_class_integrator"
7
- require_relative "rule_group_integrator"
8
- require_relative "rule_integrator"
@@ -1,27 +0,0 @@
1
- module Bali
2
- module Integrator
3
- # high-level functions to access and manage RuleClass classes
4
- module RuleClass
5
-
6
- module_function
7
-
8
- # return all rule classes
9
- def all
10
- Bali::RULE_CLASS_MAP
11
- end
12
-
13
- # return all rule class of a target
14
- def for(target)
15
- Bali::RULE_CLASS_MAP[target.to_s]
16
- end
17
-
18
- # add a new rule class
19
- def add(rule_class)
20
- target = rule_class.target_class
21
-
22
- Bali::RULE_CLASS_MAP[target.to_s] = rule_class
23
- rule_class
24
- end # add_rule_class
25
- end
26
- end
27
- end
@@ -1,29 +0,0 @@
1
- module Bali
2
- module Integrator
3
- module RuleGroup
4
-
5
- module_function
6
-
7
- # attempt to search the rule group,
8
- # but if not exist, will return nil
9
- def for(target_class, subtarget)
10
- rule_class = Bali::Integrator::RuleClass.for(target_class)
11
- rule_class.nil? ? nil : rule_class.rules_for(subtarget)
12
- end
13
-
14
- # make a rule group a zeus, that is, he can do everything, unless
15
- # specified more specifically otherwise by a definite rule
16
- def make_zeus(rule_group)
17
- rule_group.zeus = true
18
- rule_group.plant = false
19
- end
20
-
21
- # make a rule group a plant, that is, he cannot do everything, unless
22
- # specified more specifically otherwise by a definite rule
23
- def make_plant(rule_group)
24
- rule_group.plant = true
25
- rule_group.zeus = false
26
- end
27
- end
28
- end
29
- end
@@ -1,56 +0,0 @@
1
- module Bali
2
- module Integrator
3
- module Rule
4
-
5
- module_function
6
-
7
- # process conditional statement in rule definition
8
- # conditional hash: {if: proc} or {unless: proc}
9
- def embed_condition(rule, conditional_hash = nil)
10
- return if conditional_hash.nil?
11
-
12
- condition_type = conditional_hash.keys[0].to_s.downcase
13
- condition_type_symb = condition_type.to_sym
14
-
15
- if condition_type_symb == :if || condition_type_symb == :unless
16
- rule.decider = conditional_hash.values[0]
17
- rule.decider_type = condition_type_symb
18
- end
19
- nil
20
- end
21
-
22
- # to define can and cant is basically using this method
23
- # args can comprises of symbols, and hash (for condition)
24
- def add(auth_val, rule_group, *args)
25
- conditional_hash = nil
26
- operations = []
27
-
28
- # scan args for options
29
- args.each do |elm|
30
- if elm.is_a?(Hash)
31
- conditional_hash = elm
32
- else
33
- operations << elm
34
- end
35
- end
36
-
37
- # add operation one by one
38
- operations.each do |op|
39
- rule = Bali::Rule.new(auth_val, op)
40
- Bali::Integrator::Rule.embed_condition(rule, conditional_hash)
41
- rule_group.add_rule(rule)
42
- end
43
- end # bali_process_auth_rules
44
-
45
- # add can rule programatically
46
- def add_can(rule_group, *args)
47
- add :can, rule_group, *args
48
- end
49
-
50
- # add cannot rule programatically
51
- def add_cannot(rule_group, *args)
52
- add :cannot, rule_group, *args
53
- end
54
- end
55
- end
56
- end