cancan 1.1.1 → 1.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/CHANGELOG.rdoc +15 -0
- data/lib/cancan.rb +1 -0
- data/lib/cancan/ability.rb +95 -135
- data/lib/cancan/active_record_additions.rb +10 -9
- data/lib/cancan/can_definition.rb +114 -0
- data/lib/cancan/controller_additions.rb +61 -51
- data/lib/cancan/controller_resource.rb +16 -9
- data/lib/cancan/exceptions.rb +11 -11
- data/lib/cancan/resource_authorization.rb +21 -19
- data/spec/cancan/ability_spec.rb +40 -28
- data/spec/cancan/active_record_additions_spec.rb +8 -8
- data/spec/cancan/can_definition_spec.rb +44 -0
- data/spec/cancan/controller_additions_spec.rb +9 -9
- data/spec/cancan/controller_resource_spec.rb +9 -9
- data/spec/cancan/exceptions_spec.rb +5 -5
- data/spec/cancan/resource_authorization_spec.rb +35 -17
- data/spec/spec_helper.rb +1 -1
- metadata +6 -4
@@ -8,21 +8,21 @@ describe CanCan::ActiveRecordAdditions do
|
|
8
8
|
@ability = Object.new
|
9
9
|
@ability.extend(CanCan::Ability)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it "should call where(:id => nil) when no ability is defined so no records are found" do
|
13
|
-
stub(@model_class).where(:id => nil) { :no_where }
|
13
|
+
stub(@model_class).where(:id => nil).stub!.joins(nil) { :no_where }
|
14
14
|
@model_class.accessible_by(@ability, :read).should == :no_where
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
it "should call where with matching ability conditions" do
|
18
|
-
@ability.can :read, @model_class, :foo => 1
|
19
|
-
stub(@model_class).where(:
|
18
|
+
@ability.can :read, @model_class, :foo => {:bar => 1}
|
19
|
+
stub(@model_class).where(:foos => { :bar => 1 }).stub!.joins([:foo]) { :found_records }
|
20
20
|
@model_class.accessible_by(@ability, :read).should == :found_records
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
it "should default to :read ability and use scoped when where isn't available" do
|
24
|
-
@ability.can :read, @model_class, :foo => 1
|
25
|
-
stub(@model_class).scoped(:conditions => {:
|
24
|
+
@ability.can :read, @model_class, :foo => {:bar => 1}
|
25
|
+
stub(@model_class).scoped(:conditions => {:foos => {:bar => 1}}, :joins => [:foo]) { :found_records }
|
26
26
|
@model_class.accessible_by(@ability).should == :found_records
|
27
27
|
end
|
28
28
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CanCan::CanDefinition do
|
4
|
+
before(:each) do
|
5
|
+
@conditions = {}
|
6
|
+
@can = CanCan::CanDefinition.new(true, :read, Integer, @conditions, nil)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return no association joins if none exist" do
|
10
|
+
@can.association_joins.should be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return no association for joins if just attributes" do
|
14
|
+
@conditions[:foo] = :bar
|
15
|
+
@can.association_joins.should be_nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return single association for joins" do
|
19
|
+
@conditions[:foo] = {:bar => 1}
|
20
|
+
@can.association_joins.should == [:foo]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return multiple associations for joins" do
|
24
|
+
@conditions[:foo] = {:bar => 1}
|
25
|
+
@conditions[:test] = {1 => 2}
|
26
|
+
@can.association_joins.map(&:to_s).sort.should == [:foo, :test].map(&:to_s).sort
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return nested associations for joins" do
|
30
|
+
@conditions[:foo] = {:bar => {1 => 2}}
|
31
|
+
@can.association_joins.should == [{:foo => [:bar]}]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return table names in conditions for association joins" do
|
35
|
+
@conditions[:foo] = {:bar => 1}
|
36
|
+
@conditions[:test] = 1
|
37
|
+
@can.conditions(:tableize => true).should == { :foos => { :bar => 1}, :test => 1 }
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return no association joins if conditions is nil" do
|
41
|
+
can = CanCan::CanDefinition.new(true, :read, Integer, nil, nil)
|
42
|
+
can.association_joins.should be_nil
|
43
|
+
end
|
44
|
+
end
|
@@ -9,11 +9,11 @@ describe CanCan::ControllerAdditions do
|
|
9
9
|
mock(@controller_class).helper_method(:can?, :cannot?)
|
10
10
|
@controller_class.send(:include, CanCan::ControllerAdditions)
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
it "should raise ImplementationRemoved when attempting to call 'unauthorized!' on a controller" do
|
14
14
|
lambda { @controller.unauthorized! }.should raise_error(CanCan::ImplementationRemoved)
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
it "should raise access denied exception if ability us unauthorized to perform a certain action" do
|
18
18
|
begin
|
19
19
|
@controller.authorize! :read, :foo, 1, 2, 3, :message => "Access denied!"
|
@@ -25,12 +25,12 @@ describe CanCan::ControllerAdditions do
|
|
25
25
|
fail "Expected CanCan::AccessDenied exception to be raised"
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
it "should not raise access denied exception if ability is authorized to perform an action" do
|
30
30
|
@controller.current_ability.can :read, :foo
|
31
31
|
lambda { @controller.authorize!(:read, :foo) }.should_not raise_error
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
it "should raise access denied exception with default message if not specified" do
|
35
35
|
begin
|
36
36
|
@controller.authorize! :read, :foo
|
@@ -41,29 +41,29 @@ describe CanCan::ControllerAdditions do
|
|
41
41
|
fail "Expected CanCan::AccessDenied exception to be raised"
|
42
42
|
end
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
it "should have a current_ability method which generates an ability for the current user" do
|
46
46
|
@controller.current_ability.should be_kind_of(Ability)
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
it "should provide a can? and cannot? methods which go through the current ability" do
|
50
50
|
@controller.current_ability.should be_kind_of(Ability)
|
51
51
|
@controller.can?(:foo, :bar).should be_false
|
52
52
|
@controller.cannot?(:foo, :bar).should be_true
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
it "load_and_authorize_resource should setup a before filter which passes call to ResourceAuthorization" do
|
56
56
|
stub(CanCan::ResourceAuthorization).new(@controller, @controller.params, :foo => :bar).mock!.load_and_authorize_resource
|
57
57
|
mock(@controller_class).before_filter({}) { |options, block| block.call(@controller) }
|
58
58
|
@controller_class.load_and_authorize_resource :foo => :bar
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
it "authorize_resource should setup a before filter which passes call to ResourceAuthorization" do
|
62
62
|
stub(CanCan::ResourceAuthorization).new(@controller, @controller.params, :foo => :bar).mock!.authorize_resource
|
63
63
|
mock(@controller_class).before_filter(:except => :show) { |options, block| block.call(@controller) }
|
64
64
|
@controller_class.authorize_resource :foo => :bar, :except => :show
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
it "load_resource should setup a before filter which passes call to ResourceAuthorization" do
|
68
68
|
stub(CanCan::ResourceAuthorization).new(@controller, @controller.params, :foo => :bar).mock!.load_resource
|
69
69
|
mock(@controller_class).before_filter(:only => [:show, :index]) { |options, block| block.call(@controller) }
|
@@ -4,53 +4,53 @@ describe CanCan::ControllerResource do
|
|
4
4
|
before(:each) do
|
5
5
|
@controller = Object.new
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
it "should determine model class by constantizing give name" do
|
9
9
|
CanCan::ControllerResource.new(@controller, :ability).model_class.should == Ability
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it "should fetch model through model class and assign it to the instance" do
|
13
13
|
stub(Ability).find(123) { :some_ability }
|
14
14
|
CanCan::ControllerResource.new(@controller, :ability).find(123)
|
15
15
|
@controller.instance_variable_get(:@ability).should == :some_ability
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
it "should fetch model through parent and assign it to the instance" do
|
19
19
|
parent = Object.new
|
20
20
|
stub(parent).model_instance.stub!.abilities.stub!.find(123) { :some_ability }
|
21
21
|
CanCan::ControllerResource.new(@controller, :ability, parent).find(123)
|
22
22
|
@controller.instance_variable_get(:@ability).should == :some_ability
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it "should build model through model class and assign it to the instance" do
|
26
26
|
stub(Ability).new(123) { :some_ability }
|
27
27
|
CanCan::ControllerResource.new(@controller, :ability).build(123)
|
28
28
|
@controller.instance_variable_get(:@ability).should == :some_ability
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
it "should build model through parent and assign it to the instance" do
|
32
32
|
parent = Object.new
|
33
33
|
stub(parent).model_instance.stub!.abilities.stub!.build(123) { :some_ability }
|
34
34
|
CanCan::ControllerResource.new(@controller, :ability, parent).build(123)
|
35
35
|
@controller.instance_variable_get(:@ability).should == :some_ability
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
it "should not load resource if instance variable is already provided" do
|
39
39
|
@controller.instance_variable_set(:@ability, :some_ability)
|
40
40
|
CanCan::ControllerResource.new(@controller, :ability).find(123)
|
41
41
|
@controller.instance_variable_get(:@ability).should == :some_ability
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
it "should use the model class option if provided" do
|
45
45
|
stub(Person).find(123) { :some_resource }
|
46
46
|
CanCan::ControllerResource.new(@controller, :ability, nil, :resource => Person).find(123)
|
47
47
|
@controller.instance_variable_get(:@ability).should == :some_resource
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
it "should convert string to constant for resource" do
|
51
51
|
CanCan::ControllerResource.new(@controller, :ability, nil, :resource => "Person").model_class.should == Person
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
it "should raise an exception when specifying :class option since it is no longer used" do
|
55
55
|
lambda {
|
56
56
|
CanCan::ControllerResource.new(@controller, :ability, nil, :class => Person)
|
@@ -5,29 +5,29 @@ describe CanCan::AccessDenied do
|
|
5
5
|
before(:each) do
|
6
6
|
@exception = CanCan::AccessDenied.new(nil, :some_action, :some_subject)
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
it "should have action and subject accessors" do
|
10
10
|
@exception.action.should == :some_action
|
11
11
|
@exception.subject.should == :some_subject
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
it "should have a changable default message" do
|
15
15
|
@exception.message.should == "You are not authorized to access this page."
|
16
16
|
@exception.default_message = "Unauthorized!"
|
17
17
|
@exception.message.should == "Unauthorized!"
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
describe "with only a message" do
|
22
22
|
before(:each) do
|
23
23
|
@exception = CanCan::AccessDenied.new("Access denied!")
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
it "should have nil action and subject" do
|
27
27
|
@exception.action.should be_nil
|
28
28
|
@exception.subject.should be_nil
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
it "should have passed message" do
|
32
32
|
@exception.message.should == "Access denied!"
|
33
33
|
end
|
@@ -4,101 +4,112 @@ describe CanCan::ResourceAuthorization do
|
|
4
4
|
before(:each) do
|
5
5
|
@controller = Object.new # simple stub for now
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
it "should load the resource into an instance variable if params[:id] is specified" do
|
9
9
|
stub(Ability).find(123) { :some_resource }
|
10
10
|
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "show", :id => 123)
|
11
11
|
authorization.load_resource
|
12
12
|
@controller.instance_variable_get(:@ability).should == :some_resource
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
it "should properly load resource for namespaced controller" do
|
16
16
|
stub(Ability).find(123) { :some_resource }
|
17
17
|
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "admin/abilities", :action => "show", :id => 123)
|
18
18
|
authorization.load_resource
|
19
19
|
@controller.instance_variable_get(:@ability).should == :some_resource
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
it "should properly load resource for namespaced controller when using '::' for namespace" do
|
23
23
|
stub(Ability).find(123) { :some_resource }
|
24
24
|
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "Admin::AbilitiesController", :action => "show", :id => 123)
|
25
25
|
authorization.load_resource
|
26
26
|
@controller.instance_variable_get(:@ability).should == :some_resource
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
it "should build a new resource with hash if params[:id] is not specified" do
|
30
30
|
stub(Ability).new(:foo => "bar") { :some_resource }
|
31
31
|
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "create", :ability => {:foo => "bar"})
|
32
32
|
authorization.load_resource
|
33
33
|
@controller.instance_variable_get(:@ability).should == :some_resource
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
it "should build a new resource even if attribute hash isn't specified" do
|
37
37
|
stub(Ability).new(nil) { :some_resource }
|
38
38
|
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "new")
|
39
39
|
authorization.load_resource
|
40
40
|
@controller.instance_variable_get(:@ability).should == :some_resource
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
it "should not build a resource when on index action" do
|
44
44
|
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "index")
|
45
45
|
authorization.load_resource
|
46
46
|
@controller.instance_variable_get(:@ability).should be_nil
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
it "should perform authorization using controller action and loaded model" do
|
50
50
|
@controller.instance_variable_set(:@ability, :some_resource)
|
51
51
|
stub(@controller).authorize!(:show, :some_resource) { raise CanCan::AccessDenied }
|
52
52
|
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "show")
|
53
53
|
lambda { authorization.authorize_resource }.should raise_error(CanCan::AccessDenied)
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
it "should perform authorization using controller action and non loaded model" do
|
57
57
|
stub(@controller).authorize!(:show, Ability) { raise CanCan::AccessDenied }
|
58
58
|
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "show")
|
59
59
|
lambda { authorization.authorize_resource }.should raise_error(CanCan::AccessDenied)
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
it "should call load_resource and authorize_resource for load_and_authorize_resource" do
|
63
63
|
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "show")
|
64
64
|
mock(authorization).load_resource
|
65
65
|
mock(authorization).authorize_resource
|
66
66
|
authorization.load_and_authorize_resource
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
it "should not build a resource when on custom collection action" do
|
70
70
|
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "sort"}, {:collection => [:sort, :list]})
|
71
71
|
authorization.load_resource
|
72
72
|
@controller.instance_variable_get(:@ability).should be_nil
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
it "should build a resource when on custom new action even when params[:id] exists" do
|
76
76
|
stub(Ability).new(nil) { :some_resource }
|
77
77
|
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "build", :id => 123}, {:new => :build})
|
78
78
|
authorization.load_resource
|
79
79
|
@controller.instance_variable_get(:@ability).should == :some_resource
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
it "should not try to load resource for other action if params[:id] is undefined" do
|
83
83
|
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "list")
|
84
84
|
authorization.load_resource
|
85
85
|
@controller.instance_variable_get(:@ability).should be_nil
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
it "should load nested resource and fetch other resource through the association" do
|
89
|
-
|
89
|
+
person = Object.new
|
90
|
+
stub(Person).find(456) { person }
|
91
|
+
stub(person).abilities.stub!.find(123) { :some_ability }
|
90
92
|
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "show", :id => 123, :person_id => 456}, {:nested => :person})
|
91
93
|
authorization.load_resource
|
94
|
+
@controller.instance_variable_get(:@person).should == person
|
92
95
|
@controller.instance_variable_get(:@ability).should == :some_ability
|
93
96
|
end
|
94
|
-
|
97
|
+
|
98
|
+
it "should load nested resource for collection action" do
|
99
|
+
person = Object.new
|
100
|
+
stub(Person).find(456) { person }
|
101
|
+
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "index", :person_id => 456}, {:nested => :person})
|
102
|
+
authorization.load_resource
|
103
|
+
@controller.instance_variable_get(:@person).should == person
|
104
|
+
end
|
105
|
+
|
95
106
|
it "should load nested resource and build resource through a deep association" do
|
96
107
|
stub(Person).find(456).stub!.behaviors.stub!.find(789).stub!.abilities.stub!.build(nil) { :some_ability }
|
97
108
|
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "new", :person_id => 456, :behavior_id => 789}, {:nested => [:person, :behavior]})
|
98
109
|
authorization.load_resource
|
99
110
|
@controller.instance_variable_get(:@ability).should == :some_ability
|
100
111
|
end
|
101
|
-
|
112
|
+
|
102
113
|
it "should not load nested resource and build through this if *_id param isn't specified" do
|
103
114
|
stub(Person).find(456) { :some_person }
|
104
115
|
stub(Ability).new(nil) { :some_ability }
|
@@ -107,11 +118,18 @@ describe CanCan::ResourceAuthorization do
|
|
107
118
|
@controller.instance_variable_get(:@person).should == :some_person
|
108
119
|
@controller.instance_variable_get(:@ability).should == :some_ability
|
109
120
|
end
|
110
|
-
|
121
|
+
|
111
122
|
it "should load the model using a custom class" do
|
112
123
|
stub(Person).find(123) { :some_resource }
|
113
124
|
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "show", :id => 123}, {:resource => Person})
|
114
125
|
authorization.load_resource
|
115
126
|
@controller.instance_variable_get(:@ability).should == :some_resource
|
116
127
|
end
|
128
|
+
|
129
|
+
it "should use :name option to determine resource name" do
|
130
|
+
stub(Ability).find(123) { :some_resource }
|
131
|
+
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "foo", :action => "show", :id => 123}, {:name => :ability})
|
132
|
+
authorization.load_resource
|
133
|
+
@controller.instance_variable_get(:@ability).should == :some_resource
|
134
|
+
end
|
117
135
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 1.
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 1.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ryan Bates
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-07-16 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -29,6 +29,7 @@ extra_rdoc_files: []
|
|
29
29
|
files:
|
30
30
|
- lib/cancan/ability.rb
|
31
31
|
- lib/cancan/active_record_additions.rb
|
32
|
+
- lib/cancan/can_definition.rb
|
32
33
|
- lib/cancan/controller_additions.rb
|
33
34
|
- lib/cancan/controller_resource.rb
|
34
35
|
- lib/cancan/exceptions.rb
|
@@ -37,6 +38,7 @@ files:
|
|
37
38
|
- lib/cancan.rb
|
38
39
|
- spec/cancan/ability_spec.rb
|
39
40
|
- spec/cancan/active_record_additions_spec.rb
|
41
|
+
- spec/cancan/can_definition_spec.rb
|
40
42
|
- spec/cancan/controller_additions_spec.rb
|
41
43
|
- spec/cancan/controller_resource_spec.rb
|
42
44
|
- spec/cancan/exceptions_spec.rb
|