merging 1.6 additions into 2.0 branch
This commit is contained in:
commit
86063e4846
9
.travis.yml
Normal file
9
.travis.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
rvm:
|
||||||
|
- 1.8.7
|
||||||
|
- jruby
|
||||||
|
- ree
|
||||||
|
- rbx-2.0
|
||||||
|
notifications:
|
||||||
|
recipients:
|
||||||
|
- graf.otodrakula@gmail.com
|
||||||
|
- ryan@railscasts.com
|
2
Gemfile
2
Gemfile
|
@ -3,7 +3,7 @@ source "http://rubygems.org"
|
||||||
case ENV["MODEL_ADAPTER"]
|
case ENV["MODEL_ADAPTER"]
|
||||||
when nil, "active_record"
|
when nil, "active_record"
|
||||||
gem "sqlite3"
|
gem "sqlite3"
|
||||||
gem "activerecord", :require => "active_record"
|
gem "activerecord", '~> 3.0.9', :require => "active_record"
|
||||||
gem "with_model"
|
gem "with_model"
|
||||||
gem "meta_where"
|
gem "meta_where"
|
||||||
when "data_mapper"
|
when "data_mapper"
|
||||||
|
|
|
@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
||||||
s.require_path = "lib"
|
s.require_path = "lib"
|
||||||
|
|
||||||
s.add_development_dependency 'rspec', '~> 2.1.0'
|
s.add_development_dependency 'rspec', '~> 2.1.0'
|
||||||
s.add_development_dependency 'rails', '~> 3.0.0'
|
s.add_development_dependency 'rails', '~> 3.0.9'
|
||||||
s.add_development_dependency 'rr', '~> 0.10.11' # 1.0.0 has respond_to? issues: http://github.com/btakita/rr/issues/issue/43
|
s.add_development_dependency 'rr', '~> 0.10.11' # 1.0.0 has respond_to? issues: http://github.com/btakita/rr/issues/issue/43
|
||||||
s.add_development_dependency 'supermodel', '~> 0.1.4'
|
s.add_development_dependency 'supermodel', '~> 0.1.4'
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@ module CanCan
|
||||||
skip_authorize_resource(*args)
|
skip_authorize_resource(*args)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Skip both the loading behavior of CanCan. This is useful when using +load_and_authorize_resource+ but want to
|
# Skip 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
|
# 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.
|
# skip the effects on. It will apply to all actions by default.
|
||||||
#
|
#
|
||||||
|
@ -205,7 +205,7 @@ module CanCan
|
||||||
cancan_skipper[:load][name] = options
|
cancan_skipper[:load][name] = options
|
||||||
end
|
end
|
||||||
|
|
||||||
# Skip both the authorization behavior of CanCan. This is useful when using +load_and_authorize_resource+ but want to
|
# Skip 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
|
# 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.
|
# skip the effects on. It will apply to all actions by default.
|
||||||
#
|
#
|
||||||
|
|
|
@ -107,10 +107,22 @@ module CanCan
|
||||||
if @options[:singleton] && parent_resource.respond_to?(name)
|
if @options[:singleton] && parent_resource.respond_to?(name)
|
||||||
parent_resource.send(name)
|
parent_resource.send(name)
|
||||||
else
|
else
|
||||||
@options[:find_by] ? resource_base.send("find_by_#{@options[:find_by]}!", id_param) : resource_base.find(id_param)
|
if @options[:find_by]
|
||||||
|
if resource_base.respond_to? "find_by_#{@options[:find_by]}!"
|
||||||
|
resource_base.send("find_by_#{@options[:find_by]}!", id_param)
|
||||||
|
else
|
||||||
|
resource_base.send(@options[:find_by], id_param)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
adapter.find(resource_base, id_param)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def adapter
|
||||||
|
ModelAdapters::AbstractAdapter.adapter_class(resource_class)
|
||||||
|
end
|
||||||
|
|
||||||
def authorization_action
|
def authorization_action
|
||||||
parent? ? :show : @params[:action].to_sym
|
parent? ? :show : @params[:action].to_sym
|
||||||
end
|
end
|
||||||
|
|
|
@ -43,7 +43,7 @@ module CanCan
|
||||||
@message = message
|
@message = message
|
||||||
@action = action
|
@action = action
|
||||||
@subject = subject
|
@subject = subject
|
||||||
@default_message = "You are not authorized to access this page."
|
@default_message = I18n.t(:"unauthorized.default", :default => "You are not authorized to access this page.")
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
RSpec = Spec unless defined? RSpec # for RSpec 1 compatability
|
rspec_module = defined?(RSpec::Core) ? 'RSpec' : 'Spec' # for RSpec 1 compatability
|
||||||
RSpec::Matchers.define :be_able_to do |*args|
|
Kernel.const_get(rspec_module)::Matchers.define :be_able_to do |*args|
|
||||||
match do |ability|
|
match do |ability|
|
||||||
ability.can?(*args)
|
ability.can?(*args)
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,11 @@ module CanCan
|
||||||
false # override in subclass
|
false # override in subclass
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Override if you need custom find behavior
|
||||||
|
def self.find(model_class, id)
|
||||||
|
model_class.find(id)
|
||||||
|
end
|
||||||
|
|
||||||
# Used to determine if this model adapter will override the matching behavior for a hash of conditions.
|
# Used to determine if this model adapter will override the matching behavior for a hash of conditions.
|
||||||
# If this returns true then matches_conditions_hash? will be called. See Rule#matches_conditions_hash
|
# If this returns true then matches_conditions_hash? will be called. See Rule#matches_conditions_hash
|
||||||
def self.override_conditions_hash_matching?(subject, conditions)
|
def self.override_conditions_hash_matching?(subject, conditions)
|
||||||
|
|
|
@ -5,6 +5,10 @@ module CanCan
|
||||||
model_class <= DataMapper::Resource
|
model_class <= DataMapper::Resource
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.find(model_class, id)
|
||||||
|
model_class.get(id)
|
||||||
|
end
|
||||||
|
|
||||||
def self.override_conditions_hash_matching?(subject, conditions)
|
def self.override_conditions_hash_matching?(subject, conditions)
|
||||||
conditions.any? { |k,v| !k.kind_of?(Symbol) }
|
conditions.any? { |k,v| !k.kind_of?(Symbol) }
|
||||||
end
|
end
|
||||||
|
@ -27,6 +31,4 @@ module CanCan
|
||||||
end # module ModelAdapters
|
end # module ModelAdapters
|
||||||
end # module CanCan
|
end # module CanCan
|
||||||
|
|
||||||
DataMapper::Model.class_eval do
|
DataMapper::Model.append_extensions(CanCan::ModelAdditions::ClassMethods)
|
||||||
include CanCan::ModelAdditions::ClassMethods
|
|
||||||
end
|
|
||||||
|
|
|
@ -329,6 +329,14 @@ describe CanCan::ControllerResource do
|
||||||
CanCan::ControllerResource.new(@controller, :authorize => true).process
|
CanCan::ControllerResource.new(@controller, :authorize => true).process
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should allow full find method to be passed into find_by option" do
|
||||||
|
project = Project.create!(:name => "foo")
|
||||||
|
@params.merge!(:action => "show", :id => "foo")
|
||||||
|
resource = CanCan::ControllerResource.new(@controller, :find_by => :find_by_name, :load => true)
|
||||||
|
resource.process
|
||||||
|
@controller.instance_variable_get(:@project).should == project
|
||||||
|
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)
|
||||||
|
@ -349,13 +357,13 @@ describe CanCan::ControllerResource do
|
||||||
# CanCan::ControllerResource.new(@controller, :name => :foo)
|
# CanCan::ControllerResource.new(@controller, :name => :foo)
|
||||||
# }.should raise_error(CanCan::ImplementationRemoved)
|
# }.should raise_error(CanCan::ImplementationRemoved)
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# it "should raise ImplementationRemoved exception when specifying :resource option since it is no longer used" do
|
# it "should raise ImplementationRemoved exception when specifying :resource option since it is no longer used" do
|
||||||
# lambda {
|
# lambda {
|
||||||
# CanCan::ControllerResource.new(@controller, :resource => Project)
|
# CanCan::ControllerResource.new(@controller, :resource => Project)
|
||||||
# }.should raise_error(CanCan::ImplementationRemoved)
|
# }.should raise_error(CanCan::ImplementationRemoved)
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# it "should raise ImplementationRemoved exception when passing :nested option" do
|
# it "should raise ImplementationRemoved exception when passing :nested option" do
|
||||||
# lambda {
|
# lambda {
|
||||||
# CanCan::ControllerResource.new(@controller, :nested => :project)
|
# CanCan::ControllerResource.new(@controller, :nested => :project)
|
||||||
|
@ -372,7 +380,7 @@ describe CanCan::ControllerResource do
|
||||||
# @params.merge!(:action => "other_action")
|
# @params.merge!(:action => "other_action")
|
||||||
# CanCan::ControllerResource.new(@controller).skip?(:load).should be_false
|
# CanCan::ControllerResource.new(@controller).skip?(:load).should be_false
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# it "should skip resource behavior for :only one action on resource" do
|
# it "should skip resource behavior for :only one action on resource" do
|
||||||
# stub(@controller_class).cancan_skipper { {:authorize => {:project => {:only => :index}}} }
|
# stub(@controller_class).cancan_skipper { {:authorize => {:project => {:only => :index}}} }
|
||||||
# @params.merge!(:action => "index")
|
# @params.merge!(:action => "index")
|
||||||
|
@ -381,7 +389,7 @@ describe CanCan::ControllerResource do
|
||||||
# @params.merge!(:action => "other_action")
|
# @params.merge!(:action => "other_action")
|
||||||
# CanCan::ControllerResource.new(@controller, :project).skip?(:authorize).should be_false
|
# CanCan::ControllerResource.new(@controller, :project).skip?(:authorize).should be_false
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# it "should skip resource behavior :except actions in array" do
|
# it "should skip resource behavior :except actions in array" do
|
||||||
# stub(@controller_class).cancan_skipper { {:load => {nil => {:except => [:index, :show]}}} }
|
# stub(@controller_class).cancan_skipper { {:load => {nil => {:except => [:index, :show]}}} }
|
||||||
# @params.merge!(:action => "index")
|
# @params.merge!(:action => "index")
|
||||||
|
@ -392,7 +400,7 @@ describe CanCan::ControllerResource do
|
||||||
# CanCan::ControllerResource.new(@controller).skip?(:load).should be_true
|
# CanCan::ControllerResource.new(@controller).skip?(:load).should be_true
|
||||||
# CanCan::ControllerResource.new(@controller, :some_resource).skip?(:load).should be_false
|
# CanCan::ControllerResource.new(@controller, :some_resource).skip?(:load).should be_false
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# it "should skip resource behavior :except one action on resource" do
|
# it "should skip resource behavior :except one action on resource" do
|
||||||
# stub(@controller_class).cancan_skipper { {:authorize => {:project => {:except => :index}}} }
|
# stub(@controller_class).cancan_skipper { {:authorize => {:project => {:except => :index}}} }
|
||||||
# @params.merge!(:action => "index")
|
# @params.merge!(:action => "index")
|
||||||
|
@ -401,7 +409,7 @@ describe CanCan::ControllerResource do
|
||||||
# CanCan::ControllerResource.new(@controller).skip?(:authorize).should be_false
|
# CanCan::ControllerResource.new(@controller).skip?(:authorize).should be_false
|
||||||
# CanCan::ControllerResource.new(@controller, :project).skip?(:authorize).should be_true
|
# CanCan::ControllerResource.new(@controller, :project).skip?(:authorize).should be_true
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# it "should skip loading and authorization" do
|
# it "should skip loading and authorization" do
|
||||||
# stub(@controller_class).cancan_skipper { {:authorize => {nil => {}}, :load => {nil => {}}} }
|
# stub(@controller_class).cancan_skipper { {:authorize => {nil => {}}, :load => {nil => {}}} }
|
||||||
# @params.merge!(:action => "new")
|
# @params.merge!(:action => "new")
|
||||||
|
|
|
@ -32,4 +32,27 @@ describe CanCan::Unauthorized do
|
||||||
@exception.message.should == "Access denied!"
|
@exception.message.should == "Access denied!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "i18n in the default message" do
|
||||||
|
after(:each) do
|
||||||
|
I18n.backend = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "uses i18n for the default message" do
|
||||||
|
I18n.backend.store_translations :en, :unauthorized => {:default => "This is a different message"}
|
||||||
|
@exception = CanCan::Unauthorized.new
|
||||||
|
@exception.message.should == "This is a different message"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "defaults to a nice message" do
|
||||||
|
@exception = CanCan::Unauthorized.new
|
||||||
|
@exception.message.should == "You are not authorized to access this page."
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not use translation if a message is given" do
|
||||||
|
@exception = CanCan::Unauthorized.new("Hey! You're not welcome here")
|
||||||
|
@exception.message.should == "Hey! You're not welcome here"
|
||||||
|
@exception.message.should_not == "You are not authorized to access this page."
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -56,6 +56,11 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
|
||||||
CanCan::ModelAdapters::AbstractAdapter.adapter_class(Article).should == CanCan::ModelAdapters::ActiveRecordAdapter
|
CanCan::ModelAdapters::AbstractAdapter.adapter_class(Article).should == CanCan::ModelAdapters::ActiveRecordAdapter
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should find record" do
|
||||||
|
article = Article.create!
|
||||||
|
CanCan::ModelAdapters::ActiveRecordAdapter.find(Article, article.id).should == article
|
||||||
|
end
|
||||||
|
|
||||||
it "should not fetch any records when no abilities are defined" do
|
it "should not fetch any records when no abilities are defined" do
|
||||||
Article.create!
|
Article.create!
|
||||||
Article.accessible_by(@ability).should be_empty
|
Article.accessible_by(@ability).should be_empty
|
||||||
|
|
|
@ -36,6 +36,11 @@ if ENV["MODEL_ADAPTER"] == "data_mapper"
|
||||||
CanCan::ModelAdapters::AbstractAdapter.adapter_class(Article).should == CanCan::ModelAdapters::DataMapperAdapter
|
CanCan::ModelAdapters::AbstractAdapter.adapter_class(Article).should == CanCan::ModelAdapters::DataMapperAdapter
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should find record" do
|
||||||
|
article = Article.create
|
||||||
|
CanCan::ModelAdapters::DataMapperAdapter.find(Article, article.id).should == article
|
||||||
|
end
|
||||||
|
|
||||||
it "should not fetch any records when no abilities are defined" do
|
it "should not fetch any records when no abilities are defined" do
|
||||||
Article.create
|
Article.create
|
||||||
Article.accessible_by(@ability).should be_empty
|
Article.accessible_by(@ability).should be_empty
|
||||||
|
|
|
@ -36,6 +36,11 @@ if ENV["MODEL_ADAPTER"] == "mongoid"
|
||||||
CanCan::ModelAdapters::AbstractAdapter.adapter_class(MongoidProject).should == CanCan::ModelAdapters::MongoidAdapter
|
CanCan::ModelAdapters::AbstractAdapter.adapter_class(MongoidProject).should == CanCan::ModelAdapters::MongoidAdapter
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should find record" do
|
||||||
|
project = MongoidProject.create
|
||||||
|
CanCan::ModelAdapters::MongoidAdapter.find(MongoidProject, project.id).should == project
|
||||||
|
end
|
||||||
|
|
||||||
it "should compare properties on mongoid documents with the conditions hash" do
|
it "should compare properties on mongoid documents with the conditions hash" do
|
||||||
model = MongoidProject.new
|
model = MongoidProject.new
|
||||||
@ability.can :read, :mongoid_projects, :id => model.id
|
@ability.can :read, :mongoid_projects, :id => model.id
|
||||||
|
@ -180,7 +185,7 @@ if ENV["MODEL_ADAPTER"] == "mongoid"
|
||||||
@ability.can :read, :mongoid_projects, :foo => {:bar => 1}
|
@ability.can :read, :mongoid_projects, :foo => {:bar => 1}
|
||||||
MongoidProject.accessible_by(@ability, :read).entries.first.should == obj
|
MongoidProject.accessible_by(@ability, :read).entries.first.should == obj
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should exclude from the result if set to cannot" do
|
it "should exclude from the result if set to cannot" do
|
||||||
obj = MongoidProject.create(:bar => 1)
|
obj = MongoidProject.create(:bar => 1)
|
||||||
obj2 = MongoidProject.create(:bar => 2)
|
obj2 = MongoidProject.create(:bar => 2)
|
||||||
|
@ -197,7 +202,7 @@ if ENV["MODEL_ADAPTER"] == "mongoid"
|
||||||
@ability.can :read, :mongoid_projects, :bar => 2
|
@ability.can :read, :mongoid_projects, :bar => 2
|
||||||
MongoidProject.accessible_by(@ability, :read).entries.should =~ [obj, obj2]
|
MongoidProject.accessible_by(@ability, :read).entries.should =~ [obj, obj2]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not allow to fetch records when ability with just block present" do
|
it "should not allow to fetch records when ability with just block present" do
|
||||||
@ability.can :read, :mongoid_projects do
|
@ability.can :read, :mongoid_projects do
|
||||||
false
|
false
|
||||||
|
|
|
@ -30,4 +30,12 @@ end
|
||||||
class Project < SuperModel::Base
|
class Project < SuperModel::Base
|
||||||
belongs_to :category
|
belongs_to :category
|
||||||
attr_accessor :category # why doesn't SuperModel do this automatically?
|
attr_accessor :category # why doesn't SuperModel do this automatically?
|
||||||
|
|
||||||
|
def self.respond_to?(method, include_private = false)
|
||||||
|
if method.to_s == "find_by_name!" # hack to simulate ActiveRecord
|
||||||
|
true
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user