Permalink
Browse files

Merge branch 'master' of git@github.com:lifo/docrails

  • Loading branch information...
2 parents b8c46c8 + 9546ee2 commit 9226b3e8355e7b6aa3be62fff56117d75c408831 Cody Fauser committed May 14, 2008
Showing with 497 additions and 191 deletions.
  1. +4 −0 actionpack/CHANGELOG
  2. +1 −6 actionpack/lib/action_controller/flash.rb
  3. +10 −4 actionpack/lib/action_controller/record_identifier.rb
  4. +3 −3 actionpack/lib/action_controller/request_forgery_protection.rb
  5. +5 −4 actionpack/lib/action_controller/routing/segments.rb
  6. +5 −0 actionpack/lib/action_controller/session_management.rb
  7. +5 −0 actionpack/lib/action_view/helpers/sanitize_helper.rb
  8. +2 −2 actionpack/lib/action_view/partials.rb
  9. +147 −42 actionpack/test/activerecord/render_partial_with_record_identification_test.rb
  10. +36 −0 actionpack/test/controller/record_identifier_test.rb
  11. +24 −0 actionpack/test/controller/request_forgery_protection_test.rb
  12. +7 −5 actionpack/test/controller/routing_test.rb
  13. +22 −0 actionpack/test/controller/session_management_test.rb
  14. +10 −0 actionpack/test/controller/test_test.rb
  15. +5 −1 activerecord/CHANGELOG
  16. +12 −11 activerecord/lib/active_record/association_preload.rb
  17. +24 −16 activerecord/lib/active_record/attribute_methods.rb
  18. +2 −0 activerecord/lib/active_record/base.rb
  19. +44 −46 activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
  20. +10 −10 activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
  21. +10 −0 activerecord/lib/active_record/migration.rb
  22. +12 −0 activerecord/lib/active_record/named_scope.rb
  23. +1 −1 activerecord/lib/active_record/validations.rb
  24. +17 −0 activerecord/test/cases/associations/eager_test.rb
  25. +7 −1 activerecord/test/cases/associations/has_many_associations_test.rb
  26. +6 −0 activerecord/test/cases/migration_test.rb
  27. +6 −0 activerecord/test/cases/named_scope_test.rb
  28. +8 −0 activerecord/test/cases/validations_test.rb
  29. +7 −0 activerecord/test/migrations/duplicate_names/20080507052938_chunky.rb
  30. +7 −0 activerecord/test/migrations/duplicate_names/20080507053028_chunky.rb
  31. +4 −0 activerecord/test/models/author.rb
  32. +2 −0 activerecord/test/models/guid.rb
  33. +4 −0 activerecord/test/schema/schema.rb
  34. +2 −0 activesupport/CHANGELOG
  35. +3 −3 activesupport/lib/active_support/core_ext/module/attr_internal.rb
  36. +2 −3 activesupport/lib/active_support/core_ext/range/conversions.rb
  37. +7 −0 activesupport/lib/active_support/inflector.rb
  38. +0 −29 activesupport/lib/active_support/json.rb
  39. +13 −3 railties/README
  40. +1 −1 railties/Rakefile
View
@@ -1,5 +1,9 @@
*SVN*
+* Fixed that forgery protection can be used without session tracking (Peter Jones) [#139]
+
+* Added session(:on) to turn session management back on in a controller subclass if the superclass turned it off (Peter Jones) [#136]
+
* InstanceTag#default_time_from_options with hash args uses Time.current as default; respects hash settings when time falls in system local spring DST gap [Geoff Buesing]
* select_date defaults to Time.zone.today when config.time_zone is set [Geoff Buesing]
@@ -28,7 +28,6 @@ def self.included(base)
base.class_eval do
include InstanceMethods
alias_method_chain :assign_shortcuts, :flash
- alias_method_chain :process_cleanup, :flash
alias_method_chain :reset_session, :flash
end
end
@@ -166,11 +165,7 @@ def flash(refresh = false) #:doc:
def assign_shortcuts_with_flash(request, response) #:nodoc:
assign_shortcuts_without_flash(request, response)
flash(:refresh)
- end
-
- def process_cleanup_with_flash
- flash.sweep if @_session
- process_cleanup_without_flash
+ flash.sweep if @_session && !component_request?
end
end
end
@@ -33,11 +33,17 @@ module RecordIdentifier
# Returns plural/singular for a record or class. Example:
#
- # partial_path(post) # => "posts/post"
- # partial_path(Person) # => "people/person"
- def partial_path(record_or_class)
+ # partial_path(post) # => "posts/post"
+ # partial_path(Person) # => "people/person"
+ # partial_path(Person, "admin/games") # => "admin/people/person"
+ def partial_path(record_or_class, controller_path = nil)
klass = class_from_record_or_class(record_or_class)
- "#{klass.name.tableize}/#{klass.name.demodulize.underscore}"
+
+ if controller_path && controller_path.include?("/")
+ "#{File.dirname(controller_path)}/#{klass.name.tableize}/#{klass.name.demodulize.underscore}"
+ else
+ "#{klass.name.tableize}/#{klass.name.demodulize.underscore}"
+ end
end
# The DOM class convention is to use the singular form of an object or class. Examples:
@@ -105,12 +105,12 @@ def verifiable_request_format?
# Sets the token value for the current session. Pass a <tt>:secret</tt> option
# in +protect_from_forgery+ to add a custom salt to the hash.
def form_authenticity_token
- @form_authenticity_token ||= if request_forgery_protection_options[:secret]
+ @form_authenticity_token ||= if !session.respond_to?(:session_id)
+ raise InvalidAuthenticityToken, "Request Forgery Protection requires a valid session. Use #allow_forgery_protection to disable it, or use a valid session."
+ elsif request_forgery_protection_options[:secret]
authenticity_token_from_session_id
elsif session.respond_to?(:dbman) && session.dbman.respond_to?(:generate_digest)
authenticity_token_from_cookie_session
- elsif session.nil?
- raise InvalidAuthenticityToken, "Request Forgery Protection requires a valid session. Use #allow_forgery_protection to disable it, or use a valid session."
else
raise InvalidAuthenticityToken, "No :secret given to the #protect_from_forgery call. Set that or use a session store capable of generating its own keys (Cookie Session Store)."
end
@@ -244,11 +244,12 @@ def match_extraction(next_capture)
end
class PathSegment < DynamicSegment #:nodoc:
- RESERVED_PCHAR = "#{Segment::RESERVED_PCHAR}/"
- UNSAFE_PCHAR = Regexp.new("[^#{URI::REGEXP::PATTERN::UNRESERVED}#{RESERVED_PCHAR}]", false, 'N').freeze
-
def interpolation_chunk(value_code = "#{local_name}")
- "\#{URI.escape(#{value_code}.to_s, ActionController::Routing::PathSegment::UNSAFE_PCHAR)}"
+ "\#{#{value_code}}"
+ end
+
+ def extract_value
+ "#{local_name} = hash[:#{key}] && hash[:#{key}].collect { |path_component| URI.escape(path_component, ActionController::Routing::Segment::UNSAFE_PCHAR) }.to_param #{"|| #{default.inspect}" if default}"
end
def default
@@ -69,11 +69,16 @@ def session_options
# session :off,
# :if => Proc.new { |req| !(req.format.html? || req.format.js?) }
#
+ # # turn the session back on, useful when it was turned off in the
+ # # application controller, and you need it on in another controller
+ # session :on
+ #
# All session options described for ActionController::Base.process_cgi
# are valid arguments.
def session(*args)
options = args.extract_options!
+ options[:disabled] = false if args.delete(:on)
options[:disabled] = true if !args.empty?
options[:only] = [*options[:only]].map { |o| o.to_s } if options[:only]
options[:except] = [*options[:except]].map { |o| o.to_s } if options[:except]
@@ -48,6 +48,11 @@ def self.included(base)
# config.action_view.sanitized_allowed_attributes = 'id', 'class', 'style'
# end
#
+ # Please note that sanitizing user-provided text does not guarantee that the
+ # resulting markup is valid (conforming to a document type) or even well-formed.
+ # The output may still contain e.g. unescaped '<', '>', '&' characters and
+ # confuse browsers.
+ #
def sanitize(html, options = {})
self.class.white_list_sanitizer.sanitize(html, options)
end
@@ -119,7 +119,7 @@ def render_partial(partial_path, object_assigns = nil, local_assigns = {}) #:nod
""
end
else
- render_partial(ActionController::RecordIdentifier.partial_path(partial_path), partial_path, local_assigns)
+ render_partial(ActionController::RecordIdentifier.partial_path(partial_path, controller.class.controller_path), partial_path, local_assigns)
end
end
@@ -147,7 +147,7 @@ def render_partial_collection_with_unknown_partial_path(collection, local_assign
templates = Hash.new
i = 0
collection.map do |element|
- partial_path = ActionController::RecordIdentifier.partial_path(element)
+ partial_path = ActionController::RecordIdentifier.partial_path(element, controller.class.controller_path)
template = templates[partial_path] ||= ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
template.counter = i
i += 1
@@ -1,49 +1,49 @@
require 'active_record_unit'
-class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase
- fixtures :developers, :projects, :developers_projects, :topics, :replies, :companies, :mascots
+class RenderPartialWithRecordIdentificationController < ActionController::Base
+ def render_with_has_many_and_belongs_to_association
+ @developer = Developer.find(1)
+ render :partial => @developer.projects
+ end
- class RenderPartialWithRecordIdentificationController < ActionController::Base
- def render_with_has_many_and_belongs_to_association
- @developer = Developer.find(1)
- render :partial => @developer.projects
- end
-
- def render_with_has_many_association
- @topic = Topic.find(1)
- render :partial => @topic.replies
- end
-
- def render_with_named_scope
- render :partial => Reply.base
- end
-
- def render_with_has_many_through_association
- @developer = Developer.find(:first)
- render :partial => @developer.topics
- end
-
- def render_with_has_one_association
- @company = Company.find(1)
- render :partial => @company.mascot
- end
-
- def render_with_belongs_to_association
- @reply = Reply.find(1)
- render :partial => @reply.topic
- end
-
- def render_with_record
- @developer = Developer.find(:first)
- render :partial => @developer
- end
-
- def render_with_record_collection
- @developers = Developer.find(:all)
- render :partial => @developers
- end
+ def render_with_has_many_association
+ @topic = Topic.find(1)
+ render :partial => @topic.replies
+ end
+
+ def render_with_named_scope
+ render :partial => Reply.base
+ end
+
+ def render_with_has_many_through_association
+ @developer = Developer.find(:first)
+ render :partial => @developer.topics
+ end
+
+ def render_with_has_one_association
+ @company = Company.find(1)
+ render :partial => @company.mascot
+ end
+
+ def render_with_belongs_to_association
+ @reply = Reply.find(1)
+ render :partial => @reply.topic
end
- RenderPartialWithRecordIdentificationController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+ def render_with_record
+ @developer = Developer.find(:first)
+ render :partial => @developer
+ end
+
+ def render_with_record_collection
+ @developers = Developer.find(:all)
+ render :partial => @developers
+ end
+end
+RenderPartialWithRecordIdentificationController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase
+ fixtures :developers, :projects, :developers_projects, :topics, :replies, :companies, :mascots
def setup
@controller = RenderPartialWithRecordIdentificationController.new
@@ -84,3 +84,108 @@ def test_rendering_partial_with_has_one_association
assert_equal mascot.name, @response.body
end
end
+
+class RenderPartialWithRecordIdentificationController < ActionController::Base
+ def render_with_has_many_and_belongs_to_association
+ @developer = Developer.find(1)
+ render :partial => @developer.projects
+ end
+
+ def render_with_has_many_association
+ @topic = Topic.find(1)
+ render :partial => @topic.replies
+ end
+
+ def render_with_has_many_through_association
+ @developer = Developer.find(:first)
+ render :partial => @developer.topics
+ end
+
+ def render_with_belongs_to_association
+ @reply = Reply.find(1)
+ render :partial => @reply.topic
+ end
+
+ def render_with_record
+ @developer = Developer.find(:first)
+ render :partial => @developer
+ end
+
+ def render_with_record_collection
+ @developers = Developer.find(:all)
+ render :partial => @developers
+ end
+end
+RenderPartialWithRecordIdentificationController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+class Game < Struct.new(:name, :id)
+ def to_param
+ id.to_s
+ end
+end
+
+module Fun
+ class NestedController < ActionController::Base
+ def render_with_record_in_nested_controller
+ render :partial => Game.new("Pong")
+ end
+
+ def render_with_record_collection_in_nested_controller
+ render :partial => [ Game.new("Pong"), Game.new("Tank") ]
+ end
+ end
+ NestedController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+
+ module Serious
+ class NestedDeeperController < ActionController::Base
+ def render_with_record_in_deeper_nested_controller
+ render :partial => Game.new("Chess")
+ end
+
+ def render_with_record_collection_in_deeper_nested_controller
+ render :partial => [ Game.new("Chess"), Game.new("Sudoku"), Game.new("Solitaire") ]
+ end
+ end
+ NestedDeeperController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
+ end
+end
+
+class RenderPartialWithRecordIdentificationAndNestedControllersTest < ActiveRecordTestCase
+ def setup
+ @controller = Fun::NestedController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ super
+ end
+
+ def test_render_with_record_in_nested_controller
+ get :render_with_record_in_nested_controller
+ assert_template 'fun/games/_game'
+ end
+
+ def test_render_with_record_collection_in_nested_controller
+ get :render_with_record_collection_in_nested_controller
+ assert_template 'fun/games/_game'
+ end
+
+end
+
+class RenderPartialWithRecordIdentificationAndNestedDeeperControllersTest < ActiveRecordTestCase
+ def setup
+ @controller = Fun::Serious::NestedDeeperController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ super
+ end
+
+ def test_render_with_record_in_deeper_nested_controller
+ get :render_with_record_in_deeper_nested_controller
+ assert_template 'fun/serious/games/_game'
+ end
+
+ def test_render_with_record_collection_in_deeper_nested_controller
+ get :render_with_record_collection_in_deeper_nested_controller
+ assert_template 'fun/serious/games/_game'
+ end
+
+end
@@ -57,6 +57,18 @@ def test_partial_path
assert_equal expected, partial_path(Comment)
end
+ def test_partial_path_with_namespaced_controller_path
+ expected = "admin/#{@plural}/#{@singular}"
+ assert_equal expected, partial_path(@record, "admin/posts")
+ assert_equal expected, partial_path(@klass, "admin/posts")
+ end
+
+ def test_partial_path_with_not_namespaced_controller_path
+ expected = "#{@plural}/#{@singular}"
+ assert_equal expected, partial_path(@record, "posts")
+ assert_equal expected, partial_path(@klass, "posts")
+ end
+
def test_dom_class
assert_equal @singular, dom_class(@record)
end
@@ -100,4 +112,28 @@ def test_partial_path
assert_equal expected, partial_path(@record)
assert_equal expected, partial_path(Comment::Nested)
end
+
+ def test_partial_path_with_namespaced_controller_path
+ expected = "admin/comment/nesteds/nested"
+ assert_equal expected, partial_path(@record, "admin/posts")
+ assert_equal expected, partial_path(@klass, "admin/posts")
+ end
+
+ def test_partial_path_with_deeper_namespaced_controller_path
+ expected = "deeper/admin/comment/nesteds/nested"
+ assert_equal expected, partial_path(@record, "deeper/admin/posts")
+ assert_equal expected, partial_path(@klass, "deeper/admin/posts")
+ end
+
+ def test_partial_path_with_even_deeper_namespaced_controller_path
+ expected = "even/more/deeper/admin/comment/nesteds/nested"
+ assert_equal expected, partial_path(@record, "even/more/deeper/admin/posts")
+ assert_equal expected, partial_path(@klass, "even/more/deeper/admin/posts")
+ end
+
+ def test_partial_path_with_not_namespaced_controller_path
+ expected = "comment/nesteds/nested"
+ assert_equal expected, partial_path(@record, "posts")
+ assert_equal expected, partial_path(@klass, "posts")
+ end
end
Oops, something went wrong.

0 comments on commit 9226b3e

Please sign in to comment.