Fix backwards compat for DirectServeJsonResource (#18600)

As that appears in the module API.

Broke in #18595.
This commit is contained in:
Erik Johnston
2025-06-26 15:05:48 +01:00
committed by GitHub
parent 434e38941a
commit de29c13d41
19 changed files with 56 additions and 29 deletions

14
Cargo.lock generated
View File

@@ -65,6 +65,12 @@ dependencies = [
"windows-targets",
]
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
@@ -365,7 +371,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
dependencies = [
"base64",
"base64 0.22.1",
"bytes",
"headers-core",
"http",
@@ -485,7 +491,7 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb"
dependencies = [
"base64",
"base64 0.22.1",
"bytes",
"futures-channel",
"futures-core",
@@ -1053,7 +1059,7 @@ version = "0.12.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813"
dependencies = [
"base64",
"base64 0.22.1",
"bytes",
"futures-core",
"futures-util",
@@ -1327,7 +1333,7 @@ name = "synapse"
version = "0.1.0"
dependencies = [
"anyhow",
"base64",
"base64 0.21.7",
"blake2",
"bytes",
"futures",

1
changelog.d/18600.misc Normal file
View File

@@ -0,0 +1 @@
Better handling of ratelimited requests.

View File

@@ -53,7 +53,7 @@ class AdditionalResource(DirectServeJsonResource):
hs: homeserver
handler: function to be called to handle the request.
"""
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._handler = handler
async def _async_render(self, request: Request) -> Optional[Tuple[int, Any]]:

View File

@@ -42,6 +42,7 @@ from typing import (
Protocol,
Tuple,
Union,
cast,
)
import attr
@@ -49,8 +50,9 @@ import jinja2
from canonicaljson import encode_canonical_json
from zope.interface import implementer
from twisted.internet import defer, interfaces
from twisted.internet import defer, interfaces, reactor
from twisted.internet.defer import CancelledError
from twisted.internet.interfaces import IReactorTime
from twisted.python import failure
from twisted.web import resource
@@ -401,8 +403,15 @@ class DirectServeJsonResource(_AsyncResource):
"""
def __init__(
self, clock: Clock, canonical_json: bool = False, extract_context: bool = False
self,
canonical_json: bool = False,
extract_context: bool = False,
# Clock is optional as this class is exposed to the module API.
clock: Optional[Clock] = None,
):
if clock is None:
clock = Clock(cast(IReactorTime, reactor))
super().__init__(clock, extract_context)
self.canonical_json = canonical_json
@@ -460,7 +469,7 @@ class JsonResource(DirectServeJsonResource):
extract_context: bool = False,
):
self.clock = hs.get_clock()
super().__init__(self.clock, canonical_json, extract_context)
super().__init__(canonical_json, extract_context, clock=self.clock)
# Map of path regex -> method -> callback.
self._routes: Dict[Pattern[str], Dict[bytes, _PathEntry]] = {}
self.hs = hs
@@ -573,6 +582,17 @@ class DirectServeHtmlResource(_AsyncResource):
# The error template to use for this resource
ERROR_TEMPLATE = HTML_ERROR_TEMPLATE
def __init__(
self,
extract_context: bool = False,
# Clock is optional as this class is exposed to the module API.
clock: Optional[Clock] = None,
):
if clock is None:
clock = Clock(cast(IReactorTime, reactor))
super().__init__(clock, extract_context)
def _send_response(
self,
request: "SynapseRequest",

View File

@@ -81,7 +81,7 @@ class ConsentResource(DirectServeHtmlResource):
"""
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self.hs = hs
self.store = hs.get_datastores().main

View File

@@ -44,7 +44,7 @@ class FederationWhitelistResource(DirectServeJsonResource):
PATH = "/_synapse/client/v1/config/federation_whitelist"
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._federation_whitelist = hs.config.federation.federation_domain_whitelist

View File

@@ -33,7 +33,7 @@ logger = logging.getLogger(__name__)
class JwksResource(DirectServeJsonResource):
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock(), extract_context=True)
super().__init__(clock=hs.get_clock(), extract_context=True)
# Parameters that are allowed to be exposed in the public key.
# This is done manually, because authlib's private to public key conversion

View File

@@ -48,7 +48,7 @@ class NewUserConsentResource(DirectServeHtmlResource):
"""
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._sso_handler = hs.get_sso_handler()
self._server_name = hs.hostname
self._consent_version = hs.config.consent.user_consent_version

View File

@@ -35,7 +35,7 @@ class OIDCBackchannelLogoutResource(DirectServeJsonResource):
isLeaf = 1
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._oidc_handler = hs.get_oidc_handler()
async def _async_render_POST(self, request: SynapseRequest) -> None:

View File

@@ -35,7 +35,7 @@ class OIDCCallbackResource(DirectServeHtmlResource):
isLeaf = 1
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._oidc_handler = hs.get_oidc_handler()
async def _async_render_GET(self, request: SynapseRequest) -> None:

View File

@@ -47,7 +47,7 @@ class PasswordResetSubmitTokenResource(DirectServeHtmlResource):
Args:
hs: server
"""
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self.clock = hs.get_clock()
self.store = hs.get_datastores().main

View File

@@ -44,7 +44,7 @@ class PickIdpResource(DirectServeHtmlResource):
"""
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._sso_handler = hs.get_sso_handler()
self._sso_login_idp_picker_template = (
hs.config.sso.sso_login_idp_picker_template

View File

@@ -62,7 +62,7 @@ def pick_username_resource(hs: "HomeServer") -> Resource:
class AvailabilityCheckResource(DirectServeJsonResource):
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._sso_handler = hs.get_sso_handler()
async def _async_render_GET(self, request: Request) -> Tuple[int, JsonDict]:
@@ -78,7 +78,7 @@ class AvailabilityCheckResource(DirectServeJsonResource):
class AccountDetailsResource(DirectServeHtmlResource):
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._sso_handler = hs.get_sso_handler()
def template_search_dirs() -> Generator[str, None, None]:

View File

@@ -30,7 +30,7 @@ class MSC4108RendezvousSessionResource(DirectServeJsonResource):
isLeaf = True
def __init__(self, hs: "HomeServer") -> None:
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._handler = hs.get_rendezvous_handler()
async def _async_render_GET(self, request: SynapseRequest) -> None:

View File

@@ -35,7 +35,7 @@ class SAML2ResponseResource(DirectServeHtmlResource):
isLeaf = 1
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._saml_handler = hs.get_saml_handler()
self._sso_handler = hs.get_sso_handler()

View File

@@ -43,7 +43,7 @@ class SsoRegisterResource(DirectServeHtmlResource):
"""
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._sso_handler = hs.get_sso_handler()
async def _async_render_GET(self, request: Request) -> None:

View File

@@ -38,7 +38,7 @@ class UnsubscribeResource(DirectServeHtmlResource):
SUCCESS_HTML = b"<html><body>You have been unsubscribed</body><html>"
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self.notifier = hs.get_notifier()
self.auth = hs.get_auth()
self.pusher_pool = hs.get_pusherpool()

View File

@@ -86,7 +86,7 @@ class ClientWellKnownResource(DirectServeJsonResource):
isLeaf = 1
def __init__(self, hs: "HomeServer"):
super().__init__(hs.get_clock())
super().__init__(clock=hs.get_clock())
self._well_known_builder = WellKnownBuilder(hs)
async def _async_render_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:

View File

@@ -325,7 +325,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
request.write(b"response")
request.finish()
res = WrapHtmlRequestHandlerTests.TestResource(self.clock)
res = WrapHtmlRequestHandlerTests.TestResource(clock=self.clock)
res.callback = callback
channel = make_request(
@@ -345,7 +345,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
async def callback(request: SynapseRequest, **kwargs: object) -> None:
raise RedirectException(b"/look/an/eagle", 301)
res = WrapHtmlRequestHandlerTests.TestResource(self.clock)
res = WrapHtmlRequestHandlerTests.TestResource(clock=self.clock)
res.callback = callback
channel = make_request(
@@ -367,7 +367,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
e.cookies.append(b"session=yespls")
raise e
res = WrapHtmlRequestHandlerTests.TestResource(self.clock)
res = WrapHtmlRequestHandlerTests.TestResource(clock=self.clock)
res.callback = callback
channel = make_request(
@@ -388,7 +388,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
request.write(b"response")
request.finish()
res = WrapHtmlRequestHandlerTests.TestResource(self.clock)
res = WrapHtmlRequestHandlerTests.TestResource(clock=self.clock)
res.callback = callback
channel = make_request(
@@ -401,7 +401,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
class CancellableDirectServeJsonResource(DirectServeJsonResource):
def __init__(self, clock: Clock):
super().__init__(clock)
super().__init__(clock=clock)
self.clock = clock
@cancellable
@@ -418,7 +418,7 @@ class CancellableDirectServeHtmlResource(DirectServeHtmlResource):
ERROR_TEMPLATE = "{code} {msg}"
def __init__(self, clock: Clock):
super().__init__(clock)
super().__init__(clock=clock)
self.clock = clock
@cancellable