mirror of
https://github.com/github/rails.git
synced 2026-01-26 06:48:59 -05:00
Ensure methods called on association proxies respect access control. [#1083 state:resolved] [Adam Milligan, Pratik]
This commit is contained in:
@@ -140,6 +140,15 @@ module ActiveRecord
|
|||||||
@target.inspect
|
@target.inspect
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def send(method, *args)
|
||||||
|
if proxy_respond_to?(method)
|
||||||
|
super
|
||||||
|
else
|
||||||
|
load_target
|
||||||
|
@target.send(method, *args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
# Does the association have a <tt>:dependent</tt> option?
|
# Does the association have a <tt>:dependent</tt> option?
|
||||||
def dependent?
|
def dependent?
|
||||||
@@ -197,6 +206,8 @@ module ActiveRecord
|
|||||||
# Forwards any missing method call to the \target.
|
# Forwards any missing method call to the \target.
|
||||||
def method_missing(method, *args)
|
def method_missing(method, *args)
|
||||||
if load_target
|
if load_target
|
||||||
|
raise NoMethodError unless @target.respond_to?(method)
|
||||||
|
|
||||||
if block_given?
|
if block_given?
|
||||||
@target.send(method, *args) { |*block_args| yield(*block_args) }
|
@target.send(method, *args) { |*block_args| yield(*block_args) }
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ module ActiveRecord
|
|||||||
protected
|
protected
|
||||||
def owner_quoted_id
|
def owner_quoted_id
|
||||||
if @reflection.options[:primary_key]
|
if @reflection.options[:primary_key]
|
||||||
quote_value(@owner.send(@reflection.options[:primary_key]))
|
@owner.class.quote_value(@owner.send(@reflection.options[:primary_key]))
|
||||||
else
|
else
|
||||||
@owner.quoted_id
|
@owner.quoted_id
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -428,4 +428,14 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|||||||
assert log.valid?
|
assert log.valid?
|
||||||
assert log.save
|
assert log.save
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_belongs_to_proxy_should_not_respond_to_private_methods
|
||||||
|
assert_raises(NoMethodError) { companies(:first_firm).private_method }
|
||||||
|
assert_raises(NoMethodError) { companies(:second_client).firm.private_method }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_belongs_to_proxy_should_respond_to_private_methods_via_send
|
||||||
|
companies(:first_firm).send(:private_method)
|
||||||
|
companies(:second_client).firm.send(:private_method)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -349,4 +349,14 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
|||||||
assert companies(:first_firm).readonly_account.readonly?
|
assert companies(:first_firm).readonly_account.readonly?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_has_one_proxy_should_not_respond_to_private_methods
|
||||||
|
assert_raises(NoMethodError) { accounts(:signals37).private_method }
|
||||||
|
assert_raises(NoMethodError) { companies(:first_firm).account.private_method }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_has_one_proxy_should_respond_to_private_methods_via_send
|
||||||
|
accounts(:signals37).send(:private_method)
|
||||||
|
companies(:first_firm).account.send(:private_method)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -110,4 +110,14 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
|
|||||||
new_member.club = new_club = Club.create(:name => "LRUG")
|
new_member.club = new_club = Club.create(:name => "LRUG")
|
||||||
assert_equal new_club, new_member.club.target
|
assert_equal new_club, new_member.club.target
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_has_one_through_proxy_should_not_respond_to_private_methods
|
||||||
|
assert_raises(NoMethodError) { clubs(:moustache_club).private_method }
|
||||||
|
assert_raises(NoMethodError) { @member.club.private_method }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_has_one_through_proxy_should_respond_to_private_methods_via_send
|
||||||
|
clubs(:moustache_club).send(:private_method)
|
||||||
|
@member.club.send(:private_method)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,4 +4,10 @@ class Club < ActiveRecord::Base
|
|||||||
has_many :current_memberships
|
has_many :current_memberships
|
||||||
has_one :sponsor
|
has_one :sponsor
|
||||||
has_one :sponsored_member, :through => :sponsor, :source => :sponsorable, :source_type => "Member"
|
has_one :sponsored_member, :through => :sponsor, :source => :sponsorable, :source_type => "Member"
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def private_method
|
||||||
|
"I'm sorry sir, this is a *private* club, not a *pirate* club"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
@@ -13,6 +13,12 @@ class Company < AbstractCompany
|
|||||||
def arbitrary_method
|
def arbitrary_method
|
||||||
"I am Jack's profound disappointment"
|
"I am Jack's profound disappointment"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def private_method
|
||||||
|
"I am Jack's innermost fears and aspirations"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module Namespaced
|
module Namespaced
|
||||||
@@ -129,9 +135,14 @@ class Account < ActiveRecord::Base
|
|||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def validate
|
def validate
|
||||||
errors.add_on_empty "credit_limit"
|
errors.add_on_empty "credit_limit"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def private_method
|
||||||
|
"Sir, yes sir!"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user