Move the "email unsubscribe" resource, refactor the macaroon generator & simplify the access token verification logic. (#12986)

This simplifies the access token verification logic by removing the `rights`
parameter which was only ever used for the unsubscribe link in email
notifications. The latter has been moved under the `/_synapse` namespace,
since it is not a standard API.

This also makes the email verification link more secure, by embedding the
app_id and pushkey in the macaroon and verifying it. This prevents the user
from tampering the query parameters of that unsubscribe link.

Macaroon generation is refactored:

- Centralised all macaroon generation and verification logic to the
  `MacaroonGenerator`
- Moved to `synapse.utils`
- Changed the constructor to require only a `Clock`, hostname, and a secret key
  (instead of a full `Homeserver`).
- Added tests for all methods.
This commit is contained in:
Quentin Gliech 2022-06-14 15:12:08 +02:00 committed by GitHub
parent 09a3c5ce0b
commit fe1daad672
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 618 additions and 440 deletions

View file

@ -25,7 +25,7 @@ from synapse.handlers.sso import MappingException
from synapse.server import HomeServer
from synapse.types import JsonDict, UserID
from synapse.util import Clock
from synapse.util.macaroons import get_value_from_macaroon
from synapse.util.macaroons import OidcSessionData, get_value_from_macaroon
from tests.test_utils import FakeResponse, get_awaitable_result, simple_async_mock
from tests.unittest import HomeserverTestCase, override_config
@ -1227,7 +1227,7 @@ class OidcHandlerTestCase(HomeserverTestCase):
) -> str:
from synapse.handlers.oidc import OidcSessionData
return self.handler._token_generator.generate_oidc_session_token(
return self.handler._macaroon_generator.generate_oidc_session_token(
state=state,
session_data=OidcSessionData(
idp_id="oidc",
@ -1251,7 +1251,6 @@ async def _make_callback_with_userinfo(
userinfo: the OIDC userinfo dict
client_redirect_url: the URL to redirect to on success.
"""
from synapse.handlers.oidc import OidcSessionData
handler = hs.get_oidc_handler()
provider = handler._providers["oidc"]
@ -1260,7 +1259,7 @@ async def _make_callback_with_userinfo(
provider._fetch_userinfo = simple_async_mock(return_value=userinfo) # type: ignore[assignment]
state = "state"
session = handler._token_generator.generate_oidc_session_token(
session = handler._macaroon_generator.generate_oidc_session_token(
state=state,
session_data=OidcSessionData(
idp_id="oidc",