bali 2.2.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZTcxZjc2ZmMyNDgzYWVmMDNjOWNhMzNmNjZiZmNjYTcwMjkzZGE0YQ==
4
+ M2I3NWNjNmVlNWM4YzQyMGU0YzAyNzBmZGJmNTBjMTUxMGYxOWMxYg==
5
5
  data.tar.gz: !binary |-
6
- ZTYwYzIwMWE2Nzg1ZjM5YmIwM2RjNTcwY2E2MDQ4OTQ0ZTUzNWZmOA==
6
+ MzhkMjlhYzA4NDU3M2M4ODE1ODkxZTU0ZDA3NDJjZGUwODNmOTZhYg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MDdkNTNhODc2NTRkNmY1NTBmNDk3MTQ3Mzc5YWUwMjBkNmQzODkzYTliOTA3
10
- MGJkMjBkMWE0ZTE1ODZkYTY0MmFhMmJmMzMxNTMwM2I0ZWU1ZDE1Y2ZmOWUz
11
- N2I0NDg5MGYxZjU1NzMyOWU3MzcwOTJhMmUxOTBkNTQ0YWEzNGQ=
9
+ MTJhOTRkODJhMWM5OTIzNjA0NTQ0OWVjMTMzOTgwZDFlZDBhZjQzNjQ0N2Y2
10
+ YWViMDExYzMyZjI5Y2YyOTYxNDdhZWJmYWU5YTVlNDYwODgwZDA1NDhhZWRm
11
+ NTliMTI1ZGEyMjNjY2QyNGEwNTM5YjNjNDc5OGIxYjk2MTYyNTI=
12
12
  data.tar.gz: !binary |-
13
- YmI1YjcxMmNmOGFjOWFmZjk1NDA0MGIzZWFlMmEwNTk3ODgxNzVkYzRmZjQz
14
- ZTNkNTU4ZWYwYTBjNWNiZDdjZTNjODA2ZTBjNzc0NDRhZTU3MmQ0NWJiZmI0
15
- MGViMWE0ZjllNzZjM2U0N2ViYjNjZDYzY2ZlOWRkOTJkNWVhNjM=
13
+ NTMzMzBjNTczZmM2MDE1YmI0NjA0ZjY1MDRhZGZmNWRiNTRjZGYzMDRmMWI4
14
+ Zjk4ZTEzNGZkZDg0NzFmZjg0YjYwNDQ2OGVlYjgwNzkwNTY4MGFlZDE1NjI3
15
+ ZDI1ZjlhNmFhODA4OGQzZDFhMjBkNjdjMjk1ZTI0YTkzZmQ4MTY=
data/.gitignore CHANGED
@@ -12,3 +12,5 @@
12
12
  *.swo
13
13
  *.gemspec
14
14
  *.gem
15
+
16
+ plugins
@@ -20,11 +20,6 @@ module Bali
20
20
  # }
21
21
  TRANSLATED_SUBTARGET_ROLES = {}
22
22
 
23
- # pub/sub for plugin that extend bali
24
- LISTENABLE_EVENTS = {}
25
- end
26
-
27
- module Bali
28
23
  extend self
29
24
  def map_rules(&block)
30
25
  dsl_map_rules = Bali::MapRulesDsl.new
@@ -3,51 +3,48 @@ class Bali::MapRulesDsl
3
3
  attr_accessor :current_rule_class
4
4
 
5
5
  def initialize
6
- @@lock = Mutex.new
6
+ @@lock ||= Mutex.new
7
7
  end
8
8
 
9
9
  # defining rules
10
10
  def rules_for(target_class, options_hash = {}, &block)
11
11
  @@lock.synchronize do
12
- raise Bali::DslError "rules_for must describe a target which is a class" unless target_class.is_a?(Class)
13
12
  self.current_rule_class = Bali::RuleClass.new(target_class)
14
13
 
15
14
  parent_class = options_hash[:inherits] || options_hash["inherits"]
16
15
  if parent_class
17
16
  # in case there is inherits specification
18
- raise Bali::DslError, "inherits must take a class" unless parent_class.is_a?(Class)
19
- rule_class_from_parent = Bali::Integrators::Rule.rule_class_for(parent_class)
20
- raise Bali::DslError, "not yet defined a rule class for #{parent_class}" if rule_class_from_parent.nil?
17
+ parent_is_class = parent_class.class
18
+ fail Bali::DslError, 'inherits must take a class' unless parent_is_class
19
+ rule_class_from_parent = Bali::Integrator::RuleClass.for(parent_class)
20
+ fail Bali::DslError, "not yet defined a rule class for #{parent_class}" if rule_class_from_parent.nil?
21
21
  self.current_rule_class = rule_class_from_parent.clone(target_class: target_class)
22
22
  end
23
23
 
24
24
  Bali::RulesForDsl.new(self).instance_eval(&block)
25
25
 
26
26
  # done processing the block, now add the rule class
27
- Bali::Integrators::Rule.add_rule_class(self.current_rule_class)
27
+ Bali::Integrator::RuleClass.add(self.current_rule_class)
28
28
  end
29
29
  end
30
30
 
31
31
  # subtarget_class is the subtarget's class definition
32
32
  # field_name is the field that will be consulted when instantiated object of this class is passed in can? or cant?
33
33
  def roles_for(subtarget_class, field_name)
34
- raise Bali::DslError, "Subtarget must be a class" unless subtarget_class.is_a?(Class)
35
- raise Bali::DslError, "Field name must be a symbol/string" if !(field_name.is_a?(Symbol) || field_name.is_a?(String))
36
-
37
34
  Bali::TRANSLATED_SUBTARGET_ROLES[subtarget_class.to_s] = field_name
38
35
  nil
39
36
  end
40
37
 
41
38
  def describe(*params)
42
- raise Bali::DslError, "describe block must be within rules_for block"
39
+ fail Bali::DslError, "describe block must be within rules_for block"
43
40
  end
44
41
 
45
42
  def role(*params)
46
- raise Bali::DslError, "role block must be within rules_for block"
43
+ fail Bali::DslError, "role block must be within rules_for block"
47
44
  end
48
45
 
49
46
  def can(*params)
50
- raise Bali::DslError, "can block must be within role block"
47
+ fail Bali::DslError, "can block must be within role block"
51
48
  end
52
49
 
53
50
  def cant(*params)
@@ -56,15 +53,15 @@ class Bali::MapRulesDsl
56
53
  end
57
54
 
58
55
  def cannot(*params)
59
- raise Bali::DslError, "cant block must be within role block"
56
+ fail Bali::DslError, "cant block must be within role block"
60
57
  end
61
58
 
62
59
  def can_all(*params)
63
- raise Bali::DslError, "can_all block must be within role block"
60
+ fail Bali::DslError, "can_all block must be within role block"
64
61
  end
65
62
 
66
63
  def clear_rules
67
- raise Bali::DslError, "clear_rules must be called within role block"
64
+ fail Bali::DslError, "clear_rules must be called within role block"
68
65
  end
69
66
 
70
67
  def cant_all(*params)
@@ -73,6 +70,6 @@ class Bali::MapRulesDsl
73
70
  end
74
71
 
75
72
  def cannot_all(*params)
76
- raise Bali::DslError, "cant_all block must be within role block"
73
+ fail Bali::DslError, "cant_all block must be within role block"
77
74
  end
78
75
  end
@@ -6,11 +6,9 @@ class Bali::RulesForDsl
6
6
 
7
7
  # all to be processed subtargets
8
8
  attr_accessor :current_subtargets
9
- # rules defined with hash can: [] and cannot: []
10
- attr_accessor :shortcut_rules
11
9
 
12
10
  def initialize(map_rules_dsl)
13
- @@lock = Mutex.new
11
+ @@lock ||= Mutex.new
14
12
  self.map_rules_dsl = map_rules_dsl
15
13
  end
16
14
 
@@ -22,17 +20,29 @@ class Bali::RulesForDsl
22
20
  def role(*params)
23
21
  @@lock.synchronize do
24
22
  bali_scrap_actors(*params)
25
- bali_scrap_shortcut_rules(*params)
26
23
  current_subtargets.each do |subtarget|
24
+ bali_set_subtarget(subtarget)
25
+
27
26
  if block_given?
28
- bali_process_subtarget(subtarget) do
29
- yield
30
- end
27
+ yield
31
28
  else
32
- bali_process_subtarget(subtarget)
33
- end
34
- end
35
- end
29
+ # if no block, then rules are defined using shortcut notation, eg:
30
+ # role :user, can: [:edit]
31
+ # the last element of which params must be a hash
32
+ shortcut_rules = params[-1]
33
+ unless shortcut_rules.is_a?(Hash)
34
+ raise Bali::DslError, "Pass a hash for shortcut notation"
35
+ end
36
+
37
+ shortcut_can_rules = shortcut_rules[:can] || shortcut_rules["can"]
38
+ shortcut_cannot_rules = shortcut_rules[:cannot] || shortcut_rules["cannot"]
39
+
40
+ shortcut_rules.each do |auth_val, args|
41
+ Bali::Integrator::Rule.add(auth_val, self.current_rule_group, *args)
42
+ end # each shortcut rules
43
+ end # whether block is given or not
44
+ end # each subtarget
45
+ end # sync
36
46
  end # role
37
47
 
38
48
  def describe(*params)
@@ -61,12 +71,12 @@ class Bali::RulesForDsl
61
71
  true
62
72
  end
63
73
 
64
- def can(*operations)
65
- bali_process_auth_rules(:can, operations)
74
+ def can(*args)
75
+ Bali::Integrator::Rule.add_can(self.current_rule_group, *args)
66
76
  end
67
77
 
68
- def cannot(*operations)
69
- bali_process_auth_rules(:cannot, operations)
78
+ def cannot(*args)
79
+ Bali::Integrator::Rule.add_cannot(self.current_rule_group, *args)
70
80
  end
71
81
 
72
82
  def cant(*operations)
@@ -75,13 +85,11 @@ class Bali::RulesForDsl
75
85
  end
76
86
 
77
87
  def can_all
78
- self.current_rule_group.zeus = true
79
- self.current_rule_group.plant = false
88
+ Bali::Integrator::RuleGroup.make_zeus(self.current_rule_group)
80
89
  end
81
90
 
82
91
  def cannot_all
83
- self.current_rule_group.plant = true
84
- self.current_rule_group.zeus = false
92
+ Bali::Integrator::RuleGroup.make_plant(self.current_rule_group)
85
93
  end
86
94
 
87
95
  def cant_all
@@ -104,19 +112,10 @@ class Bali::RulesForDsl
104
112
  nil
105
113
  end
106
114
 
107
- def bali_scrap_shortcut_rules(*params)
108
- self.shortcut_rules = {}
109
- params.each do |passed_argument|
110
- if passed_argument.is_a?(Hash)
111
- self.shortcut_rules = passed_argument
112
- end
113
- end
114
- nil
115
- end
116
-
117
- def bali_process_subtarget(subtarget)
118
- target_class = self.map_rules_dsl.current_rule_class.target_class
115
+ # set the current processing on a specific subtarget
116
+ def bali_set_subtarget(subtarget)
119
117
  rule_class = self.map_rules_dsl.current_rule_class
118
+ target_class = rule_class.target_class
120
119
 
121
120
  rule_group = rule_class.rules_for(subtarget)
122
121
 
@@ -124,65 +123,8 @@ class Bali::RulesForDsl
124
123
  rule_group = Bali::RuleGroup.new(target_class, subtarget)
125
124
  end
126
125
 
126
+ rule_class.add_rule_group rule_group
127
127
  self.current_rule_group = rule_group
128
-
129
- if block_given?
130
- yield
131
- else
132
- # auth_val is either can or cannot
133
- shortcut_rules.each do |auth_val, operations|
134
- if operations.is_a?(Array)
135
- operations.each do |op|
136
- rule = Bali::Rule.new(auth_val, op)
137
- rule_group.add_rule(rule)
138
- end
139
- else
140
- operation = operations # well, basically is 1 only
141
- rule = Bali::Rule.new(auth_val, operation)
142
- rule_group.add_rule(rule)
143
- end
144
- end # each rules
145
- end # block_given?
146
-
147
- # add current_rule_group
148
- rule_class.add_rule_group(rule_group)
149
-
150
- nil
151
128
  end
152
129
 
153
- # to define can and cant is basically using this method
154
- def bali_process_auth_rules(auth_val, args)
155
- conditional_hash = nil
156
- operations = []
157
-
158
- # scan args for options
159
- args.each do |elm|
160
- if elm.is_a?(Hash)
161
- conditional_hash = elm
162
- else
163
- operations << elm
164
- end
165
- end
166
-
167
- # add operation one by one
168
- operations.each do |op|
169
- rule = Bali::Rule.new(auth_val, op)
170
- bali_embed_conditions(rule, conditional_hash)
171
- self.current_rule_group.add_rule(rule)
172
- end
173
- end # bali_process_auth_rules
174
-
175
- # process conditional statement in rule definition
176
- def bali_embed_conditions(rule, conditional_hash = nil)
177
- return if conditional_hash.nil?
178
-
179
- condition_type = conditional_hash.keys[0].to_s.downcase
180
- condition_type_symb = condition_type.to_sym
181
-
182
- if condition_type_symb == :if || condition_type_symb == :unless
183
- rule.decider = conditional_hash.values[0]
184
- rule.decider_type = condition_type_symb
185
- end
186
- nil
187
- end
188
130
  end # class
@@ -79,7 +79,7 @@ module Bali::Judger
79
79
 
80
80
  def rule_group
81
81
  unless @rule_group_checked
82
- @rule_group = Bali::Integrators::Rule.rule_group_for(record_class, subtarget)
82
+ @rule_group = Bali::Integrator::RuleGroup.for(record_class, subtarget)
83
83
  @rule_group_checked = true
84
84
  end
85
85
  @rule_group
@@ -87,7 +87,7 @@ module Bali::Judger
87
87
 
88
88
  def other_rule_group
89
89
  unless @other_rule_group_checked
90
- @other_rule_group = Bali::Integrators::Rule.rule_group_for(record_class, "__*__")
90
+ @other_rule_group = Bali::Integrator::RuleGroup.for(record_class, "__*__")
91
91
  @other_rule_group_checked = true
92
92
  end
93
93
  @other_rule_group
@@ -32,7 +32,7 @@ class Bali::Rule
32
32
  elsif aval == :cant
33
33
  @auth_val = :cannot
34
34
  else
35
- raise Bali::DslError, "auth_val can only either be :can or :cannot"
35
+ fail Bali::DslError, "auth_val can only either be :can or :cannot"
36
36
  end
37
37
  end
38
38
 
@@ -40,7 +40,7 @@ class Bali::Rule
40
40
  if dectype == :if || dectype == :unless
41
41
  @decider_type = dectype
42
42
  else
43
- raise Bali::DslError, "decider type can only be either if or unless, got: #{dectype}"
43
+ fail Bali::DslError, "decider type not allowed"
44
44
  end
45
45
  end
46
46
 
@@ -50,7 +50,6 @@ class Bali::Rule
50
50
  end
51
51
 
52
52
  def has_decider?
53
- raise Bali::DslError, "has decider but not sure if it is if or unless type decider" if self.decider.is_a?(Proc) && self.decider_type.nil?
54
- self.decider.is_a?(Proc)
53
+ self.decider.is_a?(Proc) && !self.decider_type.nil?
55
54
  end
56
55
  end
@@ -13,26 +13,17 @@ class Bali::RuleClass
13
13
  attr_accessor :others_rule_group
14
14
 
15
15
  def initialize(target_class)
16
- if target_class.is_a?(Class)
17
- @target_class = target_class
18
- else
19
- raise Bali::DslError, "Target class must be a Class"
20
- end
21
-
16
+ @target_class = target_class
22
17
  self.rule_groups = {}
23
18
  self.others_rule_group = Bali::RuleGroup.new(target_class, "__*__")
24
19
  end
25
20
 
26
21
  def add_rule_group(rule_group)
27
- if rule_group.is_a?(Bali::RuleGroup)
28
- target_user = rule_group.subtarget
29
- if target_user == "__*__" || target_user == :"__*__"
30
- self.others_rule_group = rule_group
31
- else
32
- self.rule_groups[rule_group.subtarget] = rule_group
33
- end
22
+ target_user = rule_group.subtarget
23
+ if target_user == "__*__" || target_user == :"__*__"
24
+ self.others_rule_group = rule_group
34
25
  else
35
- raise Bali::DslError, "Rule group must be an instance of Bali::RuleGroup, got: #{rule_group.class.name}"
26
+ self.rule_groups[rule_group.subtarget] = rule_group
36
27
  end
37
28
  end
38
29
 
@@ -51,12 +51,10 @@ class Bali::RuleGroup
51
51
  end
52
52
 
53
53
  def add_rule(rule)
54
- raise Bali::DslError, "Rule must be of class Bali::Rule, got: #{rule.class.name}" unless rule.is_a?(Bali::Rule)
55
-
56
54
  # operation cannot be defined twice
57
55
  operation = rule.operation.to_sym
58
56
 
59
- raise Bali::DslError, "Rule is defined twice for operation #{operation}" if self.cants[operation] && self.cans[operation]
57
+ return if self.cants[operation] && self.cans[operation]
60
58
 
61
59
  if rule.is_discouragement?
62
60
  self.cants[operation] = rule
@@ -80,7 +78,7 @@ class Bali::RuleGroup
80
78
  when :cannot, "cannot"
81
79
  rule = self.cants[operation.to_sym]
82
80
  else
83
- raise Bali::DslError, "Undefined operation: #{auth_val}"
81
+ fail Bali::DslError, "Undefined operation: #{auth_val}"
84
82
  end
85
83
 
86
84
  rule
@@ -1,4 +1,8 @@
1
- module Bali::Integrators
1
+ module Bali
2
+ module Integrator
3
+ end
2
4
  end
3
5
 
4
- require_relative "rules_integrator"
6
+ require_relative "rule_class_integrator"
7
+ require_relative "rule_group_integrator"
8
+ require_relative "rule_integrator"
@@ -0,0 +1,27 @@
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
@@ -0,0 +1,29 @@
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
@@ -0,0 +1,56 @@
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
@@ -1,3 +1,3 @@
1
1
  module Bali
2
- VERSION = "2.2.0"
2
+ VERSION = "2.4.0"
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: 2.2.0
4
+ version: 2.4.0
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-10-23 00:00:00.000000000 Z
11
+ date: 2016-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -64,11 +64,7 @@ files:
64
64
  - .gitignore
65
65
  - .rspec
66
66
  - .travis.yml
67
- - CHANGELOG.md
68
- - CODE_OF_CONDUCT.md
69
67
  - Gemfile
70
- - LICENSE.txt
71
- - README.md
72
68
  - Rakefile
73
69
  - bali.gemspec
74
70
  - bin/console
@@ -89,7 +85,9 @@ files:
89
85
  - lib/bali/foundations/rule/rule_class.rb
90
86
  - lib/bali/foundations/rule/rule_group.rb
91
87
  - lib/bali/integrators/all_integrators.rb
92
- - lib/bali/integrators/rules_integrator.rb
88
+ - lib/bali/integrators/rule_class_integrator.rb
89
+ - lib/bali/integrators/rule_group_integrator.rb
90
+ - lib/bali/integrators/rule_integrator.rb
93
91
  - lib/bali/objector.rb
94
92
  - lib/bali/printer.rb
95
93
  - lib/bali/version.rb
@@ -1,80 +0,0 @@
1
- ## Changelog
2
-
3
- == Version 1.0.0beta1
4
-
5
- 1. Initial version
6
-
7
- == Version 1.0.0rc1
8
-
9
- 1. Fix bug where user can't check on class
10
- 2. Adding new clause: cant_all
11
-
12
- == Version 1.0.0rc2
13
-
14
- 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)
15
- 2. Allow describing rule for `nil`, useful if user is not authenticated thus role is probably `nil`
16
- 3. Remove pry from development dependency
17
-
18
- == Version 1.0.0rc3
19
-
20
- 1. Each target class should includes `Bali::Objector`, for the following reasons:
21
- - Makes it clear that class do want to include the Bali::Objector
22
- - Transparant, and thus less confusing as to where "can?" and "cant" come from
23
- - When ruby re-parse the class's codes for any reasons, parser will be for sure include Bali::Objector
24
- 2. Return `true` to any `can?` for undefined target/subtarget alike
25
- 3. Return `false` to any `cant?` for undefined target/subtarget alike
26
-
27
- == Version 1.0.0
28
-
29
- 1. Released the stable version of this gem
30
-
31
- == Version 1.1.0rc1
32
-
33
- 1. Ability for rule class to be parsed later by passing `later: true` to rule class definition
34
- 2. Add `Bali.parse` and `Bali.parse!` (`Bali.parse!` executes "later"-tagged rule class, Bali.parse executes automatically after all rules are defined)
35
- 3. Added more thorough testing specs
36
- 4. Proc can be served under `unless` for defining the rule's decider
37
-
38
- == Version 1.1.0rc2
39
-
40
- 1. Ability to check `can?` and `cant?` for subtarget with multiple roles
41
- 2. Describe multiple rules at once for multiple subtarget
42
-
43
- == Version 1.2.0
44
-
45
- 1. Passing real object as subtarget's role, instead of symbol or array of symbol
46
- 2. Clause can also yielding user, along with the object in question
47
-
48
- == Version 2.0.0rc1
49
-
50
- 1. `Bali::AuthorizationError` subclass of `StandardError` tailored for raising error regarding with authorisation
51
- 2. Deprecating `cant`, `cant?`, and `cant_all` in favor of `cannot`, `cannot?` and `cannot_all`
52
- 3. new objectors `can!` and `cannot!` to raise error on inappropriate access
53
-
54
- == Version 2.0.0
55
-
56
- 1. Release!
57
-
58
- == Version 2.1.0
59
-
60
- 1. `others` block would allow for rule definitions within it to be applied for all undefined subtargets of a target
61
- 2. Fixing bug when roles_for of a user object retrieves `nil` as the user's role, it won't acknowledge that the user is indeed having `nil`-role and raising an error instead.
62
- 3. Inherits rules by passing `:inherits` option when defining `rules_for`
63
- 4. `clear_rules` within `describe` or `others` block to remove all inherited rules (or any rules previously defined) for that subtarget
64
- 5. Adding `Bali::Printer` that would enable for rules to be printed by calling `.pretty_print` on it
65
-
66
- == Version 2.1.1
67
-
68
- 1. Bug fixes on `clear_rules` which it clear rules defined in `others` even when not asked to
69
- 2. Bug fixes on `Bali::Printer` where inherited rules print the wrong target class due to another bug in an internal file (but doesn't hamper rules-checking logic)
70
-
71
- == Version 2.1.2
72
-
73
- 1. `nil` will be printed <nil> when objecting with can! or cannot! for better readability.
74
- 2. Bug fixes on declaring multiple rules with decider. Previously, others were ignored--now, every single rule will get defined whether decider is present or not.
75
-
76
- == Version 2.2.0
77
-
78
- 1. Deprecating `describe` block in favour of `role` block, `describe` is to be deprecated in version 3.0.
79
- 2. Using strategy pattern, heavy refactoring
80
- 3. Human-readable authorisation error message when invoking !-version of can/cannot, for eg: Role general_user is not allowed to perform operation `update` on My::Transaction
@@ -1,13 +0,0 @@
1
- # Contributor Code of Conduct
2
-
3
- As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
-
5
- We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
-
7
- Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
-
9
- Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
-
11
- Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
-
13
- This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2015 Adam Pahlevi
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
data/README.md DELETED
@@ -1,158 +0,0 @@
1
- # Bali
2
-
3
- [ ![Codeship Status for saveav/bali](https://codeship.com/projects/d2f3ded0-20cf-0133-e425-0eade5a669ff/status?branch=release)](https://codeship.com/projects/95727)
4
-
5
- [![Code Climate](https://codeclimate.com/github/saveav/bali/badges/gpa.svg)](https://codeclimate.com/github/saveav/bali)
6
-
7
- Bali is a powerful, framework-agnostic, thread-safe Ruby language authorization library. It is a universal authorization library, in the sense that it does not assume you to use specific Ruby library/gem/framework in order for successful use of this gem.
8
-
9
- Bali is short for Bulwark Authorization Library.
10
-
11
- ## Installation
12
-
13
- It can be installed directly by using bundler's install:
14
-
15
- $ gem install bali
16
-
17
- Otherwise, if you are using a framework such as Rails, you can add this into your gemfile:
18
-
19
- ```ruby
20
- gem 'bali'
21
- ```
22
-
23
- And then execute:
24
-
25
- $ bundle
26
-
27
- ## Deprecation notice
28
-
29
- 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.
30
- 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.
31
- 3. Since version 2.1.3, `describe` block is replaced with `role` block. `describe` block will be deprecated on version 3.0.
32
-
33
- ## Usage
34
-
35
- Please access [wiki pages](https://github.com/saveav/bali/wiki) for a more detailed, guided explanation, and see what Bali can do. This usage is a simple demonstration what average, standard use of Bali would looks like.
36
-
37
- Say:
38
-
39
- ```ruby
40
- class My::Transaction
41
- include Bali::Objector
42
-
43
- attr_accessor :is_settled
44
- attr_accessor :payment_channel
45
-
46
- alias :is_settled? :is_settled
47
- end
48
-
49
- class My::Employee
50
- include Bali::Objector
51
-
52
- # working experience in the company
53
- attr_accessor :exp_years
54
-
55
- # role/roles of this employee
56
- attr_accessor :roles
57
- end
58
- ```
59
-
60
- Your task is to define rule, with context to `My::Transaction` object, in which:
61
-
62
- 1. Supreme user can do everything
63
- 2. Admin user can do everything, but:
64
- - Can only cancel transaction if the transaction is done using credit card, and the transaction itself is not settled yet
65
- 3. General user can:
66
- - Download transaction
67
- 4. Finance user can:
68
- - Index transaction
69
- - Download transaction
70
- - Delete transaction if the transaction is settled
71
- - Cancel transaction if the transaction is settled
72
- 5. Monitoring user can:
73
- - Index transaction
74
- - Download transaction
75
- 6. Sales team can:
76
- - Index transaction
77
- - Download transaction
78
- 6. Unlogged in user can:
79
- - Index transaction
80
- - Download transaction
81
- - Report fraud
82
- 7. Guest user can:
83
- - Index transaction
84
- - Download transaction
85
- - Report fraud
86
-
87
- The specification above seems very terrifying, but with Bali, those can be defined in a succinct way, as follow:
88
-
89
- ```ruby
90
- Bali.map_rules do
91
- rules_for My::Transaction do
92
- role(:supreme_user) { can_all }
93
- role :admin_user do
94
- can_all
95
- # a more specific rule would be executed even if can_all is present
96
- can :cancel,
97
- if: proc { |record| record.payment_channel == "CREDIT_CARD" &&
98
- !record.is_settled? }
99
- end
100
- role "general user", can: [:download]
101
- role "finance" do
102
- can :delete, if: proc { |record| record.is_settled? }
103
- can :cancel, unless: proc { |record| record.is_settled? }
104
- end # finance_user description
105
- role :guest, nil { can :report_fraud }
106
- role :client do
107
- can :create
108
- end
109
- others do
110
- cannot_all
111
- can :download, :index
112
- cannot :create
113
- end
114
- end # rules_for
115
- end
116
- ```
117
-
118
- ## Can and Cant? testing
119
-
120
- Assuming that there exist a variable `transaction` which is an instance of `My::Transaction`:
121
-
122
- ```ruby
123
- transaction.cant?(:general_user, :delete) # => false
124
- transaction.can("general user", :download) # => true
125
- transaction.can?(:finance, :delete) # depends on context
126
- transaction.can?(:monitoring, :index) # => true
127
- transaction.can?(:sales, :download) # => true
128
- transaction.can?(:admin_user, :cancel) # depends on context
129
- transaction.can?(:supreme_user, :cancel) # => true
130
- transaction.can?(:guest, :download) # => false
131
- transaction.can?(nil, :download) # => true
132
- transaction.can?(nil, :report_fraud) # => true
133
- transaction.can?(:undefined_subtarget, :see) # => false
134
- transaction.cant?(:undefined_subtarget, :index) # => true
135
- transaction.can?(:client, :create) # => true
136
- transaction.can?(:finance, :create) # => false
137
- transaction.can?(:admin, :create) # => true
138
- ```
139
-
140
- Rule can also be tested on a class:
141
-
142
- ```ruby
143
- My::Transaction.can?(:client, :create) # => true
144
- My::Transaction.can?(:guest, :create) # => false
145
- My::Employee.can?(:undefined_subtarget, :create) # => false
146
- ```
147
-
148
- ## Contributing
149
-
150
- 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.
151
-
152
- ## License
153
-
154
- Bali is proudly available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
155
-
156
- ## Changelog
157
-
158
- Please refer to CHANGELOG.md to see it
@@ -1,37 +0,0 @@
1
- module Bali::Integrators::Rule
2
- extend self
3
-
4
- def rule_classes
5
- Bali::RULE_CLASS_MAP
6
- end
7
-
8
- def rule_class_for(target)
9
- raise Bali::DslError, "Target must be a class" unless target.is_a?(Class)
10
- rule_class = Bali::RULE_CLASS_MAP[target.to_s]
11
- return rule_class.nil? ? nil : rule_class
12
- end
13
-
14
- # attempt to search the rule group, but if not exist, will return nil
15
- def rule_group_for(target_class, subtarget)
16
- rule_class = rule_class_for(target_class)
17
- if rule_class
18
- rule_group = rule_class.rules_for(subtarget)
19
- return rule_group
20
- else
21
- return nil
22
- end
23
- end
24
-
25
- def add_rule_class(rule_class)
26
- if rule_class.is_a?(Bali::RuleClass)
27
- target = rule_class.target_class
28
-
29
- raise Bali::DslError, "Target must be a class" unless target.is_a?(Class)
30
-
31
- Bali::RULE_CLASS_MAP[target.to_s] = rule_class
32
- rule_class
33
- else
34
- raise Bali::DslError, "Only allow instance of Bali::RuleClass"
35
- end
36
- end # add_rule_class
37
- end