cancan 1.5.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -11,7 +11,7 @@ when "data_mapper"
11
11
  gem "dm-migrations", "~> 1.0.2"
12
12
  when "mongoid"
13
13
  gem "bson_ext", "~> 1.1"
14
- gem "mongoid", "~> 2.0.0.beta.19"
14
+ gem "mongoid", "~> 2.0.0.beta.20"
15
15
  else
16
16
  raise "Unknown model adapter: #{ENV["MODEL_ADAPTER"]}"
17
17
  end
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 controllers. 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 to customize this behavior.
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
- Next, make an +Ability+ class. CanCan 1.5 includes a generator for this.
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
- This is where the user permission will be defined. See the comments in models/ability.rb and {Defining Abilities}[https://github.com/ryanb/cancan/wiki/defining-abilities] for details.
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 "authorize!" method in the controller will raise an exception if the user is not able to perform the given action.
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 each action.
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+. Specs currently do not work in Ruby 1.9 due to the RR mocking framework. See the {spec/README}[https://github.com/ryanb/cancan/blob/master/spec/README.rdoc] for more information.
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[:error] = exception.message
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
- name = @model_class.reflect_on_association(name).table_name
39
- value = tableized_conditions(value)
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
- @model_class.where(conditions)
20
- end
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.first.conditions
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: 3
4
+ hash: 1
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 5
9
- - 0
10
- version: 1.5.0
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-11 00:00:00 -08:00
18
+ date: 2011-01-20 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency