adding skip load and authorize behavior - closes #164

This commit is contained in:
Ryan Bates
2011-01-08 12:04:55 -08:00
parent 71ceb83ded
commit 57327119a8
5 changed files with 156 additions and 7 deletions

View File

@@ -166,6 +166,52 @@ module CanCan
cancan_resource_class.add_before_filter(self, :authorize_resource, *args)
end
# Skip both the loading and authorization behavior of CanCan for this given controller. This is primarily
# useful to skip the behavior of a superclass. You can pass :only and :except options to specify which actions
# to skip the effects on. It will apply to all actions by default.
#
# class ProjectsController < SomeOtherController
# skip_load_and_authorize_resource :only => :index
# end
#
# You can also pass the resource name as the first argument to skip that resource.
def skip_load_and_authorize_resource(*args)
skip_load_resource(*args)
skip_authorize_resource(*args)
end
# Skip both the loading behavior of CanCan. This is useful when using +load_and_authorize_resource+ but want to
# only do authorization on certain actions. You can pass :only and :except options to specify which actions to
# skip the effects on. It will apply to all actions by default.
#
# class ProjectsController < ApplicationController
# load_and_authorize_resource
# skip_load_resource :only => :index
# end
#
# You can also pass the resource name as the first argument to skip that resource.
def skip_load_resource(*args)
options = args.extract_options!
name = args.first
cancan_skipper[:load][name] = options
end
# Skip both the authorization behavior of CanCan. This is useful when using +load_and_authorize_resource+ but want to
# only do loading on certain actions. You can pass :only and :except options to specify which actions to
# skip the effects on. It will apply to all actions by default.
#
# class ProjectsController < ApplicationController
# load_and_authorize_resource
# skip_authorize_resource :only => :index
# end
#
# You can also pass the resource name as the first argument to skip that resource.
def skip_authorize_resource(*args)
options = args.extract_options!
name = args.first
cancan_skipper[:authorize][name] = options
end
# Add this to a controller to ensure it performs authorization through +authorized+! or +authorize_resource+ call.
# If neither of these authorization methods are called, a CanCan::AuthorizationNotPerformed exception will be raised.
# This is normally added to the ApplicationController to ensure all controller actions do authorization.
@@ -209,6 +255,10 @@ module CanCan
ControllerResource
end
end
def cancan_skipper
@_cancan_skipper ||= {:authorize => {}, :load => {}}
end
end
def self.included(base)

View File

@@ -26,21 +26,38 @@ module CanCan
end
def load_resource
if load_instance?
self.resource_instance ||= load_resource_instance
elsif load_collection?
self.collection_instance ||= load_collection
unless skip?(:load)
if load_instance?
self.resource_instance ||= load_resource_instance
elsif load_collection?
self.collection_instance ||= load_collection
end
end
end
def authorize_resource
@controller.authorize!(authorization_action, resource_instance || resource_class_with_parent)
unless skip?(:authorize)
@controller.authorize!(authorization_action, resource_instance || resource_class_with_parent)
end
end
def parent?
@options.has_key?(:parent) ? @options[:parent] : @name && @name != name_from_controller.to_sym
end
def skip?(behavior) # This could probably use some refactoring
options = @controller.class.cancan_skipper[behavior][@name]
if options.nil?
false
elsif options == {}
true
elsif options[:except] && ![options[:except]].flatten.include?(@params[:action].to_sym)
true
elsif [options[:only]].flatten.include?(@params[:action].to_sym)
true
end
end
protected
def load_resource_instance