mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-09 08:10:08 +09:00
92 lines
3.3 KiB
Ruby
92 lines
3.3 KiB
Ruby
require "test_helper"
|
|
|
|
class FetchMetadataTest < ActionDispatch::IntegrationTest
|
|
setup do
|
|
host! "once.campfire.test"
|
|
@previous_exceptions = Rails.application.env_config["action_dispatch.show_exceptions"]
|
|
Rails.application.env_config["action_dispatch.show_exceptions"] = :rescuable
|
|
@previous_forgery = ActionController::Base.allow_forgery_protection
|
|
ActionController::Base.allow_forgery_protection = true
|
|
end
|
|
|
|
teardown do
|
|
ActionController::Base.allow_forgery_protection = @previous_forgery
|
|
Rails.application.env_config["action_dispatch.show_exceptions"] = @previous_exceptions
|
|
end
|
|
|
|
test "login and authenticated forms have no token fields" do
|
|
get new_session_url
|
|
assert_response :success
|
|
assert_select 'meta[name="csrf-token"]', count: 0
|
|
assert_select 'input[name="authenticity_token"]', count: 0
|
|
sign_in :david
|
|
get room_url(rooms(:watercooler))
|
|
assert_response :success
|
|
assert_select 'meta[name="csrf-token"]', count: 0
|
|
assert_select 'input[name="authenticity_token"]', count: 0
|
|
end
|
|
|
|
test "HTTPS login accepts browser metadata without a token" do
|
|
https!
|
|
%w[ same-origin same-site ].each do |site|
|
|
reset!
|
|
host! "once.campfire.test"
|
|
https!
|
|
post session_url, params: credentials, headers: {
|
|
"Sec-Fetch-Site" => site, "Origin" => "https://once.campfire.test" }
|
|
assert_response :redirect
|
|
assert cookies["session_token"].present?
|
|
end
|
|
end
|
|
|
|
test "HTTPS writes reject missing metadata even with a legacy token parameter" do
|
|
https!
|
|
assert_no_difference "Session.count" do
|
|
post session_url, params: credentials.merge(authenticity_token: "old token"), headers: { "Origin" => "https://once.campfire.test" }
|
|
end
|
|
assert_response :unprocessable_entity
|
|
end
|
|
|
|
test "cross-site none and malformed metadata cannot sign in over HTTP or HTTPS" do
|
|
[ false, true ].each do |tls|
|
|
https! tls
|
|
%w[ cross-site none garbage ].each do |site|
|
|
assert_no_difference "Session.count" do
|
|
post session_url, params: credentials, headers: { "Sec-Fetch-Site" => site }
|
|
end
|
|
assert_response :unprocessable_entity
|
|
end
|
|
end
|
|
end
|
|
|
|
test "provided foreign and null origins fail even with same-site metadata" do
|
|
%w[ https://foreign.example null ].each do |origin|
|
|
assert_no_difference "Session.count" do
|
|
post session_url, params: credentials, headers: { "Sec-Fetch-Site" => "same-site", "Origin" => origin }
|
|
end
|
|
assert_response :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
test "plain HTTP retains the missing-header fallback" do
|
|
post session_url, params: credentials, headers: { "Origin" => "http://once.campfire.test" }
|
|
assert_response :redirect
|
|
assert cookies["session_token"].present?
|
|
end
|
|
|
|
test "cross-site reads remain available and method-overridden writes stay protected" do
|
|
get new_session_url, headers: { "Sec-Fetch-Site" => "cross-site" }
|
|
assert_response :success
|
|
sign_in :david
|
|
assert_no_difference "Room.count" do
|
|
post room_path(rooms(:watercooler)), params: { _method: "delete" }, headers: { "Sec-Fetch-Site" => "cross-site" }
|
|
end
|
|
assert_response :unprocessable_entity
|
|
end
|
|
|
|
private
|
|
def credentials
|
|
{ email_address: users(:david).email_address, password: "secret123456" }
|
|
end
|
|
end
|