permissioner 0.0.2.beta → 0.1.0.beta
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/permissioner.rb +2 -2
- data/lib/permissioner/{permission_configurer.rb → configurer.rb} +2 -2
- data/lib/permissioner/controller_additions.rb +1 -2
- data/lib/permissioner/matchers.rb +39 -7
- data/lib/permissioner/matchers/exactly_allow_attributes.rb +137 -0
- data/lib/permissioner/matchers/exactly_allow_controllers.rb +48 -0
- data/lib/permissioner/matchers/exactly_allow_resources.rb +44 -0
- data/lib/permissioner/matchers/exactly_expect_actions.rb +100 -0
- data/lib/permissioner/{permission_service_additions.rb → service_additions.rb} +23 -7
- data/lib/permissioner/version.rb +1 -1
- data/permissioner.gemspec +1 -1
- data/spec/permissioner/{permission_configurer_spec.rb → configurer_spec.rb} +8 -2
- data/spec/permissioner/controller_additions_spec.rb +3 -20
- data/spec/permissioner/matchers/exactly_allow_attributes_spec.rb +227 -0
- data/spec/permissioner/matchers/exactly_allow_controllers_spec.rb +86 -0
- data/spec/permissioner/matchers/exactly_allow_resources_spec.rb +78 -0
- data/spec/permissioner/matchers/exactly_expect_actions_spec.rb +188 -0
- data/spec/permissioner/matchers_spec.rb +70 -27
- data/spec/permissioner/{permission_service_additions_spec.rb → service_additions_spec.rb} +117 -28
- data/spec/spec_helper.rb +1 -1
- metadata +22 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ba85c8029c5e0f9a4f4f9e57c546ff2dc87e74e
|
4
|
+
data.tar.gz: e9502b6cb5c9a1dc7a269ce74af1e93b23e4606e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4802cc89cfb79b4a6d500f72ca4d0e4d31650bf6c183bebd8c7caac7d34342d074fead3c94e9ece2d6e3eb79f4d3b04566a497c52806d2cf8e12be65c993295
|
7
|
+
data.tar.gz: 9d1710c507e6d7a74ed131d8f8899bd3ef6abcd7623ff676c69c3341be585a0d150f7c7536c073152ae4ad8674286157c017cbaf83f983a24485448b90d995c0
|
data/lib/permissioner.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "permissioner/version"
|
2
|
-
require "permissioner/
|
3
|
-
require "permissioner/
|
2
|
+
require "permissioner/service_additions"
|
3
|
+
require "permissioner/configurer"
|
4
4
|
require "permissioner/controller_additions"
|
5
5
|
require "permissioner/exceptions"
|
6
6
|
require "permissioner/railtie" if defined?(Rails)
|
@@ -24,10 +24,10 @@ module Permissioner
|
|
24
24
|
# end
|
25
25
|
# end
|
26
26
|
#
|
27
|
-
module
|
27
|
+
module Configurer
|
28
28
|
|
29
29
|
attr_reader :current_user, :permission_service
|
30
|
-
delegate :allow_actions, :allow_attributes, :add_filter, to: :permission_service
|
30
|
+
delegate :allow_actions, :allow_attributes, :add_filter, :clear_filters, to: :permission_service
|
31
31
|
|
32
32
|
|
33
33
|
# Expects an instance of a class including module Permissioner::PermissionServiceAdditions acting as
|
@@ -7,8 +7,7 @@ module Permissioner
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def authorize
|
10
|
-
if permission_service.allow_action?(params[:controller], params[:action], current_resource)
|
11
|
-
permission_service.passed_filters?(params[:controller], params[:action], params)
|
10
|
+
if permission_service.allow_action?(params[:controller], params[:action], resource: current_resource, params: params)
|
12
11
|
permission_service.permit_params!(params)
|
13
12
|
else
|
14
13
|
raise Permissioner::NotAuthorized
|
@@ -1,16 +1,48 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
end
|
1
|
+
require 'permissioner/matchers/exactly_expect_actions'
|
2
|
+
require 'permissioner/matchers/exactly_allow_attributes'
|
3
|
+
require 'permissioner/matchers/exactly_allow_controllers'
|
4
|
+
require 'permissioner/matchers/exactly_allow_resources'
|
6
5
|
|
7
6
|
RSpec::Matchers.define :allow_attribute do |*args|
|
8
7
|
match do |permission_service|
|
9
8
|
permission_service.allow_attribute?(*args)
|
10
9
|
end
|
11
10
|
end
|
12
|
-
|
11
|
+
|
12
|
+
RSpec::Matchers.define :pass_filters do |*args|
|
13
13
|
match do |permission_service|
|
14
|
-
permission_service.passed_filters?(
|
14
|
+
permission_service.passed_filters?(*args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Permissioner
|
19
|
+
module Matchers
|
20
|
+
|
21
|
+
RSpec::Matchers.define :allow_action do |*args|
|
22
|
+
match do |permission_service|
|
23
|
+
permission_service.allow_action?(*args)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def exactly_allow_actions(*expected_actions)
|
28
|
+
ExactlyExpectActions.new(:@allowed_actions, *expected_actions)
|
29
|
+
end
|
30
|
+
|
31
|
+
def exactly_have_filters_for(*expected_actions)
|
32
|
+
ExactlyExpectActions.new(:@filters, *expected_actions)
|
33
|
+
end
|
34
|
+
|
35
|
+
def exactly_allow_attributes(*expected_attributes)
|
36
|
+
ExactlyAllowAttributes.new(*expected_attributes)
|
37
|
+
end
|
38
|
+
|
39
|
+
def exactly_allow_controllers(*expected_controllers)
|
40
|
+
ExactlyAllowControllers.new(*expected_controllers)
|
41
|
+
end
|
42
|
+
|
43
|
+
def exactly_allow_resources(*expected_resources)
|
44
|
+
ExactlyAllowResources.new(*expected_resources)
|
45
|
+
end
|
46
|
+
|
15
47
|
end
|
16
48
|
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module Permissioner
|
2
|
+
module Matchers
|
3
|
+
class ExactlyAllowAttributes
|
4
|
+
|
5
|
+
def initialize(*all_expected_attributes)
|
6
|
+
@all_expected_attributes = all_expected_attributes.collect do |value|
|
7
|
+
raise 'multiple attributes for a resource must stated as array, e.g. [:user_id, :username]' if value.size > 2
|
8
|
+
[value[0], Array(value[1])]
|
9
|
+
end
|
10
|
+
@failing_attributes = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def matches?(permission_service)
|
14
|
+
@permission_service = permission_service
|
15
|
+
expected_attributes_exactly_match?
|
16
|
+
end
|
17
|
+
|
18
|
+
def failure_message_for_should
|
19
|
+
if @failing_attributes.empty?
|
20
|
+
"expected to find allowed attributes for resources\n" \
|
21
|
+
"#{all_expected_resources}, but found allowed attributes for resources\n"\
|
22
|
+
"#{all_allowed_resources}"
|
23
|
+
else
|
24
|
+
message = "expected attributes did not match for following resources:\n"
|
25
|
+
@failing_attributes.inject(message) do |msg, value|
|
26
|
+
msg +=
|
27
|
+
"#{value[0]}:\n"\
|
28
|
+
"#{value[1]} were expected to be allowed, but attributes\n"\
|
29
|
+
"#{allowed_attrributes_for_resource(value[0])} are allowed\n"
|
30
|
+
msg
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def failure_message_for_should_not
|
36
|
+
'given attributes are exactly allowed although this is not expected'
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def expected_attributes_exactly_match?
|
42
|
+
resources_exactly_match? && attributes_exactly_match?
|
43
|
+
end
|
44
|
+
|
45
|
+
def resources_exactly_match?
|
46
|
+
all_expected_resources == all_allowed_resources
|
47
|
+
end
|
48
|
+
|
49
|
+
def attributes_exactly_match?
|
50
|
+
@all_expected_attributes.each do |resource, expected_attributes_for_resource|
|
51
|
+
|
52
|
+
match = expected_attributes_for_resource.count == allowed_attrributes_for_resource(resource).count
|
53
|
+
|
54
|
+
if match
|
55
|
+
match = expected_attributes_for_resource.all? do |expected_attribute|
|
56
|
+
@permission_service.allow_attribute?(resource, expected_attribute)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
unless match
|
61
|
+
@failing_attributes << [resource, expected_attributes_for_resource]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
@failing_attributes.empty?
|
65
|
+
end
|
66
|
+
|
67
|
+
def all_expected_resources
|
68
|
+
@all_expected_resources ||= begin
|
69
|
+
@all_expected_attributes.collect { |value| value[0] }.sort
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def all_allowed_resources
|
74
|
+
@all_allowed_resources ||= begin
|
75
|
+
if all_allowed_attributes.any?
|
76
|
+
all_allowed_attributes.keys.sort
|
77
|
+
else
|
78
|
+
[]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def allowed_attrributes_for_resource(resource)
|
84
|
+
@all_allowed_attributes ||= {}
|
85
|
+
@all_allowed_attributes[resource] ||= begin
|
86
|
+
if all_allowed_attributes[resource]
|
87
|
+
all_allowed_attributes[resource].sort
|
88
|
+
else
|
89
|
+
[]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def all_allowed_attributes
|
95
|
+
@all_allowed_attributes ||= begin
|
96
|
+
all_allowed_attributes = @permission_service.instance_variable_get(:@allowed_attributes)
|
97
|
+
all_allowed_attributes || {}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
#def matches?(permission_service)
|
102
|
+
# @permission_service = permission_service
|
103
|
+
# expected_attributs_exactly_macht? allowed_attributes_for_resource
|
104
|
+
#end
|
105
|
+
#
|
106
|
+
#def failure_message_for_should
|
107
|
+
# "expected that for resource \"#{@resource}\" attributes\n"\
|
108
|
+
# "#{@expected_attributes} are exactly allowed, but found attributes\n"\
|
109
|
+
# "#{allowed_attributes_for_resource} allowed"
|
110
|
+
#end
|
111
|
+
#
|
112
|
+
#def failure_message_for_should_not
|
113
|
+
# "expected that for resource \"#{@resource}\" attributes\n"\
|
114
|
+
# "#{@expected_attributes} are exactly not allowed,\n"\
|
115
|
+
# "but those attributes are exactly allowed\n"
|
116
|
+
#end
|
117
|
+
#
|
118
|
+
#private
|
119
|
+
#
|
120
|
+
#def expected_attributs_exactly_macht?(allowed_attributes_for_resource)
|
121
|
+
# allowed_attributes_for_resource.count == @expected_attributes.count &&
|
122
|
+
# @expected_attributes.all? { |attribute| allowed_attributes_for_resource.include? attribute }
|
123
|
+
#end
|
124
|
+
#
|
125
|
+
#def allowed_attributes_for_resource
|
126
|
+
# @allowed_attributes_for_resource ||= begin
|
127
|
+
# all_allowed_attributes = @permission_service.instance_variable_get(:@allowed_attributes)
|
128
|
+
# if all_allowed_attributes && all_allowed_attributes[@resource]
|
129
|
+
# all_allowed_attributes[@resource]
|
130
|
+
# else
|
131
|
+
# []
|
132
|
+
# end
|
133
|
+
# end
|
134
|
+
#end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Permissioner
|
2
|
+
module Matchers
|
3
|
+
class ExactlyAllowControllers
|
4
|
+
|
5
|
+
def initialize(*expected_controllers)
|
6
|
+
@expected_controllers = expected_controllers.collect { |controller| controller.to_s }
|
7
|
+
end
|
8
|
+
|
9
|
+
def matches?(permission_service)
|
10
|
+
@permission_service = permission_service
|
11
|
+
controllers_exactly_match?(allowed_controllers)
|
12
|
+
end
|
13
|
+
|
14
|
+
def failure_message_for_should
|
15
|
+
"expected to exactly allow controllers \n" \
|
16
|
+
"#{@expected_controllers.sort}, but found controllers\n"\
|
17
|
+
"#{allowed_controllers.sort} allowed"
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_message_for_should_not
|
21
|
+
"expected to exactly not allow controllers \n" \
|
22
|
+
"#{@expected_controllers.sort}, but these controllers are exactly allowed\n"\
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def allowed_controllers
|
28
|
+
@allowed_controllers ||= begin
|
29
|
+
all_allowed_actions = @permission_service.instance_variable_get(:@allowed_actions)
|
30
|
+
if all_allowed_actions
|
31
|
+
all_allowed_actions.keys.collect { |e| e.first }.uniq
|
32
|
+
else
|
33
|
+
[]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def all_controllers_allowed?(allowed_controllers)
|
39
|
+
@expected_controllers.all? { |controller| allowed_controllers.include? controller }
|
40
|
+
end
|
41
|
+
|
42
|
+
def controllers_exactly_match?(allowed_controllers)
|
43
|
+
allowed_controllers.count == @expected_controllers.count && all_controllers_allowed?(allowed_controllers)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Permissioner
|
2
|
+
module Matchers
|
3
|
+
class ExactlyAllowResources
|
4
|
+
|
5
|
+
def initialize(*expected_resources)
|
6
|
+
@expected_resources = expected_resources
|
7
|
+
end
|
8
|
+
|
9
|
+
def matches?(permission_service)
|
10
|
+
@permission_service = permission_service
|
11
|
+
resources_exactly_match?
|
12
|
+
end
|
13
|
+
|
14
|
+
def failure_message_for_should
|
15
|
+
"expected to exactly allow resources \n" \
|
16
|
+
"#{@expected_resources.sort}, but found resources\n"\
|
17
|
+
"#{allowed_resources.sort} allowed"
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_message_for_should_not
|
21
|
+
"expected to exactly not allow resources \n" \
|
22
|
+
"#{@expected_resources.sort}, but these resources are exactly allowed\n"\
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def resources_exactly_match?
|
28
|
+
allowed_resources.count == @expected_resources.count &&
|
29
|
+
@expected_resources.all? { |resource| allowed_resources.include? resource }
|
30
|
+
end
|
31
|
+
|
32
|
+
def allowed_resources
|
33
|
+
@allowed_resources ||= begin
|
34
|
+
allowed_attributes = @permission_service.instance_variable_get(:@allowed_attributes)
|
35
|
+
if allowed_attributes
|
36
|
+
allowed_attributes.keys
|
37
|
+
else
|
38
|
+
[]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Permissioner
|
2
|
+
module Matchers
|
3
|
+
class ExactlyExpectActions
|
4
|
+
|
5
|
+
def initialize(actions_instance_var, *all_expected_actions)
|
6
|
+
@all_expected_actions = all_expected_actions.collect do |value|
|
7
|
+
raise 'multiple actions for a controller must stated as array, e.g. [:new, :create]' if value.size > 2
|
8
|
+
[value[0].to_s, Array(value[1]).collect! { |e| e.to_s }]
|
9
|
+
end
|
10
|
+
@failing_actions = []
|
11
|
+
@actions_instance_var = actions_instance_var
|
12
|
+
end
|
13
|
+
|
14
|
+
def matches?(permission_service)
|
15
|
+
@permission_service = permission_service
|
16
|
+
expected_actions_exactly_match?
|
17
|
+
end
|
18
|
+
|
19
|
+
def failure_message_for_should
|
20
|
+
if @failing_actions.empty?
|
21
|
+
"expected to find actions for controllers \n" \
|
22
|
+
"#{all_expected_controllers}, but found actions for controllers\n"\
|
23
|
+
"#{all_actuel_controllers}"
|
24
|
+
else
|
25
|
+
message = "expected actions did not match for following controllers:\n"
|
26
|
+
@failing_actions.inject(message) do |msg, value|
|
27
|
+
msg +=
|
28
|
+
"#{value[0]}:\n"\
|
29
|
+
"#{value[1]} were expected but found actions\n"\
|
30
|
+
"#{actual_actions_for_controller(value[0])}\n"
|
31
|
+
msg
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def failure_message_for_should_not
|
37
|
+
'given actions are exactly match although this is not expected'
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def expected_actions_exactly_match?
|
43
|
+
controllers_exactly_match? && actions_exactly_match?
|
44
|
+
end
|
45
|
+
|
46
|
+
def controllers_exactly_match?
|
47
|
+
all_actuel_controllers == all_expected_controllers
|
48
|
+
end
|
49
|
+
|
50
|
+
def actions_exactly_match?
|
51
|
+
@all_expected_actions.each do |controller, expected_actions_for_controller|
|
52
|
+
expected_actions_for_controller.sort!
|
53
|
+
match = actions_for_controller_exactly_match?(controller, expected_actions_for_controller)
|
54
|
+
@failing_actions << [controller, expected_actions_for_controller] unless match
|
55
|
+
match
|
56
|
+
end
|
57
|
+
@failing_actions.empty?
|
58
|
+
end
|
59
|
+
|
60
|
+
def actions_for_controller_exactly_match?(controller, expected_actions_for_controller)
|
61
|
+
if expected_actions_for_controller == ['all']
|
62
|
+
actual_actions_for_controller(controller).include?('all')
|
63
|
+
else
|
64
|
+
expected_actions_for_controller == actual_actions_for_controller(controller)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def all_actuel_actions
|
69
|
+
@all_actuel_actions ||= begin
|
70
|
+
@permission_service.instance_variable_get(@actions_instance_var) || {}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def all_actuel_controllers
|
75
|
+
@all_actuel_controllers ||= begin
|
76
|
+
all_actuel_actions.keys.collect { |e| e.first }.uniq.sort
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def all_expected_controllers
|
81
|
+
@all_expected_controllers ||= begin
|
82
|
+
@all_expected_actions.collect { |e| e[0] }
|
83
|
+
end.sort
|
84
|
+
end
|
85
|
+
|
86
|
+
def actual_actions_for_controller(controller)
|
87
|
+
@actual_actions_for_controller ||= {}
|
88
|
+
|
89
|
+
@actual_actions_for_controller[controller] ||= begin
|
90
|
+
all_actuel_actions.keys.inject([]) do |actual_actions_for_controller, value|
|
91
|
+
if value[0] == controller
|
92
|
+
actual_actions_for_controller << value[1]
|
93
|
+
end
|
94
|
+
actual_actions_for_controller
|
95
|
+
end.uniq.sort
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Permissioner
|
2
|
-
module
|
2
|
+
module ServiceAdditions
|
3
3
|
|
4
4
|
attr_accessor :current_user
|
5
5
|
|
@@ -8,19 +8,23 @@ module Permissioner
|
|
8
8
|
configure_permissions
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
def allow_action?(controller, action, subjects={})
|
12
|
+
allowed =
|
13
|
+
@allow_all ||
|
14
|
+
(@allowed_actions &&
|
15
|
+
(@allowed_actions[[controller.to_s, action.to_s]] || @allowed_actions[[controller.to_s, 'all']]))
|
16
|
+
allowed = allowed && (allowed == true || allowed.call(subjects[:resource]))
|
17
|
+
allowed && passed_filters?(controller, action, subjects)
|
15
18
|
end
|
16
19
|
|
17
20
|
def allow_attribute?(resource, attribute)
|
18
21
|
@allow_all || @allowed_attributes && @allowed_attributes[resource].try(:include?, attribute)
|
19
22
|
end
|
20
23
|
|
21
|
-
def passed_filters?(controller, action,
|
24
|
+
def passed_filters?(controller, action, subjects={})
|
25
|
+
resource, params = subjects[:resource], subjects[:params] || {}
|
22
26
|
if @filters && @filters[[controller.to_s, action.to_s]]
|
23
|
-
@filters[[controller.to_s, action.to_s]].all? { |block| block.call(params) }
|
27
|
+
@filters[[controller.to_s, action.to_s]].all? { |block| block.call(resource, params) }
|
24
28
|
else
|
25
29
|
true
|
26
30
|
end
|
@@ -85,6 +89,18 @@ module Permissioner
|
|
85
89
|
end
|
86
90
|
end
|
87
91
|
|
92
|
+
def clear_all_filters
|
93
|
+
@filters = nil
|
94
|
+
end
|
95
|
+
|
96
|
+
def clear_filters controllers, actions
|
97
|
+
Array(controllers).each do |controller|
|
98
|
+
Array(actions).each do |action|
|
99
|
+
@filters.delete([controller.to_s, action.to_s])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
88
104
|
# Configures permissions by instantiate a new object of the given class which is intended to include
|
89
105
|
# the module Permissioner::PermissionConfigurer.
|
90
106
|
#
|