aegis 2.1.1 → 2.2.0
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.
- data/VERSION +1 -1
- data/aegis.gemspec +6 -3
- data/lib/aegis.rb +0 -0
- data/lib/aegis/{access_denied.rb → errors.rb} +5 -0
- data/lib/aegis/has_role.rb +2 -1
- data/lib/aegis/loader.rb +1 -1
- data/lib/aegis/permissions.rb +2 -1
- data/lib/aegis/spec.rb +86 -0
- data/lib/rails/action_controller.rb +61 -26
- data/lib/rails/active_record.rb +0 -0
- data/spec/action_controller_spec.rb +31 -0
- data/spec/app_root/app/controllers/application_controller.rb +2 -0
- data/spec/app_root/app/controllers/reviews_controller.rb +1 -1
- data/spec/app_root/app/controllers/songs_controller.rb +8 -0
- data/spec/app_root/app/models/permissions.rb +4 -0
- data/spec/app_root/config/boot.rb +0 -0
- data/spec/app_root/config/database.yml +0 -0
- data/spec/app_root/config/environment.rb +0 -0
- data/spec/app_root/config/environments/in_memory.rb +0 -0
- data/spec/app_root/config/environments/mysql.rb +0 -0
- data/spec/app_root/config/environments/postgresql.rb +0 -0
- data/spec/app_root/config/environments/sqlite.rb +0 -0
- data/spec/app_root/config/environments/sqlite3.rb +0 -0
- data/spec/app_root/config/routes.rb +0 -0
- data/spec/app_root/lib/console_with_fixtures.rb +0 -0
- data/spec/has_role_spec.rb +6 -0
- data/spec/loader_spec.rb +3 -3
- data/spec/permissions_spec.rb +12 -1
- data/spec/spec_helper.rb +0 -0
- metadata +8 -5
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.2.0
|
data/aegis.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{aegis}
|
8
|
-
s.version = "2.
|
8
|
+
s.version = "2.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Henning Koch", "Tobias Kraze"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-08-13}
|
13
13
|
s.description = %q{Aegis is an authorization solution for Ruby on Rails that supports roles and a RESTish, resource-style declaration of permission rules.}
|
14
14
|
s.email = %q{henning.koch@makandra.de}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -23,9 +23,9 @@ Gem::Specification.new do |s|
|
|
23
23
|
"VERSION",
|
24
24
|
"aegis.gemspec",
|
25
25
|
"lib/aegis.rb",
|
26
|
-
"lib/aegis/access_denied.rb",
|
27
26
|
"lib/aegis/action.rb",
|
28
27
|
"lib/aegis/compiler.rb",
|
28
|
+
"lib/aegis/errors.rb",
|
29
29
|
"lib/aegis/has_role.rb",
|
30
30
|
"lib/aegis/loader.rb",
|
31
31
|
"lib/aegis/parser.rb",
|
@@ -33,11 +33,13 @@ Gem::Specification.new do |s|
|
|
33
33
|
"lib/aegis/resource.rb",
|
34
34
|
"lib/aegis/role.rb",
|
35
35
|
"lib/aegis/sieve.rb",
|
36
|
+
"lib/aegis/spec.rb",
|
36
37
|
"lib/rails/action_controller.rb",
|
37
38
|
"lib/rails/active_record.rb",
|
38
39
|
"spec/action_controller_spec.rb",
|
39
40
|
"spec/app_root/app/controllers/application_controller.rb",
|
40
41
|
"spec/app_root/app/controllers/reviews_controller.rb",
|
42
|
+
"spec/app_root/app/controllers/songs_controller.rb",
|
41
43
|
"spec/app_root/app/models/permissions.rb",
|
42
44
|
"spec/app_root/app/models/property.rb",
|
43
45
|
"spec/app_root/app/models/review.rb",
|
@@ -74,6 +76,7 @@ Gem::Specification.new do |s|
|
|
74
76
|
s.test_files = [
|
75
77
|
"spec/app_root/app/controllers/application_controller.rb",
|
76
78
|
"spec/app_root/app/controllers/reviews_controller.rb",
|
79
|
+
"spec/app_root/app/controllers/songs_controller.rb",
|
77
80
|
"spec/app_root/app/models/permissions.rb",
|
78
81
|
"spec/app_root/app/models/property.rb",
|
79
82
|
"spec/app_root/app/models/review.rb",
|
data/lib/aegis.rb
CHANGED
File without changes
|
data/lib/aegis/has_role.rb
CHANGED
@@ -12,7 +12,7 @@ module Aegis
|
|
12
12
|
end
|
13
13
|
|
14
14
|
send :define_method, :role_names= do |role_names|
|
15
|
-
self.role_name = role_names.join(',')
|
15
|
+
self.role_name = role_names.reject(&:blank?).join(',')
|
16
16
|
end
|
17
17
|
|
18
18
|
send :define_method, :role do
|
@@ -29,6 +29,7 @@ module Aegis
|
|
29
29
|
role_names.include?(role_name.to_s)
|
30
30
|
end
|
31
31
|
|
32
|
+
metaclass ||= singleton_class
|
32
33
|
metaclass.send :define_method, :validates_role do |*validate_options|
|
33
34
|
validate_options = validate_options[0] || {}
|
34
35
|
|
data/lib/aegis/loader.rb
CHANGED
data/lib/aegis/permissions.rb
CHANGED
data/lib/aegis/spec.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
module Aegis
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
class CheckPermissions
|
5
|
+
|
6
|
+
def initialize(expected_resource, expected_options = {})
|
7
|
+
@expected_resource = expected_resource
|
8
|
+
@expected_options = expected_options
|
9
|
+
end
|
10
|
+
|
11
|
+
def matches?(controller)
|
12
|
+
@controller_class = controller.class
|
13
|
+
@actual_resource = @controller_class.instance_variable_get('@aegis_permissions_resource')
|
14
|
+
@actual_options = @controller_class.instance_variable_get('@aegis_permissions_options')
|
15
|
+
@actual_resource == @expected_resource && @actual_options == @expected_options
|
16
|
+
end
|
17
|
+
|
18
|
+
def failure_message
|
19
|
+
if @actual_resource != @expected_resource
|
20
|
+
"expected #{@controller_class} to check permissions against resource #{@expected_resource.inspect}, but it checked against #{@actual_resource.inspect}"
|
21
|
+
else
|
22
|
+
"expected #{@controller_class} to check permissions with options #{@expected_options.inspect}, but options were #{@actual_options.inspect}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def negative_failure_message
|
27
|
+
if @actual_resource == @expected_resource
|
28
|
+
"expected #{@controller_class} to not check permissions against resource #{@expected_resource.inspect}"
|
29
|
+
else
|
30
|
+
"expected #{@controller_class} to not check permissions with options #{@expected_options.inspect}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def description
|
35
|
+
description = "check permissions against resource #{@expected_resource.inspect}"
|
36
|
+
description << " with options #{@expected_options.inspect}" if @expected_options.any?
|
37
|
+
description
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def check_permissions(*args)
|
43
|
+
CheckPermissions.new(*args)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
ActiveSupport::TestCase.send :include, Aegis::Matchers
|
51
|
+
|
52
|
+
#Spec::Rails::Example::ControllerExampleGroup.extend Aegis::ControllerSpecMacros
|
53
|
+
|
54
|
+
|
55
|
+
# def it_should_allow_access_for(*allowed_roles, &block)
|
56
|
+
#
|
57
|
+
# denied_roles = Permissions.roles.collect(&:name) - allowed_roles
|
58
|
+
#
|
59
|
+
# describe 'permissions' do
|
60
|
+
#
|
61
|
+
# before :each do
|
62
|
+
# sign_out
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# it "should deny access when no user is signed in" do
|
66
|
+
# expect { instance_eval(&block) }.to raise_error(Aegis::AccessDenied)
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# allowed_roles.each do |role|
|
70
|
+
# it "should allow access for an authenticated #{role}" do
|
71
|
+
# sign_in User.new(:role_name => role)
|
72
|
+
# expect { instance_eval(&block) }.to_not raise_error
|
73
|
+
# response.code.should == '200'
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# denied_roles.each do |role|
|
78
|
+
# it "should deny access for an authenticated #{role}" do
|
79
|
+
# sign_in User.new(:role_name => role)
|
80
|
+
# expect { instance_eval(&block) }.to raise_error(Aegis::AccessDenied)
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# end
|
@@ -1,38 +1,73 @@
|
|
1
1
|
module Aegis
|
2
2
|
module ActionController
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
4
|
+
module ClassMethods
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def require_permissions(options = {})
|
9
|
+
before_filter :unchecked_permissions, options
|
10
|
+
end
|
11
|
+
|
12
|
+
def skip_permissions(options = {})
|
13
|
+
skip_before_filter :unchecked_permissions, options
|
14
|
+
end
|
15
|
+
|
16
|
+
def permissions(resource, options = {})
|
17
|
+
|
18
|
+
filter_options = options.slice(:except, :only)
|
19
|
+
|
20
|
+
skip_before_filter :unchecked_permissions, filter_options
|
21
|
+
|
22
|
+
# Store arguments for testing
|
23
|
+
@aegis_permissions_resource = resource
|
24
|
+
@aegis_permissions_options = options
|
25
|
+
|
26
|
+
before_filter :check_permissions, filter_options
|
27
|
+
|
28
|
+
instance_eval do
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
actions_map = (options[:map] || {}).stringify_keys
|
33
|
+
object_method = options[:object] || :object
|
34
|
+
parent_object_method = options[:parent_object] || :parent_object
|
35
|
+
user_method = options[:user] || :current_user
|
36
|
+
permissions = lambda { Aegis::Permissions.app_permissions(options[:permissions]) }
|
37
|
+
|
38
|
+
define_method :check_permissions do
|
39
|
+
action = permissions.call.guess_action(
|
40
|
+
resource,
|
41
|
+
action_name.to_s,
|
42
|
+
actions_map
|
43
|
+
)
|
44
|
+
args = []
|
45
|
+
args << send(user_method)
|
46
|
+
args << send(parent_object_method) if action.takes_parent_object
|
47
|
+
args << send(object_method) if action.takes_object
|
48
|
+
action.may!(*args)
|
49
|
+
end
|
50
|
+
|
29
51
|
end
|
30
52
|
|
31
53
|
end
|
32
54
|
|
33
55
|
end
|
34
56
|
|
57
|
+
module InstanceMethods
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def unchecked_permissions
|
62
|
+
raise Aegis::UncheckedPermissions, "This controller does not check permissions"
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
35
67
|
end
|
36
68
|
end
|
37
69
|
|
38
|
-
ActionController::Base.extend
|
70
|
+
ActionController::Base.extend Aegis::ActionController::ClassMethods
|
71
|
+
ActionController::Base.send :include, Aegis::ActionController::InstanceMethods
|
72
|
+
|
73
|
+
|
data/lib/rails/active_record.rb
CHANGED
File without changes
|
@@ -28,6 +28,37 @@ describe 'Aegis::ActionController' do
|
|
28
28
|
|
29
29
|
end
|
30
30
|
|
31
|
+
describe 'require_permissions' do
|
32
|
+
|
33
|
+
it "should set a before_filter :unchecked_permissions" do
|
34
|
+
@controller_class.should_receive(:before_filter).with(:unchecked_permissions, :only => :show)
|
35
|
+
@controller_class.class_eval do
|
36
|
+
require_permissions :only => :show
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'skip_permissions' do
|
43
|
+
|
44
|
+
it "should skip a before_filter :unchecked_permissions" do
|
45
|
+
@controller_class.should_receive(:skip_before_filter).with(:unchecked_permissions, :only => :show)
|
46
|
+
@controller_class.class_eval do
|
47
|
+
skip_permissions :only => :show
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'unchecked_permissions' do
|
54
|
+
|
55
|
+
it "should raise Aegis::UncheckedPermissions" do
|
56
|
+
controller = @controller_class.new
|
57
|
+
expect { controller.send(:unchecked_permissions) }.to raise_error(Aegis::UncheckedPermissions)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
31
62
|
describe 'permissions' do
|
32
63
|
|
33
64
|
it "should fetch the context through #object, #parent_object and #current_user by default" do
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/spec/has_role_spec.rb
CHANGED
@@ -104,6 +104,12 @@ describe Aegis::HasRole do
|
|
104
104
|
user.role_names = ['first', 'second']
|
105
105
|
end
|
106
106
|
|
107
|
+
it "should ignore blank role names" do
|
108
|
+
user = @user_class.new
|
109
|
+
user.should_receive(:role_name=).with("first,second")
|
110
|
+
user.role_names = ['', nil, 'first', '', nil, 'second', '', nil]
|
111
|
+
end
|
112
|
+
|
107
113
|
end
|
108
114
|
|
109
115
|
describe 'has_role?' do
|
data/spec/loader_spec.rb
CHANGED
@@ -4,12 +4,12 @@ describe Aegis::Loader do
|
|
4
4
|
|
5
5
|
describe 'paths' do
|
6
6
|
|
7
|
-
it "should return all paths in the lib folder" do
|
7
|
+
it "should return all paths in the lib folder, except files that are optionally loaded" do
|
8
8
|
|
9
9
|
root = "#{File.dirname(__FILE__)}/../lib/"
|
10
|
-
Dir["#{root}*/*.rb"].
|
10
|
+
Dir["#{root}*/*.rb"].each do |file|
|
11
11
|
path = file.sub(root, "").sub(/\.rb$/, "")
|
12
|
-
Aegis::Loader.paths.should include(path) unless path == 'aegis/loader'
|
12
|
+
Aegis::Loader.paths.should include(path) unless path == 'aegis/loader' || path == 'aegis/spec'
|
13
13
|
end
|
14
14
|
|
15
15
|
end
|
data/spec/permissions_spec.rb
CHANGED
@@ -399,7 +399,7 @@ describe Aegis::Permissions do
|
|
399
399
|
end
|
400
400
|
|
401
401
|
@permissions.may?(@user, "zoom_into_property", "the property").should be_true
|
402
|
-
@permissions.may?(@user, "view_all_properties"
|
402
|
+
@permissions.may?(@user, "view_all_properties").should be_true
|
403
403
|
|
404
404
|
end
|
405
405
|
|
@@ -591,6 +591,17 @@ describe Aegis::Permissions do
|
|
591
591
|
|
592
592
|
end
|
593
593
|
|
594
|
+
it "should find a root action that has the same name as the given resource" do
|
595
|
+
|
596
|
+
@permissions.class_eval do
|
597
|
+
action :author_section
|
598
|
+
end
|
599
|
+
|
600
|
+
@permissions.guess_action(:author_section, 'irrelevant_action_name').should_not be_abstract
|
601
|
+
@permissions.guess_action(:undefined_action, 'irrelevant_action_name').should be_abstract
|
602
|
+
|
603
|
+
end
|
604
|
+
|
594
605
|
end
|
595
606
|
|
596
607
|
describe 'find_action_by_path' do
|
data/spec/spec_helper.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 2
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 2.
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 2.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Henning Koch
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-08-13 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -35,9 +35,9 @@ files:
|
|
35
35
|
- VERSION
|
36
36
|
- aegis.gemspec
|
37
37
|
- lib/aegis.rb
|
38
|
-
- lib/aegis/access_denied.rb
|
39
38
|
- lib/aegis/action.rb
|
40
39
|
- lib/aegis/compiler.rb
|
40
|
+
- lib/aegis/errors.rb
|
41
41
|
- lib/aegis/has_role.rb
|
42
42
|
- lib/aegis/loader.rb
|
43
43
|
- lib/aegis/parser.rb
|
@@ -45,11 +45,13 @@ files:
|
|
45
45
|
- lib/aegis/resource.rb
|
46
46
|
- lib/aegis/role.rb
|
47
47
|
- lib/aegis/sieve.rb
|
48
|
+
- lib/aegis/spec.rb
|
48
49
|
- lib/rails/action_controller.rb
|
49
50
|
- lib/rails/active_record.rb
|
50
51
|
- spec/action_controller_spec.rb
|
51
52
|
- spec/app_root/app/controllers/application_controller.rb
|
52
53
|
- spec/app_root/app/controllers/reviews_controller.rb
|
54
|
+
- spec/app_root/app/controllers/songs_controller.rb
|
53
55
|
- spec/app_root/app/models/permissions.rb
|
54
56
|
- spec/app_root/app/models/property.rb
|
55
57
|
- spec/app_root/app/models/review.rb
|
@@ -110,6 +112,7 @@ summary: Complete authorization solution for Rails
|
|
110
112
|
test_files:
|
111
113
|
- spec/app_root/app/controllers/application_controller.rb
|
112
114
|
- spec/app_root/app/controllers/reviews_controller.rb
|
115
|
+
- spec/app_root/app/controllers/songs_controller.rb
|
113
116
|
- spec/app_root/app/models/permissions.rb
|
114
117
|
- spec/app_root/app/models/property.rb
|
115
118
|
- spec/app_root/app/models/review.rb
|