cookies_test.rb 44.4 KB
Newer Older
1 2
# frozen_string_literal: true

3 4 5
require "abstract_unit"
require "openssl"
require "active_support/key_generator"
6
require "active_support/messages/rotation_configuration"
D
Initial  
David Heinemeier Hansson 已提交
7

8 9 10 11
class CookieJarTest < ActiveSupport::TestCase
  attr_reader :request

  def setup
E
eileencodes 已提交
12
    @request = ActionDispatch::Request.empty
13 14 15 16
  end

  def test_fetch
    x = Object.new
17 18 19
    assert_not request.cookie_jar.key?("zzzzzz")
    assert_equal x, request.cookie_jar.fetch("zzzzzz", x)
    assert_not request.cookie_jar.key?("zzzzzz")
20 21 22 23
  end

  def test_fetch_exists
    x = Object.new
24 25
    request.cookie_jar["foo"] = "bar"
    assert_equal "bar", request.cookie_jar.fetch("foo", x)
26 27 28 29
  end

  def test_fetch_block
    x = Object.new
30 31
    assert_not request.cookie_jar.key?("zzzzzz")
    assert_equal x, request.cookie_jar.fetch("zzzzzz") { x }
32 33 34
  end

  def test_key_is_to_s
35 36
    request.cookie_jar["foo"] = "bar"
    assert_equal "bar", request.cookie_jar.fetch(:foo)
37 38
  end

39 40 41 42 43 44
  def test_to_hash
    request.cookie_jar["foo"] = "bar"
    assert_equal({ "foo" => "bar" }, request.cookie_jar.to_hash)
    assert_equal({ "foo" => "bar" }, request.cookie_jar.to_h)
  end

45 46 47 48 49 50 51
  def test_fetch_type_error
    assert_raises(KeyError) do
      request.cookie_jar.fetch(:omglolwut)
    end
  end

  def test_each
52
    request.cookie_jar["foo"] = :bar
53
    list = []
54
    request.cookie_jar.each do |k, v|
55 56 57
      list << [k, v]
    end

58
    assert_equal [["foo", :bar]], list
59 60 61
  end

  def test_enumerable
62
    request.cookie_jar["foo"] = :bar
63
    actual = request.cookie_jar.map { |k, v| [k.to_s, v.to_s] }
64
    assert_equal [["foo", "bar"]], actual
65 66 67
  end

  def test_key_methods
68 69
    assert_not request.cookie_jar.key?(:foo)
    assert_not request.cookie_jar.has_key?("foo")
70 71 72 73 74 75 76 77 78

    request.cookie_jar[:foo] = :bar
    assert request.cookie_jar.key?(:foo)
    assert request.cookie_jar.has_key?("foo")
  end

  def test_write_doesnt_set_a_nil_header
    headers = {}
    request.cookie_jar.write(headers)
79
    assert_not_includes headers, "Set-Cookie"
80 81 82
  end
end

83
class CookiesTest < ActionController::TestCase
84 85 86 87 88 89 90 91 92 93
  class CustomSerializer
    def self.load(value)
      value.to_s + " and loaded"
    end

    def self.dump(value)
      value.to_s + " was dumped"
    end
  end

D
Initial  
David Heinemeier Hansson 已提交
94
  class TestController < ActionController::Base
95 96
    def authenticate
      cookies["user_name"] = "david"
J
Jeremy Kemper 已提交
97
      head :ok
98 99
    end

100 101
    def set_with_with_escapable_characters
      cookies["that & guy"] = "foo & bar => baz"
J
Jeremy Kemper 已提交
102
      head :ok
103 104
    end

105
    def authenticate_for_fourteen_days
106
      cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10, 5) }
J
Jeremy Kemper 已提交
107
      head :ok
108 109
    end

110
    def authenticate_for_fourteen_days_with_symbols
111
      cookies[:user_name] = { value: "david", expires: Time.utc(2005, 10, 10, 5) }
J
Jeremy Kemper 已提交
112
      head :ok
113 114
    end

115
    def set_multiple_cookies
116
      cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10, 5) }
117
      cookies["login"]     = "XJ-122"
J
Jeremy Kemper 已提交
118
      head :ok
119
    end
J
Joshua Peek 已提交
120

121
    def access_frozen_cookies
J
Jeremy Kemper 已提交
122
      cookies["will"] = "work"
J
Jeremy Kemper 已提交
123
      head :ok
124 125
    end

126 127 128 129 130
    def set_cookie_if_not_present
      cookies["user_name"] = "alice" unless cookies["user_name"].present?
      head :ok
    end

131 132
    def logout
      cookies.delete("user_name")
J
Jeremy Kemper 已提交
133
      head :ok
134 135
    end

136 137
    alias delete_cookie logout

138
    def delete_cookie_with_path
139
      cookies.delete("user_name", path: "/beaten")
J
Jeremy Kemper 已提交
140
      head :ok
141 142
    end

143
    def authenticate_with_http_only
144
      cookies["user_name"] = { value: "david", httponly: true }
J
Jeremy Kemper 已提交
145
      head :ok
146
    end
147

148
    def authenticate_with_secure
149
      cookies["user_name"] = { value: "david", secure: true }
150 151
      head :ok
    end
152 153 154 155 156

    def set_permanent_cookie
      cookies.permanent[:user_name] = "Jamie"
      head :ok
    end
J
Joshua Peek 已提交
157

158 159 160 161
    def set_signed_cookie
      cookies.signed[:user_id] = 45
      head :ok
    end
J
Joshua Peek 已提交
162

163 164 165 166 167
    def get_signed_cookie
      cookies.signed[:user_id]
      head :ok
    end

168
    def set_encrypted_cookie
169
      cookies.encrypted[:foo] = "bar"
170 171 172
      head :ok
    end

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
    class JSONWrapper
      def initialize(obj)
        @obj = obj
      end

      def as_json(options = nil)
        "wrapped: #{@obj.as_json(options)}"
      end
    end

    def set_wrapped_signed_cookie
      cookies.signed[:user_id] = JSONWrapper.new(45)
      head :ok
    end

188
    def set_wrapped_encrypted_cookie
189
      cookies.encrypted[:foo] = JSONWrapper.new("bar")
190 191 192
      head :ok
    end

193 194 195 196 197
    def get_encrypted_cookie
      cookies.encrypted[:foo]
      head :ok
    end

198
    def set_invalid_encrypted_cookie
199
      cookies[:invalid_cookie] = "invalid--9170e00a57cfc27083363b5c75b835e477bd90cf"
200 201 202
      head :ok
    end

203
    def raise_data_overflow
204
      cookies.signed[:foo] = "bye!" * 1024
205 206 207 208 209 210 211 212 213
      head :ok
    end

    def tampered_cookies
      cookies[:tampered] = "BAh7BjoIZm9vIghiYXI%3D--123456780"
      cookies.signed[:tampered]
      head :ok
    end

214 215 216 217
    def set_permanent_signed_cookie
      cookies.permanent.signed[:remember_me] = 100
      head :ok
    end
218 219 220

    def delete_and_set_cookie
      cookies.delete :user_name
221
      cookies[:user_name] = { value: "david", expires: Time.utc(2005, 10, 10, 5) }
222 223
      head :ok
    end
224 225

    def set_cookie_with_domain
226
      cookies[:user_name] = { value: "rizwanreza", domain: :all }
227 228 229
      head :ok
    end

230
    def set_cookie_with_domain_all_as_string
231
      cookies[:user_name] = { value: "rizwanreza", domain: "all" }
232 233 234
      head :ok
    end

235
    def delete_cookie_with_domain
236
      cookies.delete(:user_name, domain: :all)
237 238
      head :ok
    end
239

240
    def delete_cookie_with_domain_all_as_string
241
      cookies.delete(:user_name, domain: "all")
242 243 244
      head :ok
    end

245
    def set_cookie_with_domain_and_tld
246
      cookies[:user_name] = { value: "rizwanreza", domain: :all, tld_length: 2 }
247 248 249 250
      head :ok
    end

    def delete_cookie_with_domain_and_tld
251
      cookies.delete(:user_name, domain: :all, tld_length: 2)
252 253 254
      head :ok
    end

255
    def set_cookie_with_domains
256
      cookies[:user_name] = { value: "rizwanreza", domain: %w(example1.com example2.com .example3.com) }
257 258 259 260
      head :ok
    end

    def delete_cookie_with_domains
261
      cookies.delete(:user_name, domain: %w(example1.com example2.com .example3.com))
262 263 264
      head :ok
    end

265 266 267 268 269 270
    def symbol_key
      cookies[:user_name] = "david"
      head :ok
    end

    def string_key
271
      cookies["user_name"] = "dhh"
272 273
      head :ok
    end
274 275 276 277 278 279 280

    def symbol_key_mock
      cookies[:user_name] = "david" if cookies[:user_name] == "andrew"
      head :ok
    end

    def string_key_mock
281
      cookies["user_name"] = "david" if cookies["user_name"] == "andrew"
282 283 284 285 286 287
      head :ok
    end

    def noop
      head :ok
    end
288 289 290 291

    def encrypted_cookie
      cookies.encrypted["foo"]
    end
292 293 294 295 296

    def cookie_expires_in_two_hours
      cookies[:user_name] = { value: "assain", expires: 2.hours }
      head :ok
    end
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319

    def encrypted_discount_and_user_id_cookie
      cookies.encrypted[:user_id] = { value: 50, expires: 1.hour }
      cookies.encrypted[:discount_percentage] = 10

      head :ok
    end

    def signed_discount_and_user_id_cookie
      cookies.signed[:user_id] = { value: 50, expires: 1.hour }
      cookies.signed[:discount_percentage] = 10

      head :ok
    end

    def rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_on
      # cookies.encrypted[:favorite] = { value: "5-2-Stable Chocolate Cookies", expires: 1000.years }
      cookies[:favorite] = "KvH5lIHvX5vPQkLIK63r/NuIMwzWky8M0Zwk8SZ6DwUv8+srf36geR4nWq5KmhsZIYXA8NRdCZYIfxMKJsOFlz77Gf+Fq8vBBCWJTp95rx39A28TCUTJEyMhCNJO5eie7Skef76Qt5Jo/SCnIADAhzyGQkGBopKRcA==--qXZZFWGbCy6N8AGy--WswoH+xHrNh9MzSXDpB2fA=="

      head :ok
    end

    def rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_off
320
      cookies[:favorite] = "rTG4zs5UufEFAr+ppKwh+MDMymKyAUMOSaWyYa3uUVmD8sMQqyiyQBxgYeAncDHVZIlo4y+kDVSzp66u1/7BNYpnmFe8ES/YT2m8ckNA23jBDmnRZ9CTNfMIRXjFtfxO9YxEOzzhn0ZiA0/zFtr5wkluXtxplOz959Q7MgLOyvTze2h9p8A=--QHOS3rAEGq/HCxXs--xQNra8dk24Idc2qBtpMLpg=="
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336

      head :ok
    end

    def rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_on
      # cookies.signed[:favorite] = { value: "5-2-Stable Choco Chip Cookie", expires: 1000.years }
      cookies[:favorite] = "eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaEpJaUUxTFRJdFUzUmhZbXhsSUVOb2IyTnZJRU5vYVhBZ1EyOXZhMmxsQmpvR1JWUT0iLCJleHAiOiIzMDE4LTA3LTExVDE2OjExOjI2Ljc1M1oiLCJwdXIiOm51bGx9fQ==--7df5d885b78b70a501d6e82140ae91b24060ac00"

      head :ok
    end

    def rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_off
      cookies[:favorite] = "BAhJIiE1LTItU3RhYmxlIENob2NvIENoaXAgQ29va2llBjoGRVQ=--50bbdbf8d64f5a3ec3e54878f54d4f55b6cb3aff"

      head :ok
    end
D
Initial  
David Heinemeier Hansson 已提交
337 338
  end

339
  tests TestController
D
Initial  
David Heinemeier Hansson 已提交
340

341 342 343
  SECRET_KEY_BASE = "b3c631c314c0bbca50c1b2843150fe33"
  SIGNED_COOKIE_SALT = "signed cookie"
  ENCRYPTED_COOKIE_SALT = "encrypted cookie"
344
  ENCRYPTED_SIGNED_COOKIE_SALT = "signed encrypted cookie"
345
  AUTHENTICATED_ENCRYPTED_COOKIE_SALT = "authenticated encrypted cookie"
346

347
  def setup
348
    super
A
Aaron Patterson 已提交
349

350 351
    @request.env["action_dispatch.key_generator"] = ActiveSupport::KeyGenerator.new(SECRET_KEY_BASE, iterations: 2)
    @request.env["action_dispatch.cookies_rotations"] = ActiveSupport::Messages::RotationConfiguration.new
A
Aaron Patterson 已提交
352

353 354 355 356 357 358 359
    @request.env["action_dispatch.secret_key_base"] = SECRET_KEY_BASE
    @request.env["action_dispatch.use_authenticated_cookie_encryption"] = true

    @request.env["action_dispatch.signed_cookie_salt"] = SIGNED_COOKIE_SALT
    @request.env["action_dispatch.encrypted_cookie_salt"] = ENCRYPTED_COOKIE_SALT
    @request.env["action_dispatch.encrypted_signed_cookie_salt"] = ENCRYPTED_SIGNED_COOKIE_SALT
    @request.env["action_dispatch.authenticated_encrypted_cookie_salt"] = AUTHENTICATED_ENCRYPTED_COOKIE_SALT
A
Aaron Patterson 已提交
360

361
    @request.host = "www.nextangle.com"
362 363
  end

D
Initial  
David Heinemeier Hansson 已提交
364
  def test_setting_cookie
365
    get :authenticate
J
Jeremy Kemper 已提交
366
    assert_cookie_header "user_name=david; path=/"
367
    assert_equal({ "user_name" => "david" }, @response.cookies)
D
Initial  
David Heinemeier Hansson 已提交
368 369
  end

370
  def test_setting_the_same_value_to_cookie
371
    request.cookies[:user_name] = "david"
372
    get :authenticate
373
    assert_empty response.cookies
374 375 376
  end

  def test_setting_the_same_value_to_permanent_cookie
377
    request.cookies[:user_name] = "Jamie"
378
    get :set_permanent_cookie
379
    assert_equal({ "user_name" => "Jamie" }, response.cookies)
380 381
  end

382 383
  def test_setting_with_escapable_characters
    get :set_with_with_escapable_characters
J
Jeremy Kemper 已提交
384
    assert_cookie_header "that+%26+guy=foo+%26+bar+%3D%3E+baz; path=/"
385
    assert_equal({ "that & guy" => "foo & bar => baz" }, @response.cookies)
386 387
  end

388
  def test_setting_cookie_for_fourteen_days
389
    get :authenticate_for_fourteen_days
390
    assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000"
391
    assert_equal({ "user_name" => "david" }, @response.cookies)
392
  end
393

394
  def test_setting_cookie_for_fourteen_days_with_symbols
P
Pratik Naik 已提交
395
    get :authenticate_for_fourteen_days_with_symbols
396
    assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000"
397
    assert_equal({ "user_name" => "david" }, @response.cookies)
398 399
  end

400 401
  def test_setting_cookie_with_http_only
    get :authenticate_with_http_only
J
Jeremy Kemper 已提交
402
    assert_cookie_header "user_name=david; path=/; HttpOnly"
403
    assert_equal({ "user_name" => "david" }, @response.cookies)
404
  end
405

406
  def test_setting_cookie_with_secure
407
    @request.env["HTTPS"] = "on"
408 409
    get :authenticate_with_secure
    assert_cookie_header "user_name=david; path=/; secure"
410
    assert_equal({ "user_name" => "david" }, @response.cookies)
411
  end
412

L
lest 已提交
413
  def test_setting_cookie_with_secure_when_always_write_cookie_is_true
414
    old_cookie, @request.cookie_jar.always_write_cookie = @request.cookie_jar.always_write_cookie, true
415 416
    get :authenticate_with_secure
    assert_cookie_header "user_name=david; path=/; secure"
417
    assert_equal({ "user_name" => "david" }, @response.cookies)
418 419
  ensure
    @request.cookie_jar.always_write_cookie = old_cookie
420 421 422 423 424
  end

  def test_not_setting_cookie_with_secure
    get :authenticate_with_secure
    assert_not_cookie_header "user_name=david; path=/; secure"
425
    assert_not_equal({ "user_name" => "david" }, @response.cookies)
426 427
  end

428
  def test_multiple_cookies
429 430
    get :set_multiple_cookies
    assert_equal 2, @response.cookies.size
431
    assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000\nlogin=XJ-122; path=/"
432
    assert_equal({ "login" => "XJ-122", "user_name" => "david" }, @response.cookies)
433
  end
434

435
  def test_setting_test_cookie
436 437
    assert_nothing_raised { get :access_frozen_cookies }
  end
J
Joshua Peek 已提交
438

439
  def test_expiring_cookie
440
    request.cookies[:user_name] = "Joe"
441
    get :logout
442
    assert_cookie_header "user_name=; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
443
    assert_equal({ "user_name" => nil }, @response.cookies)
444
  end
J
Joshua Peek 已提交
445

446
  def test_delete_cookie_with_path
447
    request.cookies[:user_name] = "Joe"
448
    get :delete_cookie_with_path
449
    assert_cookie_header "user_name=; path=/beaten; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
450
  end
J
Jeremy Kemper 已提交
451

452 453 454
  def test_delete_unexisting_cookie
    request.cookies.clear
    get :delete_cookie
455
    assert_empty @response.cookies
456 457
  end

458
  def test_deleted_cookie_predicate
459
    cookies[:user_name] = "Joe"
460 461 462 463 464 465
    cookies.delete("user_name")
    assert cookies.deleted?("user_name")
    assert_equal false, cookies.deleted?("another")
  end

  def test_deleted_cookie_predicate_with_mismatching_options
466
    cookies[:user_name] = "Joe"
467 468
    cookies.delete("user_name", path: "/path")
    assert_equal false, cookies.deleted?("user_name", path: "/different")
469 470
  end

471
  def test_cookies_persist_throughout_request
Y
Yehuda Katz 已提交
472
    response = get :authenticate
473
    assert_match(/user_name=david/, response.headers["Set-Cookie"])
474
  end
475

476
  def test_set_permanent_cookie
477
    get :set_permanent_cookie
478 479
    assert_match(/Jamie/, @response.headers["Set-Cookie"])
    assert_match(%r(#{20.years.from_now.utc.year}), @response.headers["Set-Cookie"])
480
  end
J
Joshua Peek 已提交
481

482 483
  def test_read_permanent_cookie
    get :set_permanent_cookie
484
    assert_equal "Jamie", @controller.send(:cookies).permanent[:user_name]
485 486
  end

487 488 489 490 491 492 493
  def test_signed_cookie_using_default_digest
    get :set_signed_cookie
    cookies = @controller.send :cookies
    assert_not_equal 45, cookies[:user_id]
    assert_equal 45, cookies.signed[:user_id]

    key_generator = @request.env["action_dispatch.key_generator"]
494
    secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
495

496
    verifier = ActiveSupport::MessageVerifier.new(secret, serializer: Marshal, digest: "SHA1")
497 498 499 500
    assert_equal verifier.generate(45), cookies[:user_id]
  end

  def test_signed_cookie_using_custom_digest
501 502
    @request.env["action_dispatch.signed_cookie_digest"] = "SHA256"

503 504 505 506 507 508
    get :set_signed_cookie
    cookies = @controller.send :cookies
    assert_not_equal 45, cookies[:user_id]
    assert_equal 45, cookies.signed[:user_id]

    key_generator = @request.env["action_dispatch.key_generator"]
509
    secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
510

511
    verifier = ActiveSupport::MessageVerifier.new(secret, serializer: Marshal, digest: "SHA256")
512 513 514
    assert_equal verifier.generate(45), cookies[:user_id]
  end

515 516
  def test_signed_cookie_rotating_secret_and_digest
    secret = "b3c631c314c0bbca50c1b2843150fe33"
517 518

    @request.env["action_dispatch.signed_cookie_digest"] = "SHA256"
519
    @request.env["action_dispatch.cookies_rotations"].rotate :signed, secret, digest: "SHA1"
520

521
    old_message = ActiveSupport::MessageVerifier.new(secret, digest: "SHA1", serializer: Marshal).generate(45)
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
    @request.headers["Cookie"] = "user_id=#{old_message}"

    get :get_signed_cookie
    assert_equal 45, @controller.send(:cookies).signed[:user_id]

    key_generator = @request.env["action_dispatch.key_generator"]
    secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
    verifier = ActiveSupport::MessageVerifier.new(secret, digest: "SHA256", serializer: Marshal)
    assert_equal 45, verifier.verify(@response.cookies["user_id"])
  end

  def test_tampered_with_signed_cookie
    key_generator = @request.env["action_dispatch.key_generator"]
    secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])

    verifier = ActiveSupport::MessageVerifier.new(secret, serializer: Marshal, digest: "SHA1")
    message = verifier.generate(45)

    @request.headers["Cookie"] = "user_id=#{Marshal.dump 45}--#{message.split("--").last}"
    get :get_signed_cookie
    assert_nil @controller.send(:cookies).signed[:user_id]
  end

545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
  def test_signed_cookie_using_default_serializer
    get :set_signed_cookie
    cookies = @controller.send :cookies
    assert_not_equal 45, cookies[:user_id]
    assert_equal 45, cookies.signed[:user_id]
  end

  def test_signed_cookie_using_marshal_serializer
    @request.env["action_dispatch.cookies_serializer"] = :marshal
    get :set_signed_cookie
    cookies = @controller.send :cookies
    assert_not_equal 45, cookies[:user_id]
    assert_equal 45, cookies.signed[:user_id]
  end

  def test_signed_cookie_using_json_serializer
    @request.env["action_dispatch.cookies_serializer"] = :json
    get :set_signed_cookie
    cookies = @controller.send :cookies
    assert_not_equal 45, cookies[:user_id]
    assert_equal 45, cookies.signed[:user_id]
  end

568 569 570 571
  def test_wrapped_signed_cookie_using_json_serializer
    @request.env["action_dispatch.cookies_serializer"] = :json
    get :set_wrapped_signed_cookie
    cookies = @controller.send :cookies
572 573
    assert_not_equal "wrapped: 45", cookies[:user_id]
    assert_equal "wrapped: 45", cookies.signed[:user_id]
574 575
  end

576 577 578 579
  def test_signed_cookie_using_custom_serializer
    @request.env["action_dispatch.cookies_serializer"] = CustomSerializer
    get :set_signed_cookie
    assert_not_equal 45, cookies[:user_id]
580
    assert_equal "45 was dumped and loaded", cookies.signed[:user_id]
581 582
  end

583
  def test_signed_cookie_using_hybrid_serializer_can_migrate_marshal_dumped_value_to_json
584 585 586
    @request.env["action_dispatch.cookies_serializer"] = :hybrid

    key_generator = @request.env["action_dispatch.key_generator"]
587
    secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
588 589 590

    marshal_value = ActiveSupport::MessageVerifier.new(secret, serializer: Marshal).generate(45)
    @request.headers["Cookie"] = "user_id=#{marshal_value}"
591 592 593 594 595 596

    get :get_signed_cookie

    cookies = @controller.send :cookies
    assert_not_equal 45, cookies[:user_id]
    assert_equal 45, cookies.signed[:user_id]
597

598
    verifier = ActiveSupport::MessageVerifier.new(secret, serializer: JSON)
599
    assert_equal 45, verifier.verify(@response.cookies["user_id"])
600 601 602 603 604 605
  end

  def test_signed_cookie_using_hybrid_serializer_can_read_from_json_dumped_value
    @request.env["action_dispatch.cookies_serializer"] = :hybrid

    key_generator = @request.env["action_dispatch.key_generator"]
606 607
    secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])

608 609
    json_value = ActiveSupport::MessageVerifier.new(secret, serializer: JSON).generate(45)
    @request.headers["Cookie"] = "user_id=#{json_value}"
610 611 612 613 614 615

    get :get_signed_cookie

    cookies = @controller.send :cookies
    assert_not_equal 45, cookies[:user_id]
    assert_equal 45, cookies.signed[:user_id]
616 617

    assert_nil @response.cookies["user_id"]
618 619
  end

M
Melissa Xie 已提交
620
  def test_accessing_nonexistent_signed_cookie_should_not_raise_an_invalid_signature
621
    get :set_signed_cookie
A
Abhishek Jain 已提交
622
    assert_nil @controller.send(:cookies).signed[:non_existent_attribute]
623 624
  end

625
  def test_encrypted_cookie_using_default_serializer
626 627
    get :set_encrypted_cookie
    cookies = @controller.send :cookies
628
    assert_not_equal "bar", cookies[:foo]
629
    assert_nil cookies.signed[:foo]
630
    assert_equal "bar", cookies.encrypted[:foo]
631 632
  end

633 634
  def test_encrypted_cookie_using_marshal_serializer
    @request.env["action_dispatch.cookies_serializer"] = :marshal
635
    get :set_encrypted_cookie
636
    cookies = @controller.send :cookies
637
    assert_not_equal "bar", cookies[:foo]
638
    assert_nil cookies.signed[:foo]
639
    assert_equal "bar", cookies.encrypted[:foo]
640 641 642
  end

  def test_encrypted_cookie_using_json_serializer
643
    @request.env["action_dispatch.cookies_serializer"] = :json
644 645
    get :set_encrypted_cookie
    cookies = @controller.send :cookies
646
    assert_not_equal "bar", cookies[:foo]
647
    assert_nil cookies.signed[:foo]
648
    assert_equal "bar", cookies.encrypted[:foo]
649 650
  end

651 652 653 654
  def test_wrapped_encrypted_cookie_using_json_serializer
    @request.env["action_dispatch.cookies_serializer"] = :json
    get :set_wrapped_encrypted_cookie
    cookies = @controller.send :cookies
655
    assert_not_equal "wrapped: bar", cookies[:foo]
656
    assert_nil cookies.signed[:foo]
657
    assert_equal "wrapped: bar", cookies.encrypted[:foo]
658 659
  end

660 661 662
  def test_encrypted_cookie_using_custom_serializer
    @request.env["action_dispatch.cookies_serializer"] = CustomSerializer
    get :set_encrypted_cookie
663 664
    assert_not_equal "bar", cookies.encrypted[:foo]
    assert_equal "bar was dumped and loaded", cookies.encrypted[:foo]
665 666
  end

667
  def test_encrypted_cookie_using_hybrid_serializer_can_migrate_marshal_dumped_value_to_json
668 669
    @request.env["action_dispatch.cookies_serializer"] = :hybrid

670 671
    key_generator = @request.env["action_dispatch.key_generator"]
    secret = key_generator.generate_key(@request.env["action_dispatch.authenticated_encrypted_cookie_salt"], 32)
672

673
    encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: Marshal)
674 675
    marshal_value = encryptor.encrypt_and_sign("bar")
    @request.headers["Cookie"] = "foo=#{::Rack::Utils.escape marshal_value}"
676 677 678 679

    get :get_encrypted_cookie

    cookies = @controller.send :cookies
680 681
    assert_not_equal "bar", cookies[:foo]
    assert_equal "bar", cookies.encrypted[:foo]
682

683
    json_encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: JSON)
684 685
    assert_not_nil @response.cookies["foo"]
    assert_equal "bar", json_encryptor.decrypt_and_verify(@response.cookies["foo"])
686 687
  end

G
Godfrey Chan 已提交
688
  def test_encrypted_cookie_using_hybrid_serializer_can_read_from_json_dumped_value
689 690
    @request.env["action_dispatch.cookies_serializer"] = :hybrid

691 692
    key_generator = @request.env["action_dispatch.key_generator"]
    secret = key_generator.generate_key(@request.env["action_dispatch.authenticated_encrypted_cookie_salt"], 32)
693

694
    encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: JSON)
695 696
    json_value = encryptor.encrypt_and_sign("bar")
    @request.headers["Cookie"] = "foo=#{::Rack::Utils.escape json_value}"
V
Vipul A M 已提交
697 698 699 700 701 702

    get :get_encrypted_cookie

    cookies = @controller.send :cookies
    assert_not_equal "bar", cookies[:foo]
    assert_equal "bar", cookies.encrypted[:foo]
703

V
Vipul A M 已提交
704 705 706
    assert_nil @response.cookies["foo"]
  end

M
Melissa Xie 已提交
707
  def test_accessing_nonexistent_encrypted_cookie_should_not_raise_invalid_message
708
    get :set_encrypted_cookie
A
Abhishek Jain 已提交
709
    assert_nil @controller.send(:cookies).encrypted[:non_existent_attribute]
710 711 712 713 714
  end

  def test_setting_invalid_encrypted_cookie_should_return_nil_when_accessing_it
    get :set_invalid_encrypted_cookie
    assert_nil @controller.send(:cookies).encrypted[:invalid_cookie]
715 716
  end

717 718
  def test_permanent_signed_cookie
    get :set_permanent_signed_cookie
719
    assert_match(%r(#{20.years.from_now.utc.year}), @response.headers["Set-Cookie"])
720 721 722
    assert_equal 100, @controller.send(:cookies).signed[:remember_me]
  end

723
  def test_delete_and_set_cookie
724
    request.cookies[:user_name] = "Joe"
725
    get :delete_and_set_cookie
726
    assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000"
727
    assert_equal({ "user_name" => "david" }, @response.cookies)
728
  end
J
Joshua Peek 已提交
729

730 731 732 733 734 735 736 737 738 739 740 741 742
  def test_raise_data_overflow
    assert_raise(ActionDispatch::Cookies::CookieOverflow) do
      get :raise_data_overflow
    end
  end

  def test_tampered_cookies
    assert_nothing_raised do
      get :tampered_cookies
      assert_response :success
    end
  end

743 744 745 746 747 748 749 750 751
  def test_cookie_jar_mutated_by_request_persists_on_future_requests
    get :authenticate
    cookie_jar = @request.cookie_jar
    cookie_jar.signed[:user_id] = 123
    assert_equal ["user_name", "user_id"], @request.cookie_jar.instance_variable_get(:@cookies).keys
    get :get_signed_cookie
    assert_equal ["user_name", "user_id"], @request.cookie_jar.instance_variable_get(:@cookies).keys
  end

752
  def test_legacy_signed_cookie_is_treated_as_nil_by_signed_cookie_jar_if_tampered
753 754 755
    @request.headers["Cookie"] = "user_id=45"
    get :get_signed_cookie

756 757
    assert_nil @controller.send(:cookies).signed[:user_id]
    assert_nil @response.cookies["user_id"]
758 759
  end

760 761 762 763
  def test_legacy_signed_cookie_is_treated_as_nil_by_encrypted_cookie_jar_if_tampered
    @request.headers["Cookie"] = "foo=baz"
    get :get_encrypted_cookie

764 765
    assert_nil @controller.send(:cookies).encrypted[:foo]
    assert_nil @response.cookies["foo"]
766 767
  end

768 769
  def test_use_authenticated_cookie_encryption_uses_legacy_hmac_aes_cbc_encryption_when_not_enabled
    @request.env["action_dispatch.use_authenticated_cookie_encryption"] = nil
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785

    key_generator = @request.env["action_dispatch.key_generator"]
    encrypted_cookie_salt = @request.env["action_dispatch.encrypted_cookie_salt"]
    encrypted_signed_cookie_salt = @request.env["action_dispatch.encrypted_signed_cookie_salt"]
    secret = key_generator.generate_key(encrypted_cookie_salt, ActiveSupport::MessageEncryptor.key_len("aes-256-cbc"))
    sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)
    encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, cipher: "aes-256-cbc", digest: "SHA1", serializer: Marshal)

    get :set_encrypted_cookie

    cookies = @controller.send :cookies
    assert_not_equal "bar", cookies[:foo]
    assert_equal "bar", cookies.encrypted[:foo]
    assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
  end

786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
  def test_rotating_signed_cookies_digest
    @request.env["action_dispatch.signed_cookie_digest"] = "SHA256"
    @request.env["action_dispatch.cookies_rotations"].rotate :signed, digest: "SHA1"

    key_generator = @request.env["action_dispatch.key_generator"]

    old_secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
    old_value = ActiveSupport::MessageVerifier.new(old_secret).generate(45)

    @request.headers["Cookie"] = "user_id=#{old_value}"
    get :get_signed_cookie

    assert_equal 45, @controller.send(:cookies).signed[:user_id]

    secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
    verifier = ActiveSupport::MessageVerifier.new(secret, digest: "SHA256")
    assert_equal 45, verifier.verify(@response.cookies["user_id"])
  end

805 806 807 808
  def test_legacy_hmac_aes_cbc_encrypted_marshal_cookie_is_upgraded_to_authenticated_encrypted_cookie
    key_generator = @request.env["action_dispatch.key_generator"]
    encrypted_cookie_salt = @request.env["action_dispatch.encrypted_cookie_salt"]
    encrypted_signed_cookie_salt = @request.env["action_dispatch.encrypted_signed_cookie_salt"]
809
    secret = key_generator.generate_key(encrypted_cookie_salt, ActiveSupport::MessageEncryptor.key_len("aes-256-cbc"))
810
    sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)
811
    marshal_value = ActiveSupport::MessageEncryptor.new(secret, sign_secret, cipher: "aes-256-cbc", serializer: Marshal).encrypt_and_sign("bar")
812 813 814 815 816 817 818 819 820 821

    @request.headers["Cookie"] = "foo=#{marshal_value}"

    get :get_encrypted_cookie

    cookies = @controller.send :cookies
    assert_not_equal "bar", cookies[:foo]
    assert_equal "bar", cookies.encrypted[:foo]

    aead_salt = @request.env["action_dispatch.authenticated_encrypted_cookie_salt"]
822 823
    aead_secret = key_generator.generate_key(aead_salt, ActiveSupport::MessageEncryptor.key_len("aes-256-gcm"))
    aead_encryptor = ActiveSupport::MessageEncryptor.new(aead_secret, cipher: "aes-256-gcm", serializer: Marshal)
824 825 826 827 828 829 830 831 832 833

    assert_equal "bar", aead_encryptor.decrypt_and_verify(@response.cookies["foo"])
  end

  def test_legacy_hmac_aes_cbc_encrypted_json_cookie_is_upgraded_to_authenticated_encrypted_cookie
    @request.env["action_dispatch.cookies_serializer"] = :json

    key_generator = @request.env["action_dispatch.key_generator"]
    encrypted_cookie_salt = @request.env["action_dispatch.encrypted_cookie_salt"]
    encrypted_signed_cookie_salt = @request.env["action_dispatch.encrypted_signed_cookie_salt"]
834
    secret = key_generator.generate_key(encrypted_cookie_salt, ActiveSupport::MessageEncryptor.key_len("aes-256-cbc"))
835
    sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)
836
    marshal_value = ActiveSupport::MessageEncryptor.new(secret, sign_secret, cipher: "aes-256-cbc", serializer: JSON).encrypt_and_sign("bar")
837 838 839 840 841 842 843 844 845 846

    @request.headers["Cookie"] = "foo=#{marshal_value}"

    get :get_encrypted_cookie

    cookies = @controller.send :cookies
    assert_not_equal "bar", cookies[:foo]
    assert_equal "bar", cookies.encrypted[:foo]

    aead_salt = @request.env["action_dispatch.authenticated_encrypted_cookie_salt"]
847 848
    aead_secret = key_generator.generate_key(aead_salt)[0, ActiveSupport::MessageEncryptor.key_len("aes-256-gcm")]
    aead_encryptor = ActiveSupport::MessageEncryptor.new(aead_secret, cipher: "aes-256-gcm", serializer: JSON)
849 850 851 852 853 854

    assert_equal "bar", aead_encryptor.decrypt_and_verify(@response.cookies["foo"])
  end

  def test_legacy_hmac_aes_cbc_encrypted_cookie_using_64_byte_key_is_upgraded_to_authenticated_encrypted_cookie
    @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
855 856
    @request.env["action_dispatch.encrypted_cookie_salt"] = "b3c631c314c0bbca50c1b2843150fe33"
    @request.env["action_dispatch.encrypted_signed_cookie_salt"] = "b3c631c314c0bbca50c1b2843150fe33"
857 858 859 860 861 862 863 864 865 866 867 868

    # Cookie generated with 64 bytes secret
    message = ["566d4e75536d686e633246564e6b493062557079626c566d51574d30515430394c53315665564a694e4563786555744f57537454576b396a5a31566a626e52525054303d2d2d34663234333330623130623261306163363562316266323335396164666364613564643134623131"].pack("H*")
    @request.headers["Cookie"] = "foo=#{message}"

    get :get_encrypted_cookie

    cookies = @controller.send :cookies
    assert_not_equal "bar", cookies[:foo]
    assert_equal "bar", cookies.encrypted[:foo]

    salt = @request.env["action_dispatch.authenticated_encrypted_cookie_salt"]
869 870
    secret = @request.env["action_dispatch.key_generator"].generate_key(salt, ActiveSupport::MessageEncryptor.key_len("aes-256-gcm"))
    encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: Marshal)
871 872 873 874

    assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
  end

875 876
  def test_encrypted_cookie_rotating_secret
    secret = "b3c631c314c0bbca50c1b2843150fe33"
877 878

    @request.env["action_dispatch.encrypted_cookie_cipher"] = "aes-256-gcm"
879
    @request.env["action_dispatch.cookies_rotations"].rotate :encrypted, secret
880 881 882

    key_len = ActiveSupport::MessageEncryptor.key_len("aes-256-gcm")

883
    old_message = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: Marshal).encrypt_and_sign(45)
884 885 886 887 888 889 890 891 892 893 894 895

    @request.headers["Cookie"] = "foo=#{::Rack::Utils.escape old_message}"

    get :get_encrypted_cookie
    assert_equal 45, @controller.send(:cookies).encrypted[:foo]

    key_generator = @request.env["action_dispatch.key_generator"]
    secret = key_generator.generate_key(@request.env["action_dispatch.authenticated_encrypted_cookie_salt"], key_len)
    encryptor = ActiveSupport::MessageEncryptor.new(secret, cipher: "aes-256-gcm", serializer: Marshal)
    assert_equal 45, encryptor.decrypt_and_verify(@response.cookies["foo"])
  end

896 897 898 899 900 901 902 903 904 905 906 907 908
  def test_cookie_with_hash_value_not_modified_by_rotation
    @request.env["action_dispatch.signed_cookie_digest"] = "SHA256"
    @request.env["action_dispatch.cookies_rotations"].rotate :signed, digest: "SHA1"

    key_generator = @request.env["action_dispatch.key_generator"]
    old_secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
    old_value = ActiveSupport::MessageVerifier.new(old_secret).generate(bar: "baz")

    @request.headers["Cookie"] = "foo=#{old_value}"
    get :get_signed_cookie
    assert_equal({ bar: "baz" }, @controller.send(:cookies).signed[:foo])
  end

909 910 911 912 913 914
  def test_cookie_with_all_domain_option
    get :set_cookie_with_domain
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; domain=.nextangle.com; path=/"
  end

915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
  def test_cookie_with_all_domain_option_using_a_non_standard_tld
    @request.host = "two.subdomains.nextangle.local"
    get :set_cookie_with_domain
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; domain=.nextangle.local; path=/"
  end

  def test_cookie_with_all_domain_option_using_australian_style_tld
    @request.host = "nextangle.com.au"
    get :set_cookie_with_domain
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; domain=.nextangle.com.au; path=/"
  end

  def test_cookie_with_all_domain_option_using_uk_style_tld
    @request.host = "nextangle.co.uk"
    get :set_cookie_with_domain
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; domain=.nextangle.co.uk; path=/"
  end

  def test_cookie_with_all_domain_option_using_host_with_port
    @request.host = "nextangle.local:3000"
    get :set_cookie_with_domain
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; domain=.nextangle.local; path=/"
  end

943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963
  def test_cookie_with_all_domain_option_using_localhost
    @request.host = "localhost"
    get :set_cookie_with_domain
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; path=/"
  end

  def test_cookie_with_all_domain_option_using_ipv4_address
    @request.host = "192.168.1.1"
    get :set_cookie_with_domain
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; path=/"
  end

  def test_cookie_with_all_domain_option_using_ipv6_address
    @request.host = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
    get :set_cookie_with_domain
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; path=/"
  end

964
  def test_deleting_cookie_with_all_domain_option
965
    request.cookies[:user_name] = "Joe"
966 967
    get :delete_cookie_with_domain
    assert_response :success
968
    assert_cookie_header "user_name=; domain=.nextangle.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
969 970
  end

971 972 973 974 975 976 977 978 979 980 981 982 983
  def test_cookie_with_all_domain_option_and_tld_length
    get :set_cookie_with_domain_and_tld
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; domain=.nextangle.com; path=/"
  end

  def test_cookie_with_all_domain_option_using_a_non_standard_tld_and_tld_length
    @request.host = "two.subdomains.nextangle.local"
    get :set_cookie_with_domain_and_tld
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; domain=.nextangle.local; path=/"
  end

984 985 986 987 988 989 990
  def test_cookie_with_all_domain_option_using_a_non_standard_2_letter_tld
    @request.host = "admin.lvh.me"
    get :set_cookie_with_domain_and_tld
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; domain=.lvh.me; path=/"
  end

991 992 993 994 995 996 997 998
  def test_cookie_with_all_domain_option_using_host_with_port_and_tld_length
    @request.host = "nextangle.local:3000"
    get :set_cookie_with_domain_and_tld
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; domain=.nextangle.local; path=/"
  end

  def test_deleting_cookie_with_all_domain_option_and_tld_length
999
    request.cookies[:user_name] = "Joe"
1000 1001
    get :delete_cookie_with_domain_and_tld
    assert_response :success
1002
    assert_cookie_header "user_name=; domain=.nextangle.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
1003 1004
  end

1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
  def test_cookie_with_several_preset_domains_using_one_of_these_domains
    @request.host = "example1.com"
    get :set_cookie_with_domains
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; domain=example1.com; path=/"
  end

  def test_cookie_with_several_preset_domains_using_other_domain
    @request.host = "other-domain.com"
    get :set_cookie_with_domains
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; path=/"
  end

  def test_cookie_with_several_preset_domains_using_shared_domain
    @request.host = "example3.com"
    get :set_cookie_with_domains
    assert_response :success
    assert_cookie_header "user_name=rizwanreza; domain=.example3.com; path=/"
  end

  def test_deletings_cookie_with_several_preset_domains_using_one_of_these_domains
    @request.host = "example2.com"
1028
    request.cookies[:user_name] = "Joe"
1029 1030
    get :delete_cookie_with_domains
    assert_response :success
1031
    assert_cookie_header "user_name=; domain=example2.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
1032 1033 1034 1035
  end

  def test_deletings_cookie_with_several_preset_domains_using_other_domain
    @request.host = "other-domain.com"
1036
    request.cookies[:user_name] = "Joe"
1037 1038
    get :delete_cookie_with_domains
    assert_response :success
1039
    assert_cookie_header "user_name=; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
1040 1041
  end

1042
  def test_cookies_hash_is_indifferent_access
1043 1044
    get :symbol_key
    assert_equal "david", cookies[:user_name]
1045
    assert_equal "david", cookies["user_name"]
1046 1047
    get :string_key
    assert_equal "dhh", cookies[:user_name]
1048
    assert_equal "dhh", cookies["user_name"]
1049 1050
  end

1051
  def test_setting_request_cookies_is_indifferent_access
1052 1053
    cookies.clear
    cookies[:user_name] = "andrew"
1054
    get :string_key_mock
1055
    assert_equal "david", cookies["user_name"]
1056

1057
    cookies.clear
1058
    cookies["user_name"] = "andrew"
1059
    get :symbol_key_mock
1060
    assert_equal "david", cookies[:user_name]
1061 1062 1063 1064
  end

  def test_cookies_retained_across_requests
    get :symbol_key
1065
    assert_cookie_header "user_name=david; path=/"
1066 1067 1068
    assert_equal "david", cookies[:user_name]

    get :noop
1069
    assert_not_includes @response.headers, "Set-Cookie"
1070 1071 1072
    assert_equal "david", cookies[:user_name]

    get :noop
1073
    assert_not_includes @response.headers, "Set-Cookie"
1074 1075 1076 1077 1078 1079 1080
    assert_equal "david", cookies[:user_name]
  end

  def test_cookies_can_be_cleared
    get :symbol_key
    assert_equal "david", cookies[:user_name]

1081
    cookies.clear
1082 1083 1084 1085 1086 1087 1088
    get :noop
    assert_nil cookies[:user_name]

    get :symbol_key
    assert_equal "david", cookies[:user_name]
  end

1089
  def test_can_set_http_cookie_header
1090
    @request.env["HTTP_COOKIE"] = "user_name=david"
1091
    get :noop
1092 1093
    assert_equal "david", cookies["user_name"]
    assert_equal "david", cookies[:user_name]
1094 1095

    get :noop
1096 1097
    assert_equal "david", cookies["user_name"]
    assert_equal "david", cookies[:user_name]
1098

1099
    @request.env["HTTP_COOKIE"] = "user_name=andrew"
1100
    get :noop
1101 1102
    assert_equal "andrew", cookies["user_name"]
    assert_equal "andrew", cookies[:user_name]
1103 1104 1105
  end

  def test_can_set_request_cookies
1106
    @request.cookies["user_name"] = "david"
1107
    get :noop
1108 1109
    assert_equal "david", cookies["user_name"]
    assert_equal "david", cookies[:user_name]
1110 1111

    get :noop
1112 1113
    assert_equal "david", cookies["user_name"]
    assert_equal "david", cookies[:user_name]
1114

1115
    @request.cookies[:user_name] = "andrew"
1116
    get :noop
1117 1118
    assert_equal "andrew", cookies["user_name"]
    assert_equal "andrew", cookies[:user_name]
1119 1120 1121
  end

  def test_cookies_precedence_over_http_cookie
1122
    @request.env["HTTP_COOKIE"] = "user_name=andrew"
1123
    get :authenticate
1124 1125
    assert_equal "david", cookies["user_name"]
    assert_equal "david", cookies[:user_name]
1126 1127

    get :noop
1128 1129
    assert_equal "david", cookies["user_name"]
    assert_equal "david", cookies[:user_name]
1130 1131 1132
  end

  def test_cookies_precedence_over_request_cookies
1133
    @request.cookies["user_name"] = "andrew"
1134
    get :authenticate
1135 1136
    assert_equal "david", cookies["user_name"]
    assert_equal "david", cookies[:user_name]
1137

1138
    get :noop
1139 1140
    assert_equal "david", cookies["user_name"]
    assert_equal "david", cookies[:user_name]
1141 1142
  end

1143 1144 1145 1146 1147 1148
  def test_cookies_are_not_cleared
    cookies.encrypted["foo"] = "bar"
    get :noop
    assert_equal "bar", @controller.encrypted_cookie
  end

1149 1150 1151 1152 1153 1154 1155 1156
  def test_cookie_override
    get :set_cookie_if_not_present
    assert_equal "alice", cookies["user_name"]
    cookies["user_name"] = "bob"
    get :set_cookie_if_not_present
    assert_equal "bob", cookies["user_name"]
  end

1157
  def test_signed_cookie_with_expires_set_relatively
1158 1159
    request.env["action_dispatch.use_cookies_with_metadata"] = true

1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
    cookies.signed[:user_name] = { value: "assain", expires: 2.hours }

    travel 1.hour
    assert_equal "assain", cookies.signed[:user_name]

    travel 2.hours
    assert_nil cookies.signed[:user_name]
  end

  def test_encrypted_cookie_with_expires_set_relatively
1170 1171
    request.env["action_dispatch.use_cookies_with_metadata"] = true

1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187
    cookies.encrypted[:user_name] = { value: "assain", expires: 2.hours }

    travel 1.hour
    assert_equal "assain", cookies.encrypted[:user_name]

    travel 2.hours
    assert_nil cookies.encrypted[:user_name]
  end

  def test_vanilla_cookie_with_expires_set_relatively
    travel_to Time.utc(2017, 8, 15) do
      get :cookie_expires_in_two_hours
      assert_cookie_header "user_name=assain; path=/; expires=Tue, 15 Aug 2017 02:00:00 -0000"
    end
  end

1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221
  def test_purpose_metadata_for_encrypted_cookies
    get :encrypted_discount_and_user_id_cookie

    cookies[:discount_percentage] = cookies[:user_id]
    assert_equal 50, cookies.encrypted[:discount_percentage]

    request.env["action_dispatch.use_cookies_with_metadata"] = true

    get :encrypted_discount_and_user_id_cookie

    cookies[:discount_percentage] = cookies[:user_id]
    assert_nil cookies.encrypted[:discount_percentage]
  end

  def test_purpose_metadata_for_signed_cookies
    get :signed_discount_and_user_id_cookie

    cookies[:discount_percentage] = cookies[:user_id]
    assert_equal 50, cookies.signed[:discount_percentage]

    request.env["action_dispatch.use_cookies_with_metadata"] = true

    get :signed_discount_and_user_id_cookie

    cookies[:discount_percentage] = cookies[:user_id]
    assert_nil cookies.signed[:discount_percentage]
  end

  def test_switch_off_metadata_for_encrypted_cookies_if_config_is_false
    request.env["action_dispatch.use_cookies_with_metadata"] = false

    get :encrypted_discount_and_user_id_cookie

    travel 2.hours
1222
    assert_nil cookies.signed[:user_id]
1223 1224 1225 1226 1227 1228 1229 1230 1231
  end

  def test_switch_off_metadata_for_signed_cookies_if_config_is_false
    request.env["action_dispatch.use_cookies_with_metadata"] = false

    get :signed_discount_and_user_id_cookie

    travel 2.hours

1232
    assert_nil cookies.signed[:user_id]
1233 1234 1235 1236 1237 1238 1239 1240 1241
  end

  def test_read_rails_5_2_stable_encrypted_cookies_if_config_is_false
    request.env["action_dispatch.use_cookies_with_metadata"] = false

    get :rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_on

    assert_equal "5-2-Stable Chocolate Cookies", cookies.encrypted[:favorite]

1242
    travel 1001.years do
1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257
      assert_nil cookies.encrypted[:favorite]
    end

    get :rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_off

    assert_equal "5-2-Stable Chocolate Cookies", cookies.encrypted[:favorite]
  end

  def test_read_rails_5_2_stable_signed_cookies_if_config_is_false
    request.env["action_dispatch.use_cookies_with_metadata"] = false

    get :rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_on

    assert_equal "5-2-Stable Choco Chip Cookie", cookies.signed[:favorite]

1258
    travel 1001.years do
1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
      assert_nil cookies.signed[:favorite]
    end

    get :rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_off

    assert_equal "5-2-Stable Choco Chip Cookie", cookies.signed[:favorite]
  end

  def test_read_rails_5_2_stable_encrypted_cookies_if_use_metadata_config_is_true
    request.env["action_dispatch.use_cookies_with_metadata"] = true

    get :rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_on

    assert_equal "5-2-Stable Chocolate Cookies", cookies.encrypted[:favorite]

1274
    travel 1001.years do
1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289
      assert_nil cookies.encrypted[:favorite]
    end

    get :rails_5_2_stable_encrypted_cookie_with_authenticated_encryption_flag_off

    assert_equal "5-2-Stable Chocolate Cookies", cookies.encrypted[:favorite]
  end

  def test_read_rails_5_2_stable_signed_cookies_if_use_metadata_config_is_true
    request.env["action_dispatch.use_cookies_with_metadata"] = true

    get :rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_on

    assert_equal "5-2-Stable Choco Chip Cookie", cookies.signed[:favorite]

1290
    travel 1001.years do
1291 1292 1293 1294 1295 1296 1297 1298
      assert_nil cookies.signed[:favorite]
    end

    get :rails_5_2_stable_signed_cookie_with_authenticated_encryption_flag_off

    assert_equal "5-2-Stable Choco Chip Cookie", cookies.signed[:favorite]
  end

J
Jeremy Kemper 已提交
1299 1300 1301 1302
  private
    def assert_cookie_header(expected)
      header = @response.headers["Set-Cookie"]
      if header.respond_to?(:to_str)
1303
        assert_equal expected.split("\n").sort, header.split("\n").sort
J
Jeremy Kemper 已提交
1304 1305 1306 1307
      else
        assert_equal expected.split("\n"), header
      end
    end
1308 1309 1310 1311 1312 1313 1314 1315 1316

    def assert_not_cookie_header(expected)
      header = @response.headers["Set-Cookie"]
      if header.respond_to?(:to_str)
        assert_not_equal expected.split("\n").sort, header.split("\n").sort
      else
        assert_not_equal expected.split("\n"), header
      end
    end
1317
end