cancan 1.5.0 → 1.5.1
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 +7 -0
- data/Gemfile +1 -1
- data/README.rdoc +17 -8
- data/lib/cancan/controller_additions.rb +1 -1
- data/lib/cancan/model_adapters/active_record_adapter.rb +4 -3
- data/lib/cancan/model_adapters/mongoid_adapter.rb +9 -12
- data/spec/cancan/model_adapters/active_record_adapter_spec.rb +18 -0
- data/spec/cancan/model_adapters/mongoid_adapter_spec.rb +18 -1
- metadata +4 -4
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
1.5.1 (January 20, 2011)
|
2
|
+
|
3
|
+
* Fixing deeply nested conditions in Active Record adapter - see issue #246
|
4
|
+
|
5
|
+
* Improving Mongoid support for multiple can and cannot definitions (thanks stellard) - see issue #239
|
6
|
+
|
7
|
+
|
1
8
|
1.5.0 (January 11, 2011)
|
2
9
|
|
3
10
|
* Added an Ability generator - see issue #170
|
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -7,7 +7,7 @@ CanCan is an authorization library for Ruby on Rails which restricts what resour
|
|
7
7
|
|
8
8
|
== Installation
|
9
9
|
|
10
|
-
In <b>Rails 3</b>, add this to your Gemfile.
|
10
|
+
In <b>Rails 3</b>, add this to your Gemfile and run the +bundle+ command.
|
11
11
|
|
12
12
|
gem "cancan"
|
13
13
|
|
@@ -22,13 +22,19 @@ Alternatively, you can install it as a plugin.
|
|
22
22
|
|
23
23
|
== Getting Started
|
24
24
|
|
25
|
-
CanCan expects a +current_user+ method to exist in
|
25
|
+
CanCan expects a +current_user+ method to exist in the controller. First, set up some authentication (such as Authlogic[https://github.com/binarylogic/authlogic] or Devise[https://github.com/plataformatec/devise]). See {Changing Defaults}[https://github.com/ryanb/cancan/wiki/changing-defaults] if you need different behavior.
|
26
26
|
|
27
|
-
|
27
|
+
|
28
|
+
=== 1. Define Abilities
|
29
|
+
|
30
|
+
User permissions are defined in an +Ability+ class. CanCan 1.5 includes a Rails 3 generator for creating this class.
|
28
31
|
|
29
32
|
rails g cancan:ability
|
30
33
|
|
31
|
-
|
34
|
+
See {Defining Abilities}[https://github.com/ryanb/cancan/wiki/defining-abilities] for details.
|
35
|
+
|
36
|
+
|
37
|
+
=== 2. Check Abilities & Authorization
|
32
38
|
|
33
39
|
The current user's permissions can then be checked using the <tt>can?</tt> and <tt>cannot?</tt> methods in the view and controller.
|
34
40
|
|
@@ -38,14 +44,14 @@ The current user's permissions can then be checked using the <tt>can?</tt> and <
|
|
38
44
|
|
39
45
|
See {Checking Abilities}[https://github.com/ryanb/cancan/wiki/checking-abilities] for more information
|
40
46
|
|
41
|
-
The
|
47
|
+
The <tt>authorize!</tt> method in the controller will raise an exception if the user is not able to perform the given action.
|
42
48
|
|
43
49
|
def show
|
44
50
|
@article = Article.find(params[:id])
|
45
51
|
authorize! :read, @article
|
46
52
|
end
|
47
53
|
|
48
|
-
Setting this for every action can be tedious, therefore the +load_and_authorize_resource+ method is provided to automatically authorize all actions in a RESTful style resource controller. It will use a before filter to load the resource into an instance variable and authorize it for
|
54
|
+
Setting this for every action can be tedious, therefore the +load_and_authorize_resource+ method is provided to automatically authorize all actions in a RESTful style resource controller. It will use a before filter to load the resource into an instance variable and authorize it for every action.
|
49
55
|
|
50
56
|
class ArticlesController < ApplicationController
|
51
57
|
load_and_authorize_resource
|
@@ -57,6 +63,9 @@ Setting this for every action can be tedious, therefore the +load_and_authorize_
|
|
57
63
|
|
58
64
|
See {Authorizing Controller Actions}[https://github.com/ryanb/cancan/wiki/authorizing-controller-actions] for more information.
|
59
65
|
|
66
|
+
|
67
|
+
=== 3. Handle Unauthorized Access
|
68
|
+
|
60
69
|
If the user authorization fails, a <tt>CanCan::AccessDenied</tt> exception will be raised. You can catch this and modify its behavior in the +ApplicationController+.
|
61
70
|
|
62
71
|
class ApplicationController < ActionController::Base
|
@@ -82,9 +91,9 @@ See {Exception Handling}[https://github.com/ryanb/cancan/wiki/exception-handling
|
|
82
91
|
|
83
92
|
== Questions or Problems?
|
84
93
|
|
85
|
-
If you have any issues with CanCan which you cannot find the solution to in the documentation, please add an {issue on GitHub}[https://github.com/ryanb/cancan/issues] or fork the project and send a pull request.
|
94
|
+
If you have any issues with CanCan which you cannot find the solution to in the documentation[https://github.com/ryanb/cancan/wiki], please add an {issue on GitHub}[https://github.com/ryanb/cancan/issues] or fork the project and send a pull request.
|
86
95
|
|
87
|
-
To get the specs running you should call +bundle+ and then +rake+.
|
96
|
+
To get the specs running you should call +bundle+ and then +rake+. See the {spec/README}[https://github.com/ryanb/cancan/blob/master/spec/README.rdoc] for more information.
|
88
97
|
|
89
98
|
|
90
99
|
== Special Thanks
|
@@ -294,7 +294,7 @@ module CanCan
|
|
294
294
|
#
|
295
295
|
# class ApplicationController < ActionController::Base
|
296
296
|
# rescue_from CanCan::AccessDenied do |exception|
|
297
|
-
# flash[:
|
297
|
+
# flash[:alert] = exception.message
|
298
298
|
# redirect_to root_url
|
299
299
|
# end
|
300
300
|
# end
|
@@ -31,12 +31,13 @@ module CanCan
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
def tableized_conditions(conditions)
|
34
|
+
def tableized_conditions(conditions, model_class = @model_class)
|
35
35
|
return conditions unless conditions.kind_of? Hash
|
36
36
|
conditions.inject({}) do |result_hash, (name, value)|
|
37
37
|
if value.kind_of? Hash
|
38
|
-
|
39
|
-
|
38
|
+
association_class = model_class.reflect_on_association(name).class_name.constantize
|
39
|
+
name = model_class.reflect_on_association(name).table_name
|
40
|
+
value = tableized_conditions(value, association_class)
|
40
41
|
end
|
41
42
|
result_hash[name] = value
|
42
43
|
result_hash
|
@@ -16,21 +16,18 @@ module CanCan
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def database_records
|
19
|
-
@
|
20
|
-
|
21
|
-
|
22
|
-
def conditions
|
23
|
-
if @rules.size == 0
|
24
|
-
false_query
|
19
|
+
if @rules.size == 0
|
20
|
+
@model_class.where(:_id => {'$exists' => false, '$type' => 7}) # return no records in Mongoid
|
25
21
|
else
|
26
|
-
@rules.
|
22
|
+
@rules.inject(@model_class.all) do |records, rule|
|
23
|
+
if rule.base_behavior
|
24
|
+
records.or(rule.conditions)
|
25
|
+
else
|
26
|
+
records.excludes(rule.conditions)
|
27
|
+
end
|
28
|
+
end
|
27
29
|
end
|
28
30
|
end
|
29
|
-
|
30
|
-
def false_query
|
31
|
-
# this query is sure to return no results
|
32
|
-
{:_id => {'$exists' => false, '$type' => 7}} # type 7 is an ObjectID (default for _id)
|
33
|
-
end
|
34
31
|
end
|
35
32
|
end
|
36
33
|
end
|
@@ -8,12 +8,23 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
|
|
8
8
|
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
9
9
|
|
10
10
|
describe CanCan::ModelAdapters::ActiveRecordAdapter do
|
11
|
+
with_model :category do
|
12
|
+
table do |t|
|
13
|
+
t.boolean "visible"
|
14
|
+
end
|
15
|
+
model do
|
16
|
+
has_many :articles
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
11
20
|
with_model :article do
|
12
21
|
table do |t|
|
13
22
|
t.boolean "published"
|
14
23
|
t.boolean "secret"
|
24
|
+
t.integer "category_id"
|
15
25
|
end
|
16
26
|
model do
|
27
|
+
belongs_to :category
|
17
28
|
has_many :comments
|
18
29
|
end
|
19
30
|
end
|
@@ -88,6 +99,13 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
|
|
88
99
|
Comment.accessible_by(@ability).should == [comment1]
|
89
100
|
end
|
90
101
|
|
102
|
+
it "should only read comments for visible categories through articles" do
|
103
|
+
@ability.can :read, Comment, :article => { :category => { :visible => true } }
|
104
|
+
comment1 = Comment.create!(:article => Article.create!(:category => Category.create!(:visible => true)))
|
105
|
+
comment2 = Comment.create!(:article => Article.create!(:category => Category.create!(:visible => false)))
|
106
|
+
Comment.accessible_by(@ability).should == [comment1]
|
107
|
+
end
|
108
|
+
|
91
109
|
it "should allow conditions in SQL and merge with hash conditions" do
|
92
110
|
@ability.can :read, Article, :published => true
|
93
111
|
@ability.can :read, Article, ["secret=?", true]
|
@@ -56,7 +56,7 @@ if ENV["MODEL_ADAPTER"] == "mongoid"
|
|
56
56
|
lord = MongoidProject.create(:title => 'Lord')
|
57
57
|
dude = MongoidProject.create(:title => 'Dude')
|
58
58
|
|
59
|
-
MongoidProject.accessible_by(@ability, :read).should == [sir]
|
59
|
+
MongoidProject.accessible_by(@ability, :read).entries.should == [sir]
|
60
60
|
end
|
61
61
|
|
62
62
|
it "should return everything when the defined ability is manage all" do
|
@@ -154,7 +154,24 @@ if ENV["MODEL_ADAPTER"] == "mongoid"
|
|
154
154
|
@ability.can :read, MongoidProject, :foo => {:bar => 1}
|
155
155
|
MongoidProject.accessible_by(@ability, :read).entries.first.should == obj
|
156
156
|
end
|
157
|
+
|
158
|
+
it "should exclude from the result if set to cannot" do
|
159
|
+
obj = MongoidProject.create(:bar => 1)
|
160
|
+
obj2 = MongoidProject.create(:bar => 2)
|
161
|
+
@ability.can :read, MongoidProject
|
162
|
+
@ability.cannot :read, MongoidProject, :bar => 2
|
163
|
+
MongoidProject.accessible_by(@ability, :read).entries.should == [obj]
|
164
|
+
end
|
157
165
|
|
166
|
+
it "should combine the rules" do
|
167
|
+
obj = MongoidProject.create(:bar => 1)
|
168
|
+
obj2 = MongoidProject.create(:bar => 2)
|
169
|
+
obj3 = MongoidProject.create(:bar => 3)
|
170
|
+
@ability.can :read, MongoidProject, :bar => 1
|
171
|
+
@ability.can :read, MongoidProject, :bar => 2
|
172
|
+
MongoidProject.accessible_by(@ability, :read).entries.should =~ [obj, obj2]
|
173
|
+
end
|
174
|
+
|
158
175
|
it "should not allow to fetch records when ability with just block present" do
|
159
176
|
@ability.can :read, MongoidProject do
|
160
177
|
false
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cancan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 5
|
9
|
-
-
|
10
|
-
version: 1.5.
|
9
|
+
- 1
|
10
|
+
version: 1.5.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ryan Bates
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-20 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|