filling in some inline documentation for 1.4
This commit is contained in:
parent
1af6c6f395
commit
bf9b8ad1a6
|
@ -1,3 +1,22 @@
|
||||||
|
1.4.0 (not yet released)
|
||||||
|
|
||||||
|
* Adding check_authorization and skip_authorization controller class methods to ensure authorization is performed (thanks justinko) - see issue #135
|
||||||
|
|
||||||
|
* Setting initial attributes based on ability conditions in new/create actions - see issue #114
|
||||||
|
|
||||||
|
* Check parent attributes for nested association in index action - see issue #121
|
||||||
|
|
||||||
|
* Supporting nesting in can? method using hash - see issue #121
|
||||||
|
|
||||||
|
* Adding I18n support for Access Denied messages (thanks EppO) - see issue #103
|
||||||
|
|
||||||
|
* Passing no arguments to +can+ definition will pass action, class, and object to block - see issue #129
|
||||||
|
|
||||||
|
* Don't pass action to block in +can+ definition when using :+manage+ option - see issue #129
|
||||||
|
|
||||||
|
* No longer calling block in +can+ definition when checking on class - see issue #116
|
||||||
|
|
||||||
|
|
||||||
1.3.4 (August 31, 2010)
|
1.3.4 (August 31, 2010)
|
||||||
|
|
||||||
* Don't stop at +cannot+ with hash conditions when checking class (thanks tamoya) - see issue #131
|
* Don't stop at +cannot+ with hash conditions when checking class (thanks tamoya) - see issue #131
|
||||||
|
|
2
Rakefile
2
Rakefile
|
@ -10,4 +10,4 @@ Spec::Rake::SpecTask.new do |t|
|
||||||
t.spec_opts = ["-c"]
|
t.spec_opts = ["-c"]
|
||||||
end
|
end
|
||||||
|
|
||||||
task :default => :spec
|
task :default => :spec
|
||||||
|
|
|
@ -16,7 +16,7 @@ module CanCan
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
module Ability
|
module Ability
|
||||||
# Use to check if the user has permission to perform a given action on an object.
|
# Check if the user has permission to perform a given action on an object.
|
||||||
#
|
#
|
||||||
# can? :destroy, @project
|
# can? :destroy, @project
|
||||||
#
|
#
|
||||||
|
@ -24,6 +24,11 @@ module CanCan
|
||||||
#
|
#
|
||||||
# can? :create, Project
|
# can? :create, Project
|
||||||
#
|
#
|
||||||
|
# Nested resources can be passed through a hash, this way conditions which are
|
||||||
|
# dependent upon the association will work when using a class.
|
||||||
|
#
|
||||||
|
# can? :create, @category => Project
|
||||||
|
#
|
||||||
# Any additional arguments will be passed into the "can" block definition. This
|
# Any additional arguments will be passed into the "can" block definition. This
|
||||||
# can be used to pass more information about the user's request for example.
|
# can be used to pass more information about the user's request for example.
|
||||||
#
|
#
|
||||||
|
@ -69,53 +74,53 @@ module CanCan
|
||||||
# can :update, Article
|
# can :update, Article
|
||||||
#
|
#
|
||||||
# You can pass an array for either of these parameters to match any one.
|
# You can pass an array for either of these parameters to match any one.
|
||||||
|
# Here the user has the ability to update or destroy both articles and comments.
|
||||||
#
|
#
|
||||||
# can [:update, :destroy], [Article, Comment]
|
# can [:update, :destroy], [Article, Comment]
|
||||||
#
|
#
|
||||||
# In this case the user has the ability to update or destroy both articles and comments.
|
# You can pass :all to match any object and :manage to match any action. Here are some examples.
|
||||||
#
|
#
|
||||||
# You can pass a hash of conditions as the third argument.
|
# can :manage, :all
|
||||||
|
# can :update, :all
|
||||||
|
# can :manage, Project
|
||||||
|
#
|
||||||
|
# You can pass a hash of conditions as the third argument. Here the user can only see active projects which he owns.
|
||||||
#
|
#
|
||||||
# can :read, Project, :active => true, :user_id => user.id
|
# can :read, Project, :active => true, :user_id => user.id
|
||||||
#
|
#
|
||||||
# Here the user can only see active projects which he owns. See ActiveRecordAdditions#accessible_by
|
# See ActiveRecordAdditions#accessible_by for how to use this in database queries. These conditions
|
||||||
# for how to use this in database queries.
|
# are also used for initial attributes when building a record in ControllerAdditions#load_resource.
|
||||||
#
|
#
|
||||||
# If the conditions hash does not give you enough control over defining abilities, you can use a block to
|
# If the conditions hash does not give you enough control over defining abilities, you can use a block
|
||||||
# write any Ruby code you want.
|
# along with any Ruby code you want.
|
||||||
#
|
#
|
||||||
# can :update, Project do |project|
|
# can :update, Project do |project|
|
||||||
# project && project.groups.include?(user.group)
|
# project.groups.include?(user.group)
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# If the block returns true then the user has that :update ability for that project, otherwise he
|
# If the block returns true then the user has that :update ability for that project, otherwise he
|
||||||
# will be denied access. It's possible for the passed in model to be nil if one isn't specified,
|
# will be denied access. The downside to using a block is that it cannot be used to generate
|
||||||
# so be sure to take that into consideration.
|
# conditions for database queries.
|
||||||
#
|
#
|
||||||
# The downside to using a block is that it cannot be used to generate conditions for database queries.
|
# You can pass custom objects into this "can" method, this is usually done with a symbol
|
||||||
#
|
|
||||||
# You can pass :all to reference every type of object. In this case the object type will be passed
|
|
||||||
# into the block as well (just in case object is nil).
|
|
||||||
#
|
|
||||||
# can :read, :all do |object_class, object|
|
|
||||||
# object_class != Order
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# Here the user has permission to read all objects except orders.
|
|
||||||
#
|
|
||||||
# You can also pass :manage as the action which will match any action. In this case the action is
|
|
||||||
# passed to the block.
|
|
||||||
#
|
|
||||||
# can :manage, Comment do |action, comment|
|
|
||||||
# action != :destroy
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# You can pass custom objects into this "can" method, this is usually done through a symbol
|
|
||||||
# and is useful if a class isn't available to define permissions on.
|
# and is useful if a class isn't available to define permissions on.
|
||||||
#
|
#
|
||||||
# can :read, :stats
|
# can :read, :stats
|
||||||
# can? :read, :stats # => true
|
# can? :read, :stats # => true
|
||||||
#
|
#
|
||||||
|
# IMPORTANT: Neither a hash of conditions or a block will be used when checking permission on a class.
|
||||||
|
#
|
||||||
|
# can :update, Project, :priority => 3
|
||||||
|
# can? :update, Project # => true
|
||||||
|
#
|
||||||
|
# If you pass no arguments to +can+, the action, class, and object will be passed to the block and the
|
||||||
|
# block will always be executed. This allows you to override the full behavior if the permissions are
|
||||||
|
# defined in an external source such as the database.
|
||||||
|
#
|
||||||
|
# can do |action, object_class, object|
|
||||||
|
# # check the database and return true/false
|
||||||
|
# end
|
||||||
|
#
|
||||||
def can(action = nil, subject = nil, conditions = nil, &block)
|
def can(action = nil, subject = nil, conditions = nil, &block)
|
||||||
can_definitions << CanDefinition.new(true, action, subject, conditions, block)
|
can_definitions << CanDefinition.new(true, action, subject, conditions, block)
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,6 +21,10 @@ module CanCan
|
||||||
# Article.new(params[:article]) depending upon the action. It does nothing for the "index"
|
# Article.new(params[:article]) depending upon the action. It does nothing for the "index"
|
||||||
# action.
|
# action.
|
||||||
#
|
#
|
||||||
|
# If a conditions hash is used in the Ability, the +new+ and +create+ actions will set
|
||||||
|
# the initial attributes based on these conditions. This way these actions will satisfy
|
||||||
|
# the ability restrictions.
|
||||||
|
#
|
||||||
# Call this method directly on the controller class.
|
# Call this method directly on the controller class.
|
||||||
#
|
#
|
||||||
# class BooksController < ApplicationController
|
# class BooksController < ApplicationController
|
||||||
|
@ -148,23 +152,44 @@ module CanCan
|
||||||
# [:+instance_name+]
|
# [:+instance_name+]
|
||||||
# The name of the instance variable for this resource.
|
# The name of the instance variable for this resource.
|
||||||
#
|
#
|
||||||
|
# [:+through+]
|
||||||
|
# Authorize conditions on this parent resource when instance isn't available.
|
||||||
|
#
|
||||||
def authorize_resource(*args)
|
def authorize_resource(*args)
|
||||||
ControllerResource.add_before_filter(self, :authorize_resource, *args)
|
ControllerResource.add_before_filter(self, :authorize_resource, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
def skip_authorization(*args)
|
# Add this to a controller to ensure it performs authorization through +authorized+! or +authorize_resource+ call.
|
||||||
self.before_filter(*args) do |controller|
|
# If neither of these authorization methods are called, a CanCan::AuthorizationNotPerformed exception will be raised.
|
||||||
controller.instance_variable_set(:@_authorized, true)
|
# This is normally added to the ApplicationController to ensure all controller actions do authorization.
|
||||||
end
|
#
|
||||||
end
|
# class ApplicationController < ActionController::Base
|
||||||
|
# check_authorization
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Any arguments are passed to the +after_filter+ it triggers.
|
||||||
|
#
|
||||||
|
# See skip_authorization to bypass this check on specific controller actions.
|
||||||
def check_authorization(*args)
|
def check_authorization(*args)
|
||||||
self.after_filter(*args) do |controller|
|
self.after_filter(*args) do |controller|
|
||||||
unless controller.instance_variable_defined?(:@_authorized)
|
unless controller.instance_variable_defined?(:@_authorized)
|
||||||
raise AuthorizationNotPerformed, "This action does not authorize the user. Add authorize! or authorize_resource to the controller."
|
raise AuthorizationNotPerformed, "This action failed the check_authorization because it does not authorize_resource. Add skip_authorization to bypass this check."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Call this in the class of a controller to skip the check_authorization behavior on the actions.
|
||||||
|
#
|
||||||
|
# class HomeController < ApplicationController
|
||||||
|
# skip_authorization :only => :index
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Any arguments are passed to the +before_filter+ it triggers.
|
||||||
|
def skip_authorization(*args)
|
||||||
|
self.before_filter(*args) do |controller|
|
||||||
|
controller.instance_variable_set(:@_authorized, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.included(base)
|
def self.included(base)
|
||||||
|
@ -185,6 +210,16 @@ module CanCan
|
||||||
#
|
#
|
||||||
# authorize! :read, @article, :message => "Not authorized to read #{@article.name}"
|
# authorize! :read, @article, :message => "Not authorized to read #{@article.name}"
|
||||||
#
|
#
|
||||||
|
# You can also use I18n to customize the message. Action aliases defined in Ability work here.
|
||||||
|
#
|
||||||
|
# en:
|
||||||
|
# unauthorized:
|
||||||
|
# manage:
|
||||||
|
# all: "Not authorized to perform that action."
|
||||||
|
# user: "Not allowed to manage other user accounts."
|
||||||
|
# update:
|
||||||
|
# project: "Not allowed to update this project."
|
||||||
|
#
|
||||||
# You can rescue from the exception in the controller to customize how unauthorized
|
# You can rescue from the exception in the controller to customize how unauthorized
|
||||||
# access is displayed to the user.
|
# access is displayed to the user.
|
||||||
#
|
#
|
||||||
|
@ -234,6 +269,13 @@ module CanCan
|
||||||
# <%= link_to "New Project", new_project_path %>
|
# <%= link_to "New Project", new_project_path %>
|
||||||
# <% end %>
|
# <% end %>
|
||||||
#
|
#
|
||||||
|
# If it's a nested resource, you can pass the parent instance in a hash. This way it will
|
||||||
|
# check conditions which reach through that association.
|
||||||
|
#
|
||||||
|
# <% if can? :create, @category => Project %>
|
||||||
|
# <%= link_to "New Project", new_project_path %>
|
||||||
|
# <% end %>
|
||||||
|
#
|
||||||
# This simply calls "can?" on the current_ability. See Ability#can?.
|
# This simply calls "can?" on the current_ability. See Ability#can?.
|
||||||
def can?(*args)
|
def can?(*args)
|
||||||
current_ability.can?(*args)
|
current_ability.can?(*args)
|
||||||
|
|
|
@ -27,7 +27,8 @@ module CanCan
|
||||||
# exception.default_message = "Default error message"
|
# exception.default_message = "Default error message"
|
||||||
# exception.message # => "Default error message"
|
# exception.message # => "Default error message"
|
||||||
#
|
#
|
||||||
# See ControllerAdditions#authorized! for more information on rescuing from this exception.
|
# See ControllerAdditions#authorized! for more information on rescuing from this exception
|
||||||
|
# and customizing the message using I18n.
|
||||||
class AccessDenied < Error
|
class AccessDenied < Error
|
||||||
attr_reader :action, :subject
|
attr_reader :action, :subject
|
||||||
attr_writer :default_message
|
attr_writer :default_message
|
||||||
|
|
Loading…
Reference in New Issue
Block a user