Remove SynapseRequest.get_user_agent (#9069)
SynapseRequest is in danger of becoming a bit of a dumping-ground for "useful stuff relating to Requests", which isn't really its intention (its purpose is to override render, finished and connectionLost to set up the LoggingContext and write the right entries to the request log). Putting utility functions inside SynapseRequest means that lots of our code ends up requiring a SynapseRequest when there is nothing synapse-specific about the Request at all, and any old twisted.web.iweb.IRequest will do. This increases code coupling and makes testing more difficult. In short: move get_user_agent out to a utility function.pull/9092/head
parent
b161528fcc
commit
2ec8ca5e60
|
@ -0,0 +1 @@
|
|||
Remove `SynapseRequest.get_user_agent`.
|
|
@ -33,6 +33,7 @@ from synapse.api.errors import (
|
|||
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
|
||||
from synapse.appservice import ApplicationService
|
||||
from synapse.events import EventBase
|
||||
from synapse.http import get_request_user_agent
|
||||
from synapse.http.site import SynapseRequest
|
||||
from synapse.logging import opentracing as opentracing
|
||||
from synapse.storage.databases.main.registration import TokenLookupResult
|
||||
|
@ -187,7 +188,7 @@ class Auth:
|
|||
"""
|
||||
try:
|
||||
ip_addr = self.hs.get_ip_from_request(request)
|
||||
user_agent = request.get_user_agent("")
|
||||
user_agent = get_request_user_agent(request)
|
||||
|
||||
access_token = self.get_access_token_from_request(request)
|
||||
|
||||
|
|
|
@ -49,8 +49,10 @@ from synapse.api.errors import (
|
|||
UserDeactivatedError,
|
||||
)
|
||||
from synapse.api.ratelimiting import Ratelimiter
|
||||
from synapse.handlers._base import BaseHandler
|
||||
from synapse.handlers.ui_auth import INTERACTIVE_AUTH_CHECKERS
|
||||
from synapse.handlers.ui_auth.checkers import UserInteractiveAuthChecker
|
||||
from synapse.http import get_request_user_agent
|
||||
from synapse.http.server import finish_request, respond_with_html
|
||||
from synapse.http.site import SynapseRequest
|
||||
from synapse.logging.context import defer_to_thread
|
||||
|
@ -62,8 +64,6 @@ from synapse.util.async_helpers import maybe_awaitable
|
|||
from synapse.util.msisdn import phone_number_to_msisdn
|
||||
from synapse.util.threepids import canonicalise_email
|
||||
|
||||
from ._base import BaseHandler
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from synapse.app.homeserver import HomeServer
|
||||
|
||||
|
@ -539,7 +539,7 @@ class AuthHandler(BaseHandler):
|
|||
# authentication flow.
|
||||
await self.store.set_ui_auth_clientdict(sid, clientdict)
|
||||
|
||||
user_agent = request.get_user_agent("")
|
||||
user_agent = get_request_user_agent(request)
|
||||
|
||||
await self.store.add_user_agent_ip_to_ui_auth_session(
|
||||
session.session_id, user_agent, clientip
|
||||
|
|
|
@ -23,6 +23,7 @@ from typing_extensions import NoReturn, Protocol
|
|||
from twisted.web.http import Request
|
||||
|
||||
from synapse.api.errors import Codes, RedirectException, SynapseError
|
||||
from synapse.http import get_request_user_agent
|
||||
from synapse.http.server import respond_with_html
|
||||
from synapse.http.site import SynapseRequest
|
||||
from synapse.types import JsonDict, UserID, contains_invalid_mxid_characters
|
||||
|
@ -362,7 +363,7 @@ class SsoHandler:
|
|||
attributes,
|
||||
auth_provider_id,
|
||||
remote_user_id,
|
||||
request.get_user_agent(""),
|
||||
get_request_user_agent(request),
|
||||
request.getClientIP(),
|
||||
)
|
||||
|
||||
|
@ -628,7 +629,7 @@ class SsoHandler:
|
|||
attributes,
|
||||
session.auth_provider_id,
|
||||
session.remote_user_id,
|
||||
request.get_user_agent(""),
|
||||
get_request_user_agent(request),
|
||||
request.getClientIP(),
|
||||
)
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import re
|
|||
|
||||
from twisted.internet import task
|
||||
from twisted.web.client import FileBodyProducer
|
||||
from twisted.web.iweb import IRequest
|
||||
|
||||
from synapse.api.errors import SynapseError
|
||||
|
||||
|
@ -50,3 +51,17 @@ class QuieterFileBodyProducer(FileBodyProducer):
|
|||
FileBodyProducer.stopProducing(self)
|
||||
except task.TaskStopped:
|
||||
pass
|
||||
|
||||
|
||||
def get_request_user_agent(request: IRequest, default: str = "") -> str:
|
||||
"""Return the last User-Agent header, or the given default.
|
||||
"""
|
||||
# There could be raw utf-8 bytes in the User-Agent header.
|
||||
|
||||
# N.B. if you don't do this, the logger explodes cryptically
|
||||
# with maximum recursion trying to log errors about
|
||||
# the charset problem.
|
||||
# c.f. https://github.com/matrix-org/synapse/issues/3471
|
||||
|
||||
h = request.getHeader(b"User-Agent")
|
||||
return h.decode("ascii", "replace") if h else default
|
||||
|
|
|
@ -20,7 +20,7 @@ from twisted.python.failure import Failure
|
|||
from twisted.web.server import Request, Site
|
||||
|
||||
from synapse.config.server import ListenerConfig
|
||||
from synapse.http import redact_uri
|
||||
from synapse.http import get_request_user_agent, redact_uri
|
||||
from synapse.http.request_metrics import RequestMetrics, requests_counter
|
||||
from synapse.logging.context import LoggingContext, PreserveLoggingContext
|
||||
from synapse.types import Requester
|
||||
|
@ -113,15 +113,6 @@ class SynapseRequest(Request):
|
|||
method = self.method.decode("ascii")
|
||||
return method
|
||||
|
||||
def get_user_agent(self, default: str) -> str:
|
||||
"""Return the last User-Agent header, or the given default.
|
||||
"""
|
||||
user_agent = self.requestHeaders.getRawHeaders(b"User-Agent", [None])[-1]
|
||||
if user_agent is None:
|
||||
return default
|
||||
|
||||
return user_agent.decode("ascii", "replace")
|
||||
|
||||
def render(self, resrc):
|
||||
# this is called once a Resource has been found to serve the request; in our
|
||||
# case the Resource in question will normally be a JsonResource.
|
||||
|
@ -292,12 +283,7 @@ class SynapseRequest(Request):
|
|||
# and can see that we're doing something wrong.
|
||||
authenticated_entity = repr(self.requester) # type: ignore[unreachable]
|
||||
|
||||
# ...or could be raw utf-8 bytes in the User-Agent header.
|
||||
# N.B. if you don't do this, the logger explodes cryptically
|
||||
# with maximum recursion trying to log errors about
|
||||
# the charset problem.
|
||||
# c.f. https://github.com/matrix-org/synapse/issues/3471
|
||||
user_agent = self.get_user_agent("-")
|
||||
user_agent = get_request_user_agent(self, "-")
|
||||
|
||||
code = str(self.code)
|
||||
if not self.finished:
|
||||
|
|
|
@ -118,4 +118,4 @@ class CasHandlerTestCase(HomeserverTestCase):
|
|||
|
||||
def _mock_request():
|
||||
"""Returns a mock which will stand in as a SynapseRequest"""
|
||||
return Mock(spec=["getClientIP", "get_user_agent"])
|
||||
return Mock(spec=["getClientIP", "getHeader"])
|
||||
|
|
|
@ -1011,7 +1011,7 @@ def _build_callback_request(
|
|||
"addCookie",
|
||||
"requestHeaders",
|
||||
"getClientIP",
|
||||
"get_user_agent",
|
||||
"getHeader",
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -1020,5 +1020,4 @@ def _build_callback_request(
|
|||
request.args[b"code"] = [code.encode("utf-8")]
|
||||
request.args[b"state"] = [state.encode("utf-8")]
|
||||
request.getClientIP.return_value = ip_address
|
||||
request.get_user_agent.return_value = user_agent
|
||||
return request
|
||||
|
|
|
@ -262,4 +262,4 @@ class SamlHandlerTestCase(HomeserverTestCase):
|
|||
|
||||
def _mock_request():
|
||||
"""Returns a mock which will stand in as a SynapseRequest"""
|
||||
return Mock(spec=["getClientIP", "get_user_agent"])
|
||||
return Mock(spec=["getClientIP", "getHeader"])
|
||||
|
|
Loading…
Reference in New Issue