admission 0.1.6
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 +7 -0
- data/.gitignore +37 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/LICENSE +674 -0
- data/README.md +2 -0
- data/admission.gemspec +18 -0
- data/bin/rspec +8 -0
- data/lib/admission.rb +9 -0
- data/lib/admission/ability.rb +140 -0
- data/lib/admission/admission.rb +6 -0
- data/lib/admission/arbitration.rb +126 -0
- data/lib/admission/denied.rb +15 -0
- data/lib/admission/privilege.rb +129 -0
- data/lib/admission/rails.rb +94 -0
- data/lib/admission/resource_arbitration.rb +112 -0
- data/lib/admission/status.rb +38 -0
- data/lib/admission/version.rb +3 -0
- data/spec/integration/_helper.rb +2 -0
- data/spec/integration/action_arbitrating_spec.rb +119 -0
- data/spec/integration/resource_arbitrating_spec.rb +246 -0
- data/spec/rspec_config.rb +103 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/test_context/country.rb +24 -0
- data/spec/test_context/index.rb +7 -0
- data/spec/test_context/person.rb +31 -0
- data/spec/test_context/persons_fixtures.rb +43 -0
- data/spec/test_context/privileges_and_rules.rb +114 -0
- data/spec/unit/_helper.rb +1 -0
- data/spec/unit/ability_spec.rb +29 -0
- data/spec/unit/privilege/order_definer_spec.rb +184 -0
- data/spec/unit/privilege_spec.rb +146 -0
- data/spec/unit/request_arbitration_spec.rb +31 -0
- metadata +76 -0
@@ -0,0 +1,94 @@
|
|
1
|
+
# module Admission::Rails
|
2
|
+
#
|
3
|
+
# class ActionsAdmission
|
4
|
+
#
|
5
|
+
# attr_reader :resource_actions, :resource_loader
|
6
|
+
#
|
7
|
+
# def initialize controller_class
|
8
|
+
# @controller_class = controller_class
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# def authorize prepend:false, **options
|
12
|
+
# callback_name = prepend ? :prepend_before_action : :before_action
|
13
|
+
# options = options.slice(:only, :except, :if, :unless)
|
14
|
+
# admission = self
|
15
|
+
#
|
16
|
+
# @controller_class.send callback_name, options do |controller|
|
17
|
+
# ActionAbility.new(controller, admission).authorize!
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# def resource_actions *actions, loader:nil
|
22
|
+
# @resource_actions = actions.flatten
|
23
|
+
# @resource_loader = loader || :"find_#{@controller_class.controller_name.singularize}"
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# def is_resource_action? action
|
27
|
+
# @resource_actions.present? && @resource_actions.include?(action)
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# class ActionAbility
|
33
|
+
# attr_reader :controller
|
34
|
+
#
|
35
|
+
# def initialize controller, admission
|
36
|
+
# @controller = controller
|
37
|
+
# @admission = admission
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# def authorize!
|
41
|
+
# user.ability.can?(action_name, object) || (raise AccessDenied.new(self))
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# def user
|
45
|
+
# @controller.current_user
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# def object
|
49
|
+
# @object ||= if @admission.is_resource_action?(action_name)
|
50
|
+
# @controller.send @admission.resource_loader
|
51
|
+
# else
|
52
|
+
# @controller.class.controller_name
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# def action_name
|
57
|
+
# @action_name ||= @controller.params[:action].to_sym
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# def object_to_s
|
61
|
+
# case object
|
62
|
+
# when String then ":#{object}"
|
63
|
+
# when ActiveRecord::Base
|
64
|
+
# "<#{object.class.name}>"
|
65
|
+
# else
|
66
|
+
# object.to_s
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# class AccessDenied < ::StandardError
|
73
|
+
# attr_reader :action_ability
|
74
|
+
#
|
75
|
+
# def initialize ability
|
76
|
+
# @action_ability = ability
|
77
|
+
# @message = "Nemáte oprávnění pro tuto akci. (#{ability.action_name} - #{ability.object_to_s})"
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# def to_s
|
81
|
+
# @message
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
#
|
88
|
+
# ActionController::Base.instance_exec do
|
89
|
+
# def actions_admission &block
|
90
|
+
# @actions_admission ||= Admission::Rails::ActionsAdmission.new(self)
|
91
|
+
# @actions_admission.instance_exec &block if block
|
92
|
+
# @actions_admission
|
93
|
+
# end
|
94
|
+
# end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
class Admission::ResourceArbitration < Admission::Arbitration
|
2
|
+
|
3
|
+
def initialize person, rules_index, request, scope_or_resource
|
4
|
+
@person = person
|
5
|
+
scope, @resource = scope_and_resource scope_or_resource
|
6
|
+
@rules_index = rules_index[scope] || {}
|
7
|
+
@request = request.to_sym
|
8
|
+
end
|
9
|
+
|
10
|
+
def make_decision from_rules, privilege
|
11
|
+
if from_rules
|
12
|
+
decision = from_rules[privilege]
|
13
|
+
if Proc === decision
|
14
|
+
if decision.instance_variable_get :@resource_arbiter
|
15
|
+
decision = @person.instance_exec @resource, *@context, &decision
|
16
|
+
else
|
17
|
+
decision = @person.instance_exec *@context, &decision
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
unless Admission::VALID_DECISION.include? decision
|
22
|
+
raise "invalid decision: #{decision}"
|
23
|
+
end
|
24
|
+
|
25
|
+
decision
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def scope_and_resource scope_or_resource
|
30
|
+
if scope_or_resource.is_a? Symbol
|
31
|
+
[scope_or_resource]
|
32
|
+
else
|
33
|
+
[self.class.type_to_scope(scope_or_resource.class).to_sym, scope_or_resource]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.type_to_scope_resolution proc=nil, &block
|
38
|
+
@type_to_scope = proc || block
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.type_to_scope type
|
42
|
+
scope = @type_to_scope && @type_to_scope.call(type)
|
43
|
+
scope ? scope.to_sym : :"#{type.name.downcase}s"
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.nested_scope resource, scope
|
47
|
+
resource = type_to_scope resource unless resource.is_a? Symbol
|
48
|
+
"#{resource}:#{scope}".to_sym
|
49
|
+
end
|
50
|
+
|
51
|
+
class RulesBuilder < Admission::Arbitration::RulesBuilder
|
52
|
+
|
53
|
+
def allow scope, *actions, &block
|
54
|
+
raise "reserved action name #{Admission::ALL_ACTION}" if actions.include? Admission::ALL_ACTION
|
55
|
+
raise "invalid scope name" unless scope.respond_to? :to_sym
|
56
|
+
add_allowance_rule actions.flatten, (block || true), scope: scope.to_sym
|
57
|
+
end
|
58
|
+
|
59
|
+
def allow_all scope, &block
|
60
|
+
raise "invalid scope name" unless scope.respond_to? :to_sym
|
61
|
+
add_allowance_rule [Admission::ALL_ACTION], (block || true), scope: scope.to_sym
|
62
|
+
end
|
63
|
+
|
64
|
+
def forbid scope, *actions
|
65
|
+
raise "reserved action name #{Admission::ALL_ACTION}" if actions.include? Admission::ALL_ACTION
|
66
|
+
raise "invalid scope name" unless scope.respond_to? :to_sym
|
67
|
+
add_allowance_rule actions.flatten, :forbidden, scope: scope.to_sym
|
68
|
+
end
|
69
|
+
|
70
|
+
def allow_resource resource, *actions, &block
|
71
|
+
raise "reserved action name #{Admission::ALL_ACTION}" if actions.include? Admission::ALL_ACTION
|
72
|
+
raise "block not given" unless block
|
73
|
+
block.instance_variable_set :@resource_arbiter, true
|
74
|
+
scope = case resource
|
75
|
+
when Symbol then resource
|
76
|
+
when Array then nested_scope(*resource)
|
77
|
+
else type_to_scope(resource)
|
78
|
+
end
|
79
|
+
add_allowance_rule actions.flatten, block, scope: scope
|
80
|
+
end
|
81
|
+
|
82
|
+
def type_to_scope resource
|
83
|
+
Admission::ResourceArbitration.type_to_scope resource
|
84
|
+
end
|
85
|
+
|
86
|
+
def nested_scope resource, scope
|
87
|
+
Admission::ResourceArbitration.nested_scope resource, scope
|
88
|
+
end
|
89
|
+
|
90
|
+
def create_index
|
91
|
+
index_instance = @rules.reduce Hash.new do |index, allowance|
|
92
|
+
privilege = allowance[:privilege]
|
93
|
+
actions = allowance[:actions]
|
94
|
+
scope = allowance[:scope]
|
95
|
+
arbiter = allowance[:arbiter]
|
96
|
+
|
97
|
+
scope_index = (index[scope] ||= {})
|
98
|
+
|
99
|
+
actions.each do |action|
|
100
|
+
action_index = (scope_index[action] ||= {})
|
101
|
+
action_index[privilege] = arbiter
|
102
|
+
end
|
103
|
+
|
104
|
+
index
|
105
|
+
end
|
106
|
+
|
107
|
+
index_instance.freeze
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Admission::Status
|
2
|
+
|
3
|
+
attr_reader :person, :privileges, :rules
|
4
|
+
|
5
|
+
def initialize person, privileges, rules, arbiter
|
6
|
+
@person = person
|
7
|
+
@privileges = (privileges.nil? || privileges.empty?) ? nil : privileges
|
8
|
+
@rules = rules
|
9
|
+
@arbiter = arbiter
|
10
|
+
end
|
11
|
+
|
12
|
+
def can? *args
|
13
|
+
return false unless @privileges
|
14
|
+
process_request @arbiter.new(person, rules, *args)
|
15
|
+
end
|
16
|
+
|
17
|
+
def cannot? *args
|
18
|
+
!can?(*args)
|
19
|
+
end
|
20
|
+
|
21
|
+
def request! *args
|
22
|
+
can?(*args) || begin
|
23
|
+
exception = Admission::Denied.new self, *args
|
24
|
+
yield exception if block_given?
|
25
|
+
raise exception
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def process_request arbitration
|
32
|
+
privileges.any? do |privilege|
|
33
|
+
arbitration.prepare_sitting *privilege.context
|
34
|
+
arbitration.rule_per_privilege(privilege).eql? true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require_relative '_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'actions_arbitrating' do
|
4
|
+
|
5
|
+
def arbitration request, context=nil
|
6
|
+
person = Person.new 'person', Person::MALE, [:czech]
|
7
|
+
arbitration = Admission::Arbitration.new person, ACTIONS_RULES, request
|
8
|
+
arbitration.prepare_sitting *context
|
9
|
+
arbitration
|
10
|
+
end
|
11
|
+
|
12
|
+
def privilege *args, context: nil
|
13
|
+
p = Admission::Privilege.get_from_order PRIVILEGES_ORDER, *args
|
14
|
+
p = p.dup_with_context context if context
|
15
|
+
p
|
16
|
+
end
|
17
|
+
|
18
|
+
def rule request, privilege
|
19
|
+
arbitration(request, privilege.context).rule_per_privilege privilege
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'allows human to do anything' do
|
23
|
+
expect(
|
24
|
+
rule :anything, privilege(:human)
|
25
|
+
).to eql(true)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'disallows woman to do anything' do
|
29
|
+
person = Person.new 'person', Person::FEMALE, [:czech]
|
30
|
+
arbitration = Admission::Arbitration.new person, ACTIONS_RULES, :anything
|
31
|
+
arbitration.prepare_sitting
|
32
|
+
expect(
|
33
|
+
arbitration.rule_per_privilege privilege(:human)
|
34
|
+
).to eql(false)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'allow woman-count to do anything in her country' do
|
38
|
+
person = Person.new 'person', Person::FEMALE, [:czech]
|
39
|
+
arbitration = Admission::Arbitration.new person, ACTIONS_RULES, :anything
|
40
|
+
arbitration.prepare_sitting :czech
|
41
|
+
expect(
|
42
|
+
arbitration.rule_per_privilege privilege(:human, :count, context: [:czech])
|
43
|
+
).to eql(true)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'allows only king to raise taxes' do
|
47
|
+
expect(
|
48
|
+
rule :raise_taxes, privilege(:human)
|
49
|
+
).to eql(:forbidden)
|
50
|
+
|
51
|
+
expect(
|
52
|
+
rule :raise_taxes, privilege(:human, :count)
|
53
|
+
).to eql(:forbidden)
|
54
|
+
|
55
|
+
expect(
|
56
|
+
rule :raise_taxes, privilege(:human, :king)
|
57
|
+
).to eql(true)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'allows count and king to impose corvee in his countries' do
|
61
|
+
expect(
|
62
|
+
rule :impose_corvee,
|
63
|
+
privilege(:human, :count, context: [:czech])
|
64
|
+
).to eql(true)
|
65
|
+
|
66
|
+
expect(
|
67
|
+
rule :impose_corvee,
|
68
|
+
privilege(:human, :king, context: [:czech])
|
69
|
+
).to eql(true)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'forbids count and king to impose corvee outside his countries' do
|
73
|
+
expect(
|
74
|
+
rule :impose_corvee,
|
75
|
+
privilege(:human, :count, context: [:taiwan])
|
76
|
+
).to eql(:forbidden)
|
77
|
+
|
78
|
+
expect(
|
79
|
+
rule :impose_corvee,
|
80
|
+
privilege(:human, :king, context: [:taiwan])
|
81
|
+
).to eql(:forbidden)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'forbids any human to impose a draft' do
|
85
|
+
expect(
|
86
|
+
rule :impose_draft, privilege(:human)
|
87
|
+
).to eql(:forbidden)
|
88
|
+
|
89
|
+
expect(
|
90
|
+
rule :impose_draft, privilege(:human, :count)
|
91
|
+
).to eql(:forbidden)
|
92
|
+
|
93
|
+
expect(
|
94
|
+
rule :impose_draft, privilege(:human, :king)
|
95
|
+
).to eql(:forbidden)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'allows lord to impose draft' do
|
99
|
+
expect(
|
100
|
+
rule :impose_draft,
|
101
|
+
privilege(:vassal, :lord)
|
102
|
+
).to eql(true)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'forbids emperor to impose draft because of inheritance' do
|
106
|
+
expect(
|
107
|
+
rule :impose_draft,
|
108
|
+
privilege(:emperor)
|
109
|
+
).to eql(:forbidden)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'allows emperor to act as god' do
|
113
|
+
expect(
|
114
|
+
rule :act_as_god,
|
115
|
+
privilege(:emperor)
|
116
|
+
).to eql(true)
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,246 @@
|
|
1
|
+
require_relative '_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'resources_arbitrating' do
|
4
|
+
|
5
|
+
let(:person){ Person.new 'person', Person::MALE, [:czech] }
|
6
|
+
let(:female){ Person.new 'female', Person::FEMALE, [:czech] }
|
7
|
+
|
8
|
+
def arbitration scope, action, context=nil
|
9
|
+
arbitration = Admission::ResourceArbitration.new person, RESOURCE_RULES, action, scope
|
10
|
+
arbitration.prepare_sitting *context
|
11
|
+
arbitration
|
12
|
+
end
|
13
|
+
|
14
|
+
def privilege *args, context: nil
|
15
|
+
p = Admission::Privilege.get_from_order PRIVILEGES_ORDER, *args
|
16
|
+
p = p.dup_with_context context if context
|
17
|
+
p
|
18
|
+
end
|
19
|
+
|
20
|
+
def actions_rule action, privilege
|
21
|
+
arbitration(:actions, action, privilege.context).rule_per_privilege privilege
|
22
|
+
end
|
23
|
+
|
24
|
+
def rule scope, action, privilege
|
25
|
+
arbitration(scope, action, privilege.context).rule_per_privilege privilege
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'actions scope' do
|
29
|
+
|
30
|
+
it 'allows human to do anything' do
|
31
|
+
expect(
|
32
|
+
actions_rule :anything, privilege(:human)
|
33
|
+
).to eql(true)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'disallows woman to do anything' do
|
37
|
+
arbitration = Admission::ResourceArbitration.new female, RESOURCE_RULES,
|
38
|
+
:anything, :actions
|
39
|
+
arbitration.prepare_sitting
|
40
|
+
expect(
|
41
|
+
arbitration.rule_per_privilege privilege(:human)
|
42
|
+
).to eql(false)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'allow woman-count to do anything in her country' do
|
46
|
+
arbitration = Admission::ResourceArbitration.new female, RESOURCE_RULES,
|
47
|
+
:anything, :actions
|
48
|
+
arbitration.prepare_sitting :czech
|
49
|
+
expect(
|
50
|
+
arbitration.rule_per_privilege privilege(:human, :count, context: [:czech])
|
51
|
+
).to eql(true)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'allows only king to raise taxes' do
|
55
|
+
expect(
|
56
|
+
actions_rule :raise_taxes, privilege(:human)
|
57
|
+
).to eql(:forbidden)
|
58
|
+
|
59
|
+
expect(
|
60
|
+
actions_rule :raise_taxes, privilege(:human, :count)
|
61
|
+
).to eql(:forbidden)
|
62
|
+
|
63
|
+
expect(
|
64
|
+
actions_rule :raise_taxes, privilege(:human, :king)
|
65
|
+
).to eql(true)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'allows count and king to impose corvee in his countries' do
|
69
|
+
expect(
|
70
|
+
actions_rule :impose_corvee,
|
71
|
+
privilege(:human, :count, context: [:czech])
|
72
|
+
).to eql(true)
|
73
|
+
|
74
|
+
expect(
|
75
|
+
actions_rule :impose_corvee,
|
76
|
+
privilege(:human, :king, context: [:czech])
|
77
|
+
).to eql(true)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'forbids count and king to impose corvee outside his countries' do
|
81
|
+
expect(
|
82
|
+
actions_rule :impose_corvee,
|
83
|
+
privilege(:human, :count, context: [:taiwan])
|
84
|
+
).to eql(:forbidden)
|
85
|
+
|
86
|
+
expect(
|
87
|
+
actions_rule :impose_corvee,
|
88
|
+
privilege(:human, :king, context: [:taiwan])
|
89
|
+
).to eql(:forbidden)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'forbids any human to impose a draft' do
|
93
|
+
expect(
|
94
|
+
actions_rule :impose_draft, privilege(:human)
|
95
|
+
).to eql(:forbidden)
|
96
|
+
|
97
|
+
expect(
|
98
|
+
actions_rule :impose_draft, privilege(:human, :count)
|
99
|
+
).to eql(:forbidden)
|
100
|
+
|
101
|
+
expect(
|
102
|
+
actions_rule :impose_draft, privilege(:human, :king)
|
103
|
+
).to eql(:forbidden)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'allows lord to impose draft' do
|
107
|
+
expect(
|
108
|
+
actions_rule :impose_draft, privilege(:vassal, :lord)
|
109
|
+
).to eql(true)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'forbids emperor to impose draft because of inheritance' do
|
113
|
+
expect(
|
114
|
+
actions_rule :impose_draft, privilege(:emperor)
|
115
|
+
).to eql(:forbidden)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'allows emperor to act as god' do
|
119
|
+
expect(
|
120
|
+
actions_rule :act_as_god, privilege(:emperor)
|
121
|
+
).to eql(true)
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
describe 'resources scope' do
|
127
|
+
|
128
|
+
it 'allows vassal to see only himself' do
|
129
|
+
expect(
|
130
|
+
rule person, :show, privilege(:vassal)
|
131
|
+
).to eql(true)
|
132
|
+
|
133
|
+
person = Person.new 'person', Person::FEMALE, [:czech]
|
134
|
+
expect(
|
135
|
+
rule person, :show, privilege(:vassal)
|
136
|
+
).to eql(false)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'passes nil as argument if resource-arbiter accessed by name-scope' do
|
140
|
+
expect{
|
141
|
+
rule :persons, :show, privilege(:vassal)
|
142
|
+
}.to raise_error('person is nil')
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'allows vassal to list persons only per his countries' do
|
146
|
+
expect(
|
147
|
+
rule :persons, :index, privilege(:vassal, context: [:czech])
|
148
|
+
).to eql(true)
|
149
|
+
|
150
|
+
expect(
|
151
|
+
rule :persons, :index, privilege(:vassal, context: [:taiwan])
|
152
|
+
).to eql(false)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'allows access scope-arbiter by resource' do
|
156
|
+
expect(
|
157
|
+
rule person, :index, privilege(:vassal, context: [:czech])
|
158
|
+
).to eql(true)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'allows lord to see any person' do
|
162
|
+
expect(
|
163
|
+
rule person, :show, privilege(:vassal, :lord)
|
164
|
+
).to eql(true)
|
165
|
+
|
166
|
+
expect(
|
167
|
+
rule female, :show, privilege(:vassal, :lord)
|
168
|
+
).to eql(true)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'allows lord to list persons from his country' do
|
172
|
+
expect(
|
173
|
+
rule person, :index, privilege(:vassal, context: [:czech])
|
174
|
+
).to eql(true)
|
175
|
+
|
176
|
+
expect(
|
177
|
+
rule :persons, :index, privilege(:vassal, context: [:czech])
|
178
|
+
).to eql(true)
|
179
|
+
|
180
|
+
expect(
|
181
|
+
rule person, :index, privilege(:vassal, context: [:taiwan])
|
182
|
+
).to eql(false)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'allows lord to update person that is from his country' do
|
186
|
+
expect(
|
187
|
+
rule female, :update,
|
188
|
+
privilege(:vassal, :lord, context: [:czech])
|
189
|
+
).to eql(true)
|
190
|
+
|
191
|
+
expect(
|
192
|
+
rule female, :update, privilege(:vassal, :lord)
|
193
|
+
).to eql(false)
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'disallows lord to update person not from his country' do
|
197
|
+
female = Person.new 'person', Person::FEMALE, [:taiwan]
|
198
|
+
|
199
|
+
expect(
|
200
|
+
rule female, :update,
|
201
|
+
privilege(:vassal, :lord, context: [:czech])
|
202
|
+
).to eql(false)
|
203
|
+
|
204
|
+
expect(
|
205
|
+
rule female, :update,
|
206
|
+
privilege(:vassal, :lord, context: [:taiwan])
|
207
|
+
).to eql(false)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'ensures lord cannot update person accessing him by scope-name' do
|
211
|
+
expect(
|
212
|
+
rule :persons, :update, privilege(:vassal, :lord)
|
213
|
+
).to eql(false)
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'disallows vassal to update person' do
|
217
|
+
expect(
|
218
|
+
rule person, :update, privilege(:vassal, context: [:czech])
|
219
|
+
).to eql(false)
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'allows lord to destroy person from his country' do
|
223
|
+
female = Person.new 'person', Person::FEMALE, [:taiwan]
|
224
|
+
|
225
|
+
expect(
|
226
|
+
rule person, :destroy,
|
227
|
+
privilege(:vassal, :lord, context: [:czech])
|
228
|
+
).to eql(true)
|
229
|
+
|
230
|
+
expect(
|
231
|
+
rule female, :destroy,
|
232
|
+
privilege(:vassal, :lord, context: [:czech])
|
233
|
+
).to eql(false)
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'disallows lord to destroy apache helicopter' do
|
237
|
+
helicopter = Person.new 'person', Person::APACHE_HELICOPTER, [:czech]
|
238
|
+
expect(
|
239
|
+
rule helicopter, :destroy,
|
240
|
+
privilege(:vassal, :lord, context: [:czech])
|
241
|
+
).to eql(false)
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|