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 CHANGED
@@ -1 +1 @@
1
- 2.1.1
1
+ 2.2.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{aegis}
8
- s.version = "2.1.1"
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-07-26}
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",
File without changes
@@ -1,4 +1,9 @@
1
1
  module Aegis
2
+
2
3
  class AccessDenied < StandardError
3
4
  end
5
+
6
+ class UncheckedPermissions < StandardError
7
+ end
8
+
4
9
  end
@@ -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
 
@@ -5,7 +5,7 @@ module Aegis
5
5
  def paths
6
6
  [ 'ostruct',
7
7
 
8
- 'aegis/access_denied',
8
+ 'aegis/errors',
9
9
  'aegis/action',
10
10
  'aegis/compiler',
11
11
  'aegis/has_role',
@@ -130,7 +130,8 @@ module Aegis
130
130
  [ mapped.to_s ]
131
131
  else
132
132
  [ "#{action_name}_#{resource_name.to_s.singularize}",
133
- "#{action_name}_#{resource_name.to_s.pluralize}" ]
133
+ "#{action_name}_#{resource_name.to_s.pluralize}",
134
+ resource_name ]
134
135
  end
135
136
  end
136
137
 
@@ -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
- def permissions(resource, options = {})
5
-
6
- before_filter :check_permissions, options.slice(:except, :only)
7
-
8
- instance_eval do
9
-
10
- private
11
-
12
- actions_map = (options[:map] || {}).stringify_keys
13
- object_method = options[:object] || :object
14
- parent_object_method = options[:parent_object] || :parent_object
15
- user_method = options[:user] || :current_user
16
- permissions = lambda { Aegis::Permissions.app_permissions(options[:permissions]) }
17
-
18
- define_method :check_permissions do
19
- action = permissions.call.guess_action(
20
- resource,
21
- action_name.to_s,
22
- actions_map
23
- )
24
- args = []
25
- args << send(user_method)
26
- args << send(parent_object_method) if action.takes_parent_object
27
- args << send(object_method) if action.takes_object
28
- action.may!(*args)
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(Aegis::ActionController)
70
+ ActionController::Base.extend Aegis::ActionController::ClassMethods
71
+ ActionController::Base.send :include, Aegis::ActionController::InstanceMethods
72
+
73
+
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
@@ -1,5 +1,7 @@
1
1
  class ApplicationController < ActionController::Base
2
2
 
3
+ require_permissions
4
+
3
5
  def current_user
4
6
  User.new(:role_name => 'user')
5
7
  end
@@ -33,4 +33,4 @@ class ReviewsController < ApplicationController
33
33
  @parent_object ||= Property.find(params[:id])
34
34
  end
35
35
 
36
- end
36
+ end
@@ -0,0 +1,8 @@
1
+ class SongsController
2
+
3
+ require_permissions
4
+
5
+ skip_permissions :only => :index
6
+ permissions :songs, :only => :new
7
+
8
+ end
@@ -10,5 +10,9 @@ class Permissions < Aegis::Permissions
10
10
  end
11
11
  end
12
12
 
13
+ resources :maps do
14
+ action :with_permission, :collection => true
15
+ end
16
+
13
17
  end
14
18
 
File without changes
File without changes
File without changes
File without changes
@@ -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
@@ -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"].collect do |file|
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
@@ -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", "the property").should be_true
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
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
- - 1
8
- - 1
9
- version: 2.1.1
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-07-26 00:00:00 +02:00
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