cancan 1.2.0 → 1.3.2
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 +38 -0
- data/README.rdoc +14 -9
- data/Rakefile +12 -12
- data/lib/cancan.rb +1 -1
- data/lib/cancan/ability.rb +32 -35
- data/lib/cancan/active_record_additions.rb +3 -4
- data/lib/cancan/can_definition.rb +37 -47
- data/lib/cancan/controller_additions.rb +58 -26
- data/lib/cancan/controller_resource.rb +115 -40
- data/lib/cancan/query.rb +97 -0
- data/spec/cancan/ability_spec.rb +94 -43
- data/spec/cancan/active_record_additions_spec.rb +27 -4
- data/spec/cancan/can_definition_spec.rb +7 -7
- data/spec/cancan/controller_additions_spec.rb +12 -6
- data/spec/cancan/controller_resource_spec.rb +218 -26
- data/spec/cancan/query_spec.rb +107 -0
- data/spec/matchers.rb +13 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +25 -1
- metadata +10 -17
- data/lib/cancan/resource_authorization.rb +0 -70
- data/spec/cancan/resource_authorization_spec.rb +0 -135
data/spec/matchers.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Spec::Matchers.define :orderlessly_match do |original_string|
|
2
|
+
match do |given_string|
|
3
|
+
original_string.split('').sort == given_string.split('').sort
|
4
|
+
end
|
5
|
+
|
6
|
+
failure_message_for_should do |given_string|
|
7
|
+
"expected \"#{given_string}\" to have the same characters as \"#{original_string}\""
|
8
|
+
end
|
9
|
+
|
10
|
+
failure_message_for_should_not do |given_string|
|
11
|
+
"expected \"#{given_string}\" not to have the same characters as \"#{original_string}\""
|
12
|
+
end
|
13
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
CHANGED
@@ -4,6 +4,7 @@ require 'active_support'
|
|
4
4
|
require 'active_record'
|
5
5
|
require 'action_controller'
|
6
6
|
require 'action_view'
|
7
|
+
require 'matchers'
|
7
8
|
require 'cancan'
|
8
9
|
require 'cancan/matchers'
|
9
10
|
|
@@ -18,6 +19,29 @@ class Ability
|
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
21
|
-
# this class helps out in testing
|
22
|
+
# this class helps out in testing SQL conditions
|
22
23
|
class Person
|
24
|
+
class << self
|
25
|
+
protected
|
26
|
+
|
27
|
+
def sanitize_sql(hash_cond)
|
28
|
+
case hash_cond
|
29
|
+
when Hash
|
30
|
+
sanitize_hash(hash_cond).join(' AND ')
|
31
|
+
when Array
|
32
|
+
hash_cond.shift.gsub('?'){"#{hash_cond.shift.inspect}"}
|
33
|
+
when String then hash_cond
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def sanitize_hash(hash)
|
38
|
+
hash.map do |name, value|
|
39
|
+
if Hash === value
|
40
|
+
sanitize_hash(value).map{|cond| "#{name}.#{cond}"}
|
41
|
+
else
|
42
|
+
"#{name}=#{value}"
|
43
|
+
end
|
44
|
+
end.flatten
|
45
|
+
end
|
46
|
+
end
|
23
47
|
end
|
metadata
CHANGED
@@ -1,12 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cancan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
segments:
|
6
|
-
- 1
|
7
|
-
- 2
|
8
|
-
- 0
|
9
|
-
version: 1.2.0
|
4
|
+
version: 1.3.2
|
10
5
|
platform: ruby
|
11
6
|
authors:
|
12
7
|
- Ryan Bates
|
@@ -14,11 +9,11 @@ autorequire:
|
|
14
9
|
bindir: bin
|
15
10
|
cert_chain: []
|
16
11
|
|
17
|
-
date: 2010-07
|
12
|
+
date: 2010-08-07 00:00:00 -07:00
|
18
13
|
default_executable:
|
19
14
|
dependencies: []
|
20
15
|
|
21
|
-
description: Simple authorization solution for Rails which is
|
16
|
+
description: Simple authorization solution for Rails which is decoupled from user roles. All permissions are stored in a single location.
|
22
17
|
email: ryan@railscasts.com
|
23
18
|
executables: []
|
24
19
|
|
@@ -34,7 +29,7 @@ files:
|
|
34
29
|
- lib/cancan/controller_resource.rb
|
35
30
|
- lib/cancan/exceptions.rb
|
36
31
|
- lib/cancan/matchers.rb
|
37
|
-
- lib/cancan/
|
32
|
+
- lib/cancan/query.rb
|
38
33
|
- lib/cancan.rb
|
39
34
|
- spec/cancan/ability_spec.rb
|
40
35
|
- spec/cancan/active_record_additions_spec.rb
|
@@ -43,7 +38,9 @@ files:
|
|
43
38
|
- spec/cancan/controller_resource_spec.rb
|
44
39
|
- spec/cancan/exceptions_spec.rb
|
45
40
|
- spec/cancan/matchers_spec.rb
|
46
|
-
- spec/cancan/
|
41
|
+
- spec/cancan/query_spec.rb
|
42
|
+
- spec/matchers.rb
|
43
|
+
- spec/spec.opts
|
47
44
|
- spec/spec_helper.rb
|
48
45
|
- CHANGELOG.rdoc
|
49
46
|
- LICENSE
|
@@ -63,22 +60,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
63
60
|
requirements:
|
64
61
|
- - ">="
|
65
62
|
- !ruby/object:Gem::Version
|
66
|
-
segments:
|
67
|
-
- 0
|
68
63
|
version: "0"
|
64
|
+
version:
|
69
65
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
66
|
requirements:
|
71
67
|
- - ">="
|
72
68
|
- !ruby/object:Gem::Version
|
73
|
-
segments:
|
74
|
-
- 1
|
75
|
-
- 3
|
76
|
-
- 4
|
77
69
|
version: 1.3.4
|
70
|
+
version:
|
78
71
|
requirements: []
|
79
72
|
|
80
73
|
rubyforge_project: cancan
|
81
|
-
rubygems_version: 1.3.
|
74
|
+
rubygems_version: 1.3.5
|
82
75
|
signing_key:
|
83
76
|
specification_version: 3
|
84
77
|
summary: Simple authorization solution for Rails.
|
@@ -1,70 +0,0 @@
|
|
1
|
-
module CanCan
|
2
|
-
# Handle the load and authorization controller logic so we don't clutter up all controllers with non-interface methods.
|
3
|
-
# This class is used internally, so you do not need to call methods directly on it.
|
4
|
-
class ResourceAuthorization # :nodoc:
|
5
|
-
def self.add_before_filter(controller_class, method, options = {})
|
6
|
-
controller_class.before_filter(options.slice(:only, :except)) do |controller|
|
7
|
-
ResourceAuthorization.new(controller, controller.params, options.except(:only, :except)).send(method)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize(controller, params, options = {})
|
12
|
-
@controller = controller
|
13
|
-
@params = params
|
14
|
-
@options = options
|
15
|
-
end
|
16
|
-
|
17
|
-
def load_and_authorize_resource
|
18
|
-
load_resource
|
19
|
-
authorize_resource
|
20
|
-
end
|
21
|
-
|
22
|
-
def load_resource
|
23
|
-
if collection_actions.include? @params[:action].to_sym
|
24
|
-
parent_resource
|
25
|
-
else
|
26
|
-
if new_actions.include? @params[:action].to_sym
|
27
|
-
resource.build(@params[model_name.to_sym])
|
28
|
-
elsif @params[:id]
|
29
|
-
resource.find(@params[:id])
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def authorize_resource
|
35
|
-
@controller.authorize!(@params[:action].to_sym, resource.model_instance || resource.model_class)
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def resource
|
41
|
-
@resource ||= ControllerResource.new(@controller, model_name, parent_resource, @options)
|
42
|
-
end
|
43
|
-
|
44
|
-
def parent_resource
|
45
|
-
parent = nil
|
46
|
-
[@options[:nested]].flatten.compact.each do |name|
|
47
|
-
id = @params["#{name}_id".to_sym]
|
48
|
-
if id
|
49
|
-
parent = ControllerResource.new(@controller, name, parent)
|
50
|
-
parent.find(id)
|
51
|
-
else
|
52
|
-
parent = nil
|
53
|
-
end
|
54
|
-
end
|
55
|
-
parent
|
56
|
-
end
|
57
|
-
|
58
|
-
def model_name
|
59
|
-
@options[:name] || @params[:controller].sub("Controller", "").underscore.split('/').last.singularize
|
60
|
-
end
|
61
|
-
|
62
|
-
def collection_actions
|
63
|
-
[:index] + [@options[:collection]].flatten
|
64
|
-
end
|
65
|
-
|
66
|
-
def new_actions
|
67
|
-
[:new, :create] + [@options[:new]].flatten
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
@@ -1,135 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe CanCan::ResourceAuthorization do
|
4
|
-
before(:each) do
|
5
|
-
@controller = Object.new # simple stub for now
|
6
|
-
end
|
7
|
-
|
8
|
-
it "should load the resource into an instance variable if params[:id] is specified" do
|
9
|
-
stub(Ability).find(123) { :some_resource }
|
10
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "show", :id => 123)
|
11
|
-
authorization.load_resource
|
12
|
-
@controller.instance_variable_get(:@ability).should == :some_resource
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should properly load resource for namespaced controller" do
|
16
|
-
stub(Ability).find(123) { :some_resource }
|
17
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "admin/abilities", :action => "show", :id => 123)
|
18
|
-
authorization.load_resource
|
19
|
-
@controller.instance_variable_get(:@ability).should == :some_resource
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should properly load resource for namespaced controller when using '::' for namespace" do
|
23
|
-
stub(Ability).find(123) { :some_resource }
|
24
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "Admin::AbilitiesController", :action => "show", :id => 123)
|
25
|
-
authorization.load_resource
|
26
|
-
@controller.instance_variable_get(:@ability).should == :some_resource
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should build a new resource with hash if params[:id] is not specified" do
|
30
|
-
stub(Ability).new(:foo => "bar") { :some_resource }
|
31
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "create", :ability => {:foo => "bar"})
|
32
|
-
authorization.load_resource
|
33
|
-
@controller.instance_variable_get(:@ability).should == :some_resource
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should build a new resource even if attribute hash isn't specified" do
|
37
|
-
stub(Ability).new(nil) { :some_resource }
|
38
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "new")
|
39
|
-
authorization.load_resource
|
40
|
-
@controller.instance_variable_get(:@ability).should == :some_resource
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should not build a resource when on index action" do
|
44
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "index")
|
45
|
-
authorization.load_resource
|
46
|
-
@controller.instance_variable_get(:@ability).should be_nil
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should perform authorization using controller action and loaded model" do
|
50
|
-
@controller.instance_variable_set(:@ability, :some_resource)
|
51
|
-
stub(@controller).authorize!(:show, :some_resource) { raise CanCan::AccessDenied }
|
52
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "show")
|
53
|
-
lambda { authorization.authorize_resource }.should raise_error(CanCan::AccessDenied)
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should perform authorization using controller action and non loaded model" do
|
57
|
-
stub(@controller).authorize!(:show, Ability) { raise CanCan::AccessDenied }
|
58
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "show")
|
59
|
-
lambda { authorization.authorize_resource }.should raise_error(CanCan::AccessDenied)
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should call load_resource and authorize_resource for load_and_authorize_resource" do
|
63
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "show")
|
64
|
-
mock(authorization).load_resource
|
65
|
-
mock(authorization).authorize_resource
|
66
|
-
authorization.load_and_authorize_resource
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should not build a resource when on custom collection action" do
|
70
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "sort"}, {:collection => [:sort, :list]})
|
71
|
-
authorization.load_resource
|
72
|
-
@controller.instance_variable_get(:@ability).should be_nil
|
73
|
-
end
|
74
|
-
|
75
|
-
it "should build a resource when on custom new action even when params[:id] exists" do
|
76
|
-
stub(Ability).new(nil) { :some_resource }
|
77
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "build", :id => 123}, {:new => :build})
|
78
|
-
authorization.load_resource
|
79
|
-
@controller.instance_variable_get(:@ability).should == :some_resource
|
80
|
-
end
|
81
|
-
|
82
|
-
it "should not try to load resource for other action if params[:id] is undefined" do
|
83
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, :controller => "abilities", :action => "list")
|
84
|
-
authorization.load_resource
|
85
|
-
@controller.instance_variable_get(:@ability).should be_nil
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should load nested resource and fetch other resource through the association" do
|
89
|
-
person = Object.new
|
90
|
-
stub(Person).find(456) { person }
|
91
|
-
stub(person).abilities.stub!.find(123) { :some_ability }
|
92
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "show", :id => 123, :person_id => 456}, {:nested => :person})
|
93
|
-
authorization.load_resource
|
94
|
-
@controller.instance_variable_get(:@person).should == person
|
95
|
-
@controller.instance_variable_get(:@ability).should == :some_ability
|
96
|
-
end
|
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
|
-
|
106
|
-
it "should load nested resource and build resource through a deep association" do
|
107
|
-
stub(Person).find(456).stub!.behaviors.stub!.find(789).stub!.abilities.stub!.build(nil) { :some_ability }
|
108
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "new", :person_id => 456, :behavior_id => 789}, {:nested => [:person, :behavior]})
|
109
|
-
authorization.load_resource
|
110
|
-
@controller.instance_variable_get(:@ability).should == :some_ability
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should not load nested resource and build through this if *_id param isn't specified" do
|
114
|
-
stub(Person).find(456) { :some_person }
|
115
|
-
stub(Ability).new(nil) { :some_ability }
|
116
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "new", :person_id => 456}, {:nested => [:person, :behavior]})
|
117
|
-
authorization.load_resource
|
118
|
-
@controller.instance_variable_get(:@person).should == :some_person
|
119
|
-
@controller.instance_variable_get(:@ability).should == :some_ability
|
120
|
-
end
|
121
|
-
|
122
|
-
it "should load the model using a custom class" do
|
123
|
-
stub(Person).find(123) { :some_resource }
|
124
|
-
authorization = CanCan::ResourceAuthorization.new(@controller, {:controller => "abilities", :action => "show", :id => 123}, {:resource => Person})
|
125
|
-
authorization.load_resource
|
126
|
-
@controller.instance_variable_get(:@ability).should == :some_resource
|
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
|
135
|
-
end
|