changing the interface for ControllerResource load/authorize so they can be intertwined

This commit is contained in:
Ryan Bates 2011-05-19 16:38:33 -04:00
parent e24d5d146b
commit a29e31606b
5 changed files with 74 additions and 114 deletions

View File

@ -12,7 +12,7 @@ module CanCan
# end # end
# #
def load_and_authorize_resource(*args) def load_and_authorize_resource(*args)
cancan_resource_class.add_before_filter(self, :load_and_authorize_resource, *args) cancan_resource_class.add_before_filter(self, {:load => true, :authorize => true}, *args)
end end
# Sets up a before filter which loads the model resource into an instance variable. # Sets up a before filter which loads the model resource into an instance variable.
@ -114,7 +114,7 @@ module CanCan
# #
def load_resource(*args) def load_resource(*args)
raise ImplementationRemoved, "The load_resource method has been removed, use load_and_authorize_resource instead." raise ImplementationRemoved, "The load_resource method has been removed, use load_and_authorize_resource instead."
cancan_resource_class.add_before_filter(self, :load_resource, *args) cancan_resource_class.add_before_filter(self, {:load => true}, *args)
end end
# Sets up a before filter which authorizes the resource using the instance variable. # Sets up a before filter which authorizes the resource using the instance variable.
@ -171,7 +171,7 @@ module CanCan
# #
def authorize_resource(*args) def authorize_resource(*args)
raise ImplementationRemoved, "The authorize_resource method has been removed, use load_and_authorize_resource instead." raise ImplementationRemoved, "The authorize_resource method has been removed, use load_and_authorize_resource instead."
cancan_resource_class.add_before_filter(self, :authorize_resource, *args) cancan_resource_class.add_before_filter(self, {:authorize => true}, *args)
end end
# Skip both the loading and authorization behavior of CanCan for this given controller. This is primarily # Skip both the loading and authorization behavior of CanCan for this given controller. This is primarily

View File

@ -2,12 +2,12 @@ module CanCan
# Handle the load and authorization controller logic so we don't clutter up all controllers with non-interface methods. # Handle the load and authorization controller logic so we don't clutter up all controllers with non-interface methods.
# This class is used internally, so you do not need to call methods directly on it. # This class is used internally, so you do not need to call methods directly on it.
class ControllerResource # :nodoc: class ControllerResource # :nodoc:
def self.add_before_filter(controller_class, method, *args) def self.add_before_filter(controller_class, behavior, *args)
options = args.extract_options! options = args.extract_options!.merge(behavior)
resource_name = args.first resource_name = args.first
before_filter_method = options.delete(:prepend) ? :prepend_before_filter : :before_filter before_filter_method = options.delete(:prepend) ? :prepend_before_filter : :before_filter
controller_class.send(before_filter_method, options.slice(:only, :except)) do |controller| controller_class.send(before_filter_method, options.slice(:only, :except)) do |controller|
controller.class.cancan_resource_class.new(controller, resource_name, options.except(:only, :except)).send(method) controller.class.cancan_resource_class.new(controller, resource_name, options.except(:only, :except)).process
end end
end end
@ -18,12 +18,8 @@ module CanCan
@name = args.first @name = args.first
end end
def load_and_authorize_resource def process
load_resource if @options[:load]
authorize_resource
end
def load_resource
if load_instance? if load_instance?
self.resource_instance ||= load_resource_instance self.resource_instance ||= load_resource_instance
elsif load_collection? elsif load_collection?
@ -31,8 +27,7 @@ module CanCan
current_ability.fully_authorized! @params[:action], @params[:controller] current_ability.fully_authorized! @params[:action], @params[:controller]
end end
end end
if @options[:authorize]
def authorize_resource
if resource_instance if resource_instance
if @params[name] && (authorization_action == :create || authorization_action == :update) if @params[name] && (authorization_action == :create || authorization_action == :update)
@params[name].each do |key, value| @params[name].each do |key, value|
@ -43,6 +38,7 @@ module CanCan
end end
end end
end end
end
def parent? def parent?
@options.has_key?(:parent) ? @options[:parent] : @name && @name != name_from_controller.to_sym @options.has_key?(:parent) ? @options[:parent] : @name && @name != name_from_controller.to_sym

View File

@ -33,13 +33,13 @@ describe CanCan::ControllerAdditions do
end end
it "load_and_authorize_resource should setup a before filter which passes call to ControllerResource" do it "load_and_authorize_resource should setup a before filter which passes call to ControllerResource" do
stub(CanCan::ControllerResource).new(@controller, nil, :foo => :bar).mock!.load_and_authorize_resource stub(CanCan::ControllerResource).new(@controller, nil, :load => true, :authorize => true, :foo => :bar).mock!.process
mock(@controller_class).before_filter({}) { |options, block| block.call(@controller) } mock(@controller_class).before_filter({}) { |options, block| block.call(@controller) }
@controller_class.load_and_authorize_resource :foo => :bar @controller_class.load_and_authorize_resource :foo => :bar
end end
it "load_and_authorize_resource should properly pass first argument as the resource name" do it "load_and_authorize_resource should properly pass first argument as the resource name" do
stub(CanCan::ControllerResource).new(@controller, :project, :foo => :bar).mock!.load_and_authorize_resource stub(CanCan::ControllerResource).new(@controller, :project, :load => true, :authorize => true, :foo => :bar).mock!.process
mock(@controller_class).before_filter({}) { |options, block| block.call(@controller) } mock(@controller_class).before_filter({}) { |options, block| block.call(@controller) }
@controller_class.load_and_authorize_resource :project, :foo => :bar @controller_class.load_and_authorize_resource :project, :foo => :bar
end end

View File

@ -14,63 +14,55 @@ describe CanCan::ControllerResource do
it "should load the resource into an instance variable if params[:id] is specified" do it "should load the resource into an instance variable if params[:id] is specified" do
project = Project.create! project = Project.create!
@params.merge!(:action => "show", :id => project.id) @params.merge!(:action => "show", :id => project.id)
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should == project @controller.instance_variable_get(:@project).should == project
end end
it "should not load resource into an instance variable if already set" do it "should not load resource into an instance variable if already set" do
@params.merge!(:action => "show", :id => 123) @params.merge!(:action => "show", :id => 123)
@controller.instance_variable_set(:@project, :some_project) @controller.instance_variable_set(:@project, :some_project)
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should == :some_project @controller.instance_variable_get(:@project).should == :some_project
end end
it "should properly load resource for namespaced controller" do it "should properly load resource for namespaced controller" do
project = Project.create! project = Project.create!
@params.merge!(:controller => "admin/projects", :action => "show", :id => project.id) @params.merge!(:controller => "admin/projects", :action => "show", :id => project.id)
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should == project @controller.instance_variable_get(:@project).should == project
end end
it "should properly load resource for namespaced controller when using '::' for namespace" do it "should properly load resource for namespaced controller when using '::' for namespace" do
project = Project.create! project = Project.create!
@params.merge!(:controller => "Admin::ProjectsController", :action => "show", :id => project.id) @params.merge!(:controller => "Admin::ProjectsController", :action => "show", :id => project.id)
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should == project @controller.instance_variable_get(:@project).should == project
end end
it "should build a new resource with hash if params[:id] is not specified and authorize on each attribute" do it "should build a new resource with hash if params[:id] is not specified and authorize on each attribute" do
@params.merge!(:action => "create", :project => {:name => "foobar"}) @params.merge!(:action => "create", :project => {:name => "foobar"})
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).name.should == "foobar" @controller.instance_variable_get(:@project).name.should == "foobar"
end end
it "should build a new resource with attributes from current ability" do it "should build a new resource with attributes from current ability" do
@params.merge!(:action => "new") @params.merge!(:action => "new")
@ability.can(:create, :projects, :name => "from conditions") @ability.can(:create, :projects, :name => "from conditions")
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).name.should == "from conditions" @controller.instance_variable_get(:@project).name.should == "from conditions"
end end
it "should override initial attributes with params" do it "should override initial attributes with params" do
@params.merge!(:action => "new", :project => {:name => "from params"}) @params.merge!(:action => "new", :project => {:name => "from params"})
@ability.can(:create, :projects, :name => "from conditions") @ability.can(:create, :projects, :name => "from conditions")
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).name.should == "from params" @controller.instance_variable_get(:@project).name.should == "from params"
end end
it "should build a collection when on index action when class responds to accessible_by and mark ability as fully authorized" do it "should build a collection when on index action when class responds to accessible_by and mark ability as fully authorized" do
stub(Project).accessible_by(@ability, :index) { :found_projects } stub(Project).accessible_by(@ability, :index) { :found_projects }
@params[:action] = "index" @params[:action] = "index"
resource = CanCan::ControllerResource.new(@controller, :project) CanCan::ControllerResource.new(@controller, :project, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should be_nil @controller.instance_variable_get(:@project).should be_nil
@controller.instance_variable_get(:@projects).should == :found_projects @controller.instance_variable_get(:@projects).should == :found_projects
@ability.should be_fully_authorized(:index, :projects) @ability.should be_fully_authorized(:index, :projects)
@ -78,8 +70,7 @@ describe CanCan::ControllerResource do
it "should not build a collection when on index action when class does not respond to accessible_by and not mark ability as fully authorized" do it "should not build a collection when on index action when class does not respond to accessible_by and not mark ability as fully authorized" do
@params[:action] = "index" @params[:action] = "index"
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should be_nil @controller.instance_variable_get(:@project).should be_nil
@controller.instance_variable_defined?(:@projects).should be_false @controller.instance_variable_defined?(:@projects).should be_false
@ability.should_not be_fully_authorized(:index, :projects) @ability.should_not be_fully_authorized(:index, :projects)
@ -89,8 +80,7 @@ describe CanCan::ControllerResource do
stub(Project).accessible_by(@ability) { :found_projects } stub(Project).accessible_by(@ability) { :found_projects }
@params[:action] = "index" @params[:action] = "index"
@ability.can(:read, :projects) { |p| false } @ability.can(:read, :projects) { |p| false }
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should be_nil @controller.instance_variable_get(:@project).should be_nil
@controller.instance_variable_defined?(:@projects).should be_false @controller.instance_variable_defined?(:@projects).should be_false
end end
@ -99,53 +89,43 @@ describe CanCan::ControllerResource do
@params[:action] = "index" @params[:action] = "index"
@controller.instance_variable_set(:@project, :some_project) @controller.instance_variable_set(:@project, :some_project)
stub(@controller).authorize!(:index, :projects) { raise CanCan::Unauthorized } stub(@controller).authorize!(:index, :projects) { raise CanCan::Unauthorized }
resource = CanCan::ControllerResource.new(@controller) resource = CanCan::ControllerResource.new(@controller, :authorize => true)
lambda { resource.authorize_resource }.should_not raise_error(CanCan::Unauthorized) lambda { resource.process }.should_not raise_error(CanCan::Unauthorized)
end end
it "should authorize parent resource in collection action" do it "should authorize parent resource in collection action" do
@params[:action] = "index" @params[:action] = "index"
@controller.instance_variable_set(:@category, :some_category) @controller.instance_variable_set(:@category, :some_category)
stub(@controller).authorize!(:show, :some_category) { raise CanCan::Unauthorized } stub(@controller).authorize!(:show, :some_category) { raise CanCan::Unauthorized }
resource = CanCan::ControllerResource.new(@controller, :category, :parent => true) resource = CanCan::ControllerResource.new(@controller, :category, :parent => true, :authorize => true)
lambda { resource.authorize_resource }.should raise_error(CanCan::Unauthorized) lambda { resource.process }.should raise_error(CanCan::Unauthorized)
end end
it "should perform authorization using controller action and loaded model" do it "should perform authorization using controller action and loaded model" do
@params.merge!(:action => "show", :id => 123) @params.merge!(:action => "show", :id => 123)
@controller.instance_variable_set(:@project, :some_project) @controller.instance_variable_set(:@project, :some_project)
stub(@controller).authorize!(:show, :some_project) { raise CanCan::Unauthorized } stub(@controller).authorize!(:show, :some_project) { raise CanCan::Unauthorized }
resource = CanCan::ControllerResource.new(@controller) resource = CanCan::ControllerResource.new(@controller, :authorize => true)
lambda { resource.authorize_resource }.should raise_error(CanCan::Unauthorized) lambda { resource.process }.should raise_error(CanCan::Unauthorized)
end end
it "should not perform authorization using controller action when no loaded model" do it "should not perform authorization using controller action when no loaded model" do
@params.merge!(:action => "show", :id => 123) @params.merge!(:action => "show", :id => 123)
stub(@controller).authorize!(:show, :projects) { raise CanCan::Unauthorized } stub(@controller).authorize!(:show, :projects) { raise CanCan::Unauthorized }
resource = CanCan::ControllerResource.new(@controller) resource = CanCan::ControllerResource.new(@controller, :authorize => true)
lambda { resource.authorize_resource }.should_not raise_error(CanCan::Unauthorized) lambda { resource.process }.should_not raise_error(CanCan::Unauthorized)
end
it "should call load_resource and authorize_resource for load_and_authorize_resource" do
@params.merge!(:action => "show", :id => 123)
resource = CanCan::ControllerResource.new(@controller)
mock(resource).load_resource
mock(resource).authorize_resource
resource.load_and_authorize_resource
end end
it "should not build a single resource when on custom collection action even with id" do it "should not build a single resource when on custom collection action even with id" do
@params.merge!(:action => "sort", :id => 123) @params.merge!(:action => "sort", :id => 123)
resource = CanCan::ControllerResource.new(@controller, :collection => [:sort, :list]) CanCan::ControllerResource.new(@controller, :load => true, :collection => [:sort, :list]).process
resource.load_resource
@controller.instance_variable_get(:@project).should be_nil @controller.instance_variable_get(:@project).should be_nil
end end
it "should load a collection resource when on custom action with no id param" do it "should load a collection resource when on custom action with no id param" do
stub(Project).accessible_by(@ability, :sort) { :found_projects } stub(Project).accessible_by(@ability, :sort) { :found_projects }
@params[:action] = "sort" @params[:action] = "sort"
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should be_nil @controller.instance_variable_get(:@project).should be_nil
@controller.instance_variable_get(:@projects).should == :found_projects @controller.instance_variable_get(:@projects).should == :found_projects
end end
@ -153,15 +133,13 @@ describe CanCan::ControllerResource do
it "should build a resource when on custom new action even when params[:id] exists" do it "should build a resource when on custom new action even when params[:id] exists" do
@params.merge!(:action => "build", :id => 123) @params.merge!(:action => "build", :id => 123)
stub(Project).new { :some_project } stub(Project).new { :some_project }
resource = CanCan::ControllerResource.new(@controller, :new => :build) CanCan::ControllerResource.new(@controller, :load => true, :new => :build).process
resource.load_resource
@controller.instance_variable_get(:@project).should == :some_project @controller.instance_variable_get(:@project).should == :some_project
end end
it "should not try to load resource for other action if params[:id] is undefined" do it "should not try to load resource for other action if params[:id] is undefined" do
@params[:action] = "list" @params[:action] = "list"
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :load => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should be_nil @controller.instance_variable_get(:@project).should be_nil
end end
@ -188,8 +166,7 @@ describe CanCan::ControllerResource do
it "should load parent resource through proper id parameter" do it "should load parent resource through proper id parameter" do
project = Project.create! project = Project.create!
@params.merge!(:action => "index", :project_id => project.id) @params.merge!(:action => "index", :project_id => project.id)
resource = CanCan::ControllerResource.new(@controller, :project, :parent => true) CanCan::ControllerResource.new(@controller, :project, :load => true, :parent => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should == project @controller.instance_variable_get(:@project).should == project
end end
@ -198,8 +175,7 @@ describe CanCan::ControllerResource do
category = Object.new category = Object.new
@controller.instance_variable_set(:@category, category) @controller.instance_variable_set(:@category, category)
stub(category).projects.stub!.find(123) { :some_project } stub(category).projects.stub!.find(123) { :some_project }
resource = CanCan::ControllerResource.new(@controller, :through => :category) CanCan::ControllerResource.new(@controller, :load => true, :through => :category).process
resource.load_resource
@controller.instance_variable_get(:@project).should == :some_project @controller.instance_variable_get(:@project).should == :some_project
end end
@ -208,8 +184,7 @@ describe CanCan::ControllerResource do
category = Object.new category = Object.new
@controller.instance_variable_set(:@category, category) @controller.instance_variable_set(:@category, category)
stub(category).custom_projects.stub!.find(123) { :some_project } stub(category).custom_projects.stub!.find(123) { :some_project }
resource = CanCan::ControllerResource.new(@controller, :through => :category, :through_association => :custom_projects) CanCan::ControllerResource.new(@controller, :load => true, :through => :category, :through_association => :custom_projects).process
resource.load_resource
@controller.instance_variable_get(:@project).should == :some_project @controller.instance_variable_get(:@project).should == :some_project
end end
@ -218,25 +193,23 @@ describe CanCan::ControllerResource do
category = Object.new category = Object.new
stub(@controller).category { category } stub(@controller).category { category }
stub(category).projects.stub!.find(123) { :some_project } stub(category).projects.stub!.find(123) { :some_project }
resource = CanCan::ControllerResource.new(@controller, :through => :category) CanCan::ControllerResource.new(@controller, :load => true, :through => :category).process
resource.load_resource
@controller.instance_variable_get(:@project).should == :some_project @controller.instance_variable_get(:@project).should == :some_project
end end
it "should not load through parent resource if instance isn't loaded when shallow" do it "should not load through parent resource if instance isn't loaded when shallow" do
project = Project.create! project = Project.create!
@params.merge!(:action => "show", :id => project.id) @params.merge!(:action => "show", :id => project.id)
resource = CanCan::ControllerResource.new(@controller, :through => :category, :shallow => true) CanCan::ControllerResource.new(@controller, :load => true, :through => :category, :shallow => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should == project @controller.instance_variable_get(:@project).should == project
end end
it "should raise Unauthorized when attempting to load resource through nil" do it "should raise Unauthorized when attempting to load resource through nil" do
project = Project.create! project = Project.create!
@params.merge!(:action => "show", :id => project.id) @params.merge!(:action => "show", :id => project.id)
resource = CanCan::ControllerResource.new(@controller, :through => :category) resource = CanCan::ControllerResource.new(@controller, :load => true, :through => :category)
lambda { lambda {
resource.load_resource resource.process
}.should raise_error(CanCan::Unauthorized) { |exception| }.should raise_error(CanCan::Unauthorized) { |exception|
exception.action.should == :show exception.action.should == :show
exception.subject.should == :projects exception.subject.should == :projects
@ -250,8 +223,8 @@ describe CanCan::ControllerResource do
category = Object.new category = Object.new
@controller.instance_variable_set(:@category, category) @controller.instance_variable_set(:@category, category)
stub(@controller).authorize!(:index, category => :projects) { raise CanCan::Unauthorized } stub(@controller).authorize!(:index, category => :projects) { raise CanCan::Unauthorized }
resource = CanCan::ControllerResource.new(@controller, :through => :category) resource = CanCan::ControllerResource.new(@controller, :authorize => true, :through => :category)
lambda { resource.authorize_resource }.should raise_error(CanCan::Unauthorized) lambda { resource.process }.should raise_error(CanCan::Unauthorized)
end end
it "should load through first matching if multiple are given" do it "should load through first matching if multiple are given" do
@ -259,8 +232,7 @@ describe CanCan::ControllerResource do
category = Object.new category = Object.new
@controller.instance_variable_set(:@category, category) @controller.instance_variable_set(:@category, category)
stub(category).projects.stub!.find(123) { :some_project } stub(category).projects.stub!.find(123) { :some_project }
resource = CanCan::ControllerResource.new(@controller, :through => [:category, :user]) CanCan::ControllerResource.new(@controller, :load => true, :through => [:category, :user]).process
resource.load_resource
@controller.instance_variable_get(:@project).should == :some_project @controller.instance_variable_get(:@project).should == :some_project
end end
@ -269,8 +241,7 @@ describe CanCan::ControllerResource do
category = Object.new category = Object.new
@controller.instance_variable_set(:@category, category) @controller.instance_variable_set(:@category, category)
stub(category).project { :some_project } stub(category).project { :some_project }
resource = CanCan::ControllerResource.new(@controller, :through => :category, :singleton => true) CanCan::ControllerResource.new(@controller, :load => true, :through => :category, :singleton => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should == :some_project @controller.instance_variable_get(:@project).should == :some_project
end end
@ -278,8 +249,7 @@ describe CanCan::ControllerResource do
@params.merge!(:action => "create", :project => {:name => "foobar"}) @params.merge!(:action => "create", :project => {:name => "foobar"})
category = Category.new category = Category.new
@controller.instance_variable_set(:@category, category) @controller.instance_variable_set(:@category, category)
resource = CanCan::ControllerResource.new(@controller, :through => :category, :singleton => true) CanCan::ControllerResource.new(@controller, :load => true, :through => :category, :singleton => true).process
resource.load_resource
@controller.instance_variable_get(:@project).name.should == "foobar" @controller.instance_variable_get(:@project).name.should == "foobar"
@controller.instance_variable_get(:@project).category.should == category @controller.instance_variable_get(:@project).category.should == category
end end
@ -287,15 +257,13 @@ describe CanCan::ControllerResource do
it "should find record through has_one association with :singleton and :shallow options" do it "should find record through has_one association with :singleton and :shallow options" do
project = Project.create! project = Project.create!
@params.merge!(:action => "show", :id => project.id) @params.merge!(:action => "show", :id => project.id)
resource = CanCan::ControllerResource.new(@controller, :through => :category, :singleton => true, :shallow => true) CanCan::ControllerResource.new(@controller, :load => true, :through => :category, :singleton => true, :shallow => true).process
resource.load_resource
@controller.instance_variable_get(:@project).should == project @controller.instance_variable_get(:@project).should == project
end end
it "should build record through has_one association with :singleton and :shallow options" do it "should build record through has_one association with :singleton and :shallow options" do
@params.merge!(:action => "create", :project => {:name => "foobar"}) @params.merge!(:action => "create", :project => {:name => "foobar"})
resource = CanCan::ControllerResource.new(@controller, :through => :category, :singleton => true, :shallow => true) CanCan::ControllerResource.new(@controller, :load => true, :through => :category, :singleton => true, :shallow => true).process
resource.load_resource
@controller.instance_variable_get(:@project).name.should == "foobar" @controller.instance_variable_get(:@project).name.should == "foobar"
end end
@ -303,39 +271,37 @@ describe CanCan::ControllerResource do
project = Project.create! project = Project.create!
@params.merge!(:action => "new", :project_id => project.id) @params.merge!(:action => "new", :project_id => project.id)
stub(@controller).authorize!(:show, project) { raise CanCan::Unauthorized } stub(@controller).authorize!(:show, project) { raise CanCan::Unauthorized }
resource = CanCan::ControllerResource.new(@controller, :project, :parent => true) resource = CanCan::ControllerResource.new(@controller, :project, :load => true, :authorize => true, :parent => true)
lambda { resource.load_and_authorize_resource }.should raise_error(CanCan::Unauthorized) lambda { resource.process }.should raise_error(CanCan::Unauthorized)
end end
it "should load the model using a custom class" do it "should load the model using a custom class" do
project = Project.create! project = Project.create!
@params.merge!(:action => "show", :id => project.id) @params.merge!(:action => "show", :id => project.id)
resource = CanCan::ControllerResource.new(@controller, :class => Project) CanCan::ControllerResource.new(@controller, :load => true, :class => Project).process
resource.load_resource
@controller.instance_variable_get(:@project).should == project @controller.instance_variable_get(:@project).should == project
end end
it "should not authorize based on resource name if class is false because we don't do class level authorization anymore" do it "should not authorize based on resource name if class is false because we don't do class level authorization anymore" do
@params.merge!(:action => "show", :id => 123) @params.merge!(:action => "show", :id => 123)
stub(@controller).authorize!(:show, :projects) { raise CanCan::Unauthorized } stub(@controller).authorize!(:show, :projects) { raise CanCan::Unauthorized }
resource = CanCan::ControllerResource.new(@controller, :class => false) resource = CanCan::ControllerResource.new(@controller, :authorize => true, :class => false)
lambda { resource.authorize_resource }.should_not raise_error(CanCan::Unauthorized) lambda { resource.process }.should_not raise_error(CanCan::Unauthorized)
end end
it "should load and authorize using custom instance name" do it "should load and authorize using custom instance name" do
project = Project.create! project = Project.create!
@params.merge!(:action => "show", :id => project.id) @params.merge!(:action => "show", :id => project.id)
stub(@controller).authorize!(:show, project) { raise CanCan::Unauthorized } stub(@controller).authorize!(:show, project) { raise CanCan::Unauthorized }
resource = CanCan::ControllerResource.new(@controller, :instance_name => :custom_project) resource = CanCan::ControllerResource.new(@controller, :load => true, :authorize => true, :instance_name => :custom_project)
lambda { resource.load_and_authorize_resource }.should raise_error(CanCan::Unauthorized) lambda { resource.process }.should raise_error(CanCan::Unauthorized)
@controller.instance_variable_get(:@custom_project).should == project @controller.instance_variable_get(:@custom_project).should == project
end end
it "should load resource using custom find_by attribute" do it "should load resource using custom find_by attribute" do
project = Project.create!(:name => "foo") project = Project.create!(:name => "foo")
@params.merge!(:action => "show", :id => "foo") @params.merge!(:action => "show", :id => "foo")
resource = CanCan::ControllerResource.new(@controller, :find_by => :name) CanCan::ControllerResource.new(@controller, :load => true, :find_by => :name).process
resource.load_resource
@controller.instance_variable_get(:@project).should == project @controller.instance_variable_get(:@project).should == project
end end
@ -343,16 +309,14 @@ describe CanCan::ControllerResource do
@params.merge!(:action => "create", :project => {:name => "foo"}) @params.merge!(:action => "create", :project => {:name => "foo"})
@controller.instance_variable_set(:@project, :some_project) @controller.instance_variable_set(:@project, :some_project)
mock(@controller).authorize!(:create, :some_project, :name) mock(@controller).authorize!(:create, :some_project, :name)
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :authorize => true).process
resource.authorize_resource
end end
it "should authorize each new attribute in the update action" do it "should authorize each new attribute in the update action" do
@params.merge!(:action => "update", :id => 123, :project => {:name => "foo"}) @params.merge!(:action => "update", :id => 123, :project => {:name => "foo"})
@controller.instance_variable_set(:@project, :some_project) @controller.instance_variable_set(:@project, :some_project)
mock(@controller).authorize!(:update, :some_project, :name) mock(@controller).authorize!(:update, :some_project, :name)
resource = CanCan::ControllerResource.new(@controller) CanCan::ControllerResource.new(@controller, :authorize => true).process
resource.authorize_resource
end end
# it "should raise ImplementationRemoved when adding :name option" do # it "should raise ImplementationRemoved when adding :name option" do

View File

@ -14,21 +14,21 @@ describe CanCan::InheritedResource do
it "show should load resource through @controller.resource" do it "show should load resource through @controller.resource" do
@params.merge!(:action => "show", :id => 123) @params.merge!(:action => "show", :id => 123)
stub(@controller).resource { :project_resource } stub(@controller).resource { :project_resource }
CanCan::InheritedResource.new(@controller).load_resource CanCan::InheritedResource.new(@controller, :load => true).process
@controller.instance_variable_get(:@project).should == :project_resource @controller.instance_variable_get(:@project).should == :project_resource
end end
it "new should load through @controller.build_resource" do it "new should load through @controller.build_resource" do
@params[:action] = "new" @params[:action] = "new"
stub(@controller).build_resource { :project_resource } stub(@controller).build_resource { :project_resource }
CanCan::InheritedResource.new(@controller).load_resource CanCan::InheritedResource.new(@controller, :load => true).process
@controller.instance_variable_get(:@project).should == :project_resource @controller.instance_variable_get(:@project).should == :project_resource
end end
it "index should load through @controller.association_chain when parent" do it "index should load through @controller.association_chain when parent" do
@params[:action] = "index" @params[:action] = "index"
stub(@controller).association_chain { @controller.instance_variable_set(:@project, :project_resource) } stub(@controller).association_chain { @controller.instance_variable_set(:@project, :project_resource) }
CanCan::InheritedResource.new(@controller, :parent => true).load_resource CanCan::InheritedResource.new(@controller, :load => true, :parent => true).process
@controller.instance_variable_get(:@project).should == :project_resource @controller.instance_variable_get(:@project).should == :project_resource
end end
@ -36,7 +36,7 @@ describe CanCan::InheritedResource do
@params[:action] = "index" @params[:action] = "index"
stub(Project).accessible_by(@ability, :index) { :projects } stub(Project).accessible_by(@ability, :index) { :projects }
stub(@controller).end_of_association_chain { Project } stub(@controller).end_of_association_chain { Project }
CanCan::InheritedResource.new(@controller).load_resource CanCan::InheritedResource.new(@controller, :load => true).process
@controller.instance_variable_get(:@projects).should == :projects @controller.instance_variable_get(:@projects).should == :projects
end end
end end