test_macaroons.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. # Copyright 2022 The Matrix.org Foundation C.I.C.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from pymacaroons.exceptions import MacaroonVerificationFailedException
  15. from synapse.util.macaroons import MacaroonGenerator, OidcSessionData
  16. from tests.server import get_clock
  17. from tests.unittest import TestCase
  18. class MacaroonGeneratorTestCase(TestCase):
  19. def setUp(self):
  20. self.reactor, hs_clock = get_clock()
  21. self.macaroon_generator = MacaroonGenerator(hs_clock, "tesths", b"verysecret")
  22. self.other_macaroon_generator = MacaroonGenerator(
  23. hs_clock, "tesths", b"anothersecretkey"
  24. )
  25. def test_guest_access_token(self):
  26. """Test the generation and verification of guest access tokens"""
  27. token = self.macaroon_generator.generate_guest_access_token("@user:tesths")
  28. user_id = self.macaroon_generator.verify_guest_token(token)
  29. self.assertEqual(user_id, "@user:tesths")
  30. # Raises with another secret key
  31. with self.assertRaises(MacaroonVerificationFailedException):
  32. self.other_macaroon_generator.verify_guest_token(token)
  33. # Check that an old access token without the guest caveat does not work
  34. macaroon = self.macaroon_generator._generate_base_macaroon("access")
  35. macaroon.add_first_party_caveat(f"user_id = {user_id}")
  36. macaroon.add_first_party_caveat("nonce = 0123456789abcdef")
  37. token = macaroon.serialize()
  38. with self.assertRaises(MacaroonVerificationFailedException):
  39. self.macaroon_generator.verify_guest_token(token)
  40. def test_delete_pusher_token(self):
  41. """Test the generation and verification of delete_pusher tokens"""
  42. token = self.macaroon_generator.generate_delete_pusher_token(
  43. "@user:tesths", "m.mail", "john@example.com"
  44. )
  45. user_id = self.macaroon_generator.verify_delete_pusher_token(
  46. token, "m.mail", "john@example.com"
  47. )
  48. self.assertEqual(user_id, "@user:tesths")
  49. # Raises with another secret key
  50. with self.assertRaises(MacaroonVerificationFailedException):
  51. self.other_macaroon_generator.verify_delete_pusher_token(
  52. token, "m.mail", "john@example.com"
  53. )
  54. # Raises when verifying for another pushkey
  55. with self.assertRaises(MacaroonVerificationFailedException):
  56. self.macaroon_generator.verify_delete_pusher_token(
  57. token, "m.mail", "other@example.com"
  58. )
  59. # Raises when verifying for another app_id
  60. with self.assertRaises(MacaroonVerificationFailedException):
  61. self.macaroon_generator.verify_delete_pusher_token(
  62. token, "somethingelse", "john@example.com"
  63. )
  64. # Check that an old token without the app_id and pushkey still works
  65. macaroon = self.macaroon_generator._generate_base_macaroon("delete_pusher")
  66. macaroon.add_first_party_caveat("user_id = @user:tesths")
  67. token = macaroon.serialize()
  68. user_id = self.macaroon_generator.verify_delete_pusher_token(
  69. token, "m.mail", "john@example.com"
  70. )
  71. self.assertEqual(user_id, "@user:tesths")
  72. def test_short_term_login_token(self):
  73. """Test the generation and verification of short-term login tokens"""
  74. token = self.macaroon_generator.generate_short_term_login_token(
  75. user_id="@user:tesths",
  76. auth_provider_id="oidc",
  77. auth_provider_session_id="sid",
  78. duration_in_ms=2 * 60 * 1000,
  79. )
  80. info = self.macaroon_generator.verify_short_term_login_token(token)
  81. self.assertEqual(info.user_id, "@user:tesths")
  82. self.assertEqual(info.auth_provider_id, "oidc")
  83. self.assertEqual(info.auth_provider_session_id, "sid")
  84. # Raises with another secret key
  85. with self.assertRaises(MacaroonVerificationFailedException):
  86. self.other_macaroon_generator.verify_short_term_login_token(token)
  87. # Wait a minute
  88. self.reactor.pump([60])
  89. # Shouldn't raise
  90. self.macaroon_generator.verify_short_term_login_token(token)
  91. # Wait another minute
  92. self.reactor.pump([60])
  93. # Should raise since it expired
  94. with self.assertRaises(MacaroonVerificationFailedException):
  95. self.macaroon_generator.verify_short_term_login_token(token)
  96. def test_oidc_session_token(self):
  97. """Test the generation and verification of OIDC session cookies"""
  98. state = "arandomstate"
  99. session_data = OidcSessionData(
  100. idp_id="oidc",
  101. nonce="nonce",
  102. client_redirect_url="https://example.com/",
  103. ui_auth_session_id="",
  104. )
  105. token = self.macaroon_generator.generate_oidc_session_token(
  106. state, session_data, duration_in_ms=2 * 60 * 1000
  107. ).encode("utf-8")
  108. info = self.macaroon_generator.verify_oidc_session_token(token, state)
  109. self.assertEqual(session_data, info)
  110. # Raises with another secret key
  111. with self.assertRaises(MacaroonVerificationFailedException):
  112. self.other_macaroon_generator.verify_oidc_session_token(token, state)
  113. # Should raise with another state
  114. with self.assertRaises(MacaroonVerificationFailedException):
  115. self.macaroon_generator.verify_oidc_session_token(token, "anotherstate")
  116. # Wait a minute
  117. self.reactor.pump([60])
  118. # Shouldn't raise
  119. self.macaroon_generator.verify_oidc_session_token(token, state)
  120. # Wait another minute
  121. self.reactor.pump([60])
  122. # Should raise since it expired
  123. with self.assertRaises(MacaroonVerificationFailedException):
  124. self.macaroon_generator.verify_oidc_session_token(token, state)