admission 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|