Merge branch 'develop' into madlittlemods/14108-optimize-filter_events_for_client
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -343,9 +343,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.87"
|
||||
version = "1.0.88"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
|
||||
checksum = "8e8b3801309262e8184d9687fb697586833e939767aea0dda89f5a8e650e8bd7"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
||||
1
changelog.d/14404.misc
Normal file
1
changelog.d/14404.misc
Normal file
@@ -0,0 +1 @@
|
||||
Faster joins: filter out non local events when a room doesn't have its full state.
|
||||
1
changelog.d/14479.misc
Normal file
1
changelog.d/14479.misc
Normal file
@@ -0,0 +1 @@
|
||||
`scripts-dev/federation_client`: Fix routing on servers with `.well-known` files.
|
||||
1
changelog.d/14499.doc
Normal file
1
changelog.d/14499.doc
Normal file
@@ -0,0 +1 @@
|
||||
Fixed link to 'Synapse administration endpoints'.
|
||||
1
changelog.d/14500.misc
Normal file
1
changelog.d/14500.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump pygithub from 1.56 to 1.57.
|
||||
1
changelog.d/14501.misc
Normal file
1
changelog.d/14501.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump sentry-sdk from 1.10.1 to 1.11.0.
|
||||
1
changelog.d/14502.misc
Normal file
1
changelog.d/14502.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump types-pillow from 9.2.2.1 to 9.3.0.1.
|
||||
1
changelog.d/14503.misc
Normal file
1
changelog.d/14503.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump towncrier from 21.9.0 to 22.8.0.
|
||||
1
changelog.d/14504.misc
Normal file
1
changelog.d/14504.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump phonenumbers from 8.12.56 to 8.13.0.
|
||||
1
changelog.d/14505.misc
Normal file
1
changelog.d/14505.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump serde_json from 1.0.87 to 1.0.88.
|
||||
@@ -19,7 +19,7 @@ already on your `$PATH` depending on how Synapse was installed.
|
||||
Finding your user's `access_token` is client-dependent, but will usually be shown in the client's settings.
|
||||
|
||||
## Making an Admin API request
|
||||
For security reasons, we [recommend](reverse_proxy.md#synapse-administration-endpoints)
|
||||
For security reasons, we [recommend](../../../reverse_proxy.md#synapse-administration-endpoints)
|
||||
that the Admin API (`/_synapse/admin/...`) should be hidden from public view using a
|
||||
reverse proxy. This means you should typically query the Admin API from a terminal on
|
||||
the machine which runs Synapse.
|
||||
|
||||
39
poetry.lock
generated
39
poetry.lock
generated
@@ -663,7 +663,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
||||
|
||||
[[package]]
|
||||
name = "phonenumbers"
|
||||
version = "8.12.56"
|
||||
version = "8.13.0"
|
||||
description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers."
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -814,15 +814,15 @@ python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "pygithub"
|
||||
version = "1.56"
|
||||
version = "1.57"
|
||||
description = "Use the full Github API v3"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
deprecated = "*"
|
||||
pyjwt = ">=2.0"
|
||||
pyjwt = ">=2.4.0"
|
||||
pynacl = ">=1.4.0"
|
||||
requests = ">=2.14.0"
|
||||
|
||||
@@ -1076,7 +1076,7 @@ doc = ["Sphinx", "sphinx-rtd-theme"]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-sdk"
|
||||
version = "1.10.1"
|
||||
version = "1.11.0"
|
||||
description = "Python client for Sentry (https://sentry.io)"
|
||||
category = "main"
|
||||
optional = true
|
||||
@@ -1098,6 +1098,7 @@ fastapi = ["fastapi (>=0.79.0)"]
|
||||
flask = ["blinker (>=1.1)", "flask (>=0.11)"]
|
||||
httpx = ["httpx (>=0.16.0)"]
|
||||
pure-eval = ["asttokens", "executing", "pure-eval"]
|
||||
pymongo = ["pymongo (>=3.1)"]
|
||||
pyspark = ["pyspark (>=2.4.4)"]
|
||||
quart = ["blinker (>=1.1)", "quart (>=0.16.1)"]
|
||||
rq = ["rq (>=0.6)"]
|
||||
@@ -1256,11 +1257,11 @@ python-versions = ">= 3.5"
|
||||
|
||||
[[package]]
|
||||
name = "towncrier"
|
||||
version = "21.9.0"
|
||||
version = "22.8.0"
|
||||
description = "Building newsfiles for your project."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
click = "*"
|
||||
@@ -1268,7 +1269,7 @@ click-default-group = "*"
|
||||
incremental = "*"
|
||||
jinja2 = "*"
|
||||
setuptools = "*"
|
||||
tomli = {version = "*", markers = "python_version >= \"3.6\""}
|
||||
tomli = "*"
|
||||
|
||||
[package.extras]
|
||||
dev = ["packaging"]
|
||||
@@ -1439,7 +1440,7 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "types-pillow"
|
||||
version = "9.2.2.1"
|
||||
version = "9.3.0.1"
|
||||
description = "Typing stubs for Pillow"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -2257,8 +2258,8 @@ pathspec = [
|
||||
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
|
||||
]
|
||||
phonenumbers = [
|
||||
{file = "phonenumbers-8.12.56-py2.py3-none-any.whl", hash = "sha256:80a7422cf0999a6f9b7a2e6cfbdbbfcc56ab5b75414dc3b805bbec91276b64a3"},
|
||||
{file = "phonenumbers-8.12.56.tar.gz", hash = "sha256:82a4f226c930d02dcdf6d4b29e4cfd8678991fe65c2efd5fdd143557186f0868"},
|
||||
{file = "phonenumbers-8.13.0-py2.py3-none-any.whl", hash = "sha256:dbaea9e4005a976bcf18fbe2bb87cb9cd0a3f119136f04188ac412d7741cebf0"},
|
||||
{file = "phonenumbers-8.13.0.tar.gz", hash = "sha256:93745d7afd38e246660bb601b07deac54eeb76c8e5e43f5e83333b0383a0a1e4"},
|
||||
]
|
||||
pillow = [
|
||||
{file = "Pillow-9.3.0-1-cp37-cp37m-win32.whl", hash = "sha256:e6ea6b856a74d560d9326c0f5895ef8050126acfdc7ca08ad703eb0081e82b74"},
|
||||
@@ -2419,8 +2420,8 @@ pyflakes = [
|
||||
{file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"},
|
||||
]
|
||||
pygithub = [
|
||||
{file = "PyGithub-1.56-py3-none-any.whl", hash = "sha256:d15f13d82165306da8a68aefc0f848a6f6432d5febbff13b60a94758ce3ef8b5"},
|
||||
{file = "PyGithub-1.56.tar.gz", hash = "sha256:80c6d85cf0f9418ffeb840fd105840af694c4f17e102970badbaf678251f2a01"},
|
||||
{file = "PyGithub-1.57-py3-none-any.whl", hash = "sha256:5822febeac2391f1306c55a99af2bc8f86c8bf82ded000030cd02c18f31b731f"},
|
||||
{file = "PyGithub-1.57.tar.gz", hash = "sha256:c273f252b278fb81f1769505cc6921bdb6791e1cebd6ac850cc97dad13c31ff3"},
|
||||
]
|
||||
pygments = [
|
||||
{file = "Pygments-2.11.2-py3-none-any.whl", hash = "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65"},
|
||||
@@ -2568,8 +2569,8 @@ semantic-version = [
|
||||
{file = "semantic_version-2.10.0.tar.gz", hash = "sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c"},
|
||||
]
|
||||
sentry-sdk = [
|
||||
{file = "sentry-sdk-1.10.1.tar.gz", hash = "sha256:105faf7bd7b7fa25653404619ee261527266b14103fe1389e0ce077bd23a9691"},
|
||||
{file = "sentry_sdk-1.10.1-py2.py3-none-any.whl", hash = "sha256:06c0fa9ccfdc80d7e3b5d2021978d6eb9351fa49db9b5847cf4d1f2a473414ad"},
|
||||
{file = "sentry-sdk-1.11.0.tar.gz", hash = "sha256:e7b78a1ddf97a5f715a50ab8c3f7a93f78b114c67307785ee828ef67a5d6f117"},
|
||||
{file = "sentry_sdk-1.11.0-py2.py3-none-any.whl", hash = "sha256:f467e6c7fac23d4d42bc83eb049c400f756cd2d65ab44f0cc1165d0c7c3d40bc"},
|
||||
]
|
||||
service-identity = [
|
||||
{file = "service-identity-21.1.0.tar.gz", hash = "sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34"},
|
||||
@@ -2720,8 +2721,8 @@ tornado = [
|
||||
{file = "tornado-6.1.tar.gz", hash = "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791"},
|
||||
]
|
||||
towncrier = [
|
||||
{file = "towncrier-21.9.0-py2.py3-none-any.whl", hash = "sha256:fc5a88a2a54988e3a8ed2b60d553599da8330f65722cc607c839614ed87e0f92"},
|
||||
{file = "towncrier-21.9.0.tar.gz", hash = "sha256:9cb6f45c16e1a1eec9d0e7651165e7be60cd0ab81d13a5c96ca97a498ae87f48"},
|
||||
{file = "towncrier-22.8.0-py2.py3-none-any.whl", hash = "sha256:3b780c3d966e1b26414830aec3d15000654b31e64e024f3e5fd128b4c6eb8f47"},
|
||||
{file = "towncrier-22.8.0.tar.gz", hash = "sha256:7d3839b033859b45fb55df82b74cfd702431933c0cc9f287a5a7ea3e05d042cb"},
|
||||
]
|
||||
treq = [
|
||||
{file = "treq-22.2.0-py3-none-any.whl", hash = "sha256:27d95b07c5c14be3e7b280416139b036087617ad5595be913b1f9b3ce981b9b2"},
|
||||
@@ -2808,8 +2809,8 @@ types-opentracing = [
|
||||
{file = "types_opentracing-2.4.10-py3-none-any.whl", hash = "sha256:66d9cfbbdc4a6f8ca8189a15ad26f0fe41cee84c07057759c5d194e2505b84c2"},
|
||||
]
|
||||
types-pillow = [
|
||||
{file = "types-Pillow-9.2.2.1.tar.gz", hash = "sha256:85c139e06e1c46ec5f9c634d5c54a156b0958d5d0e8be024ed353db0c804b426"},
|
||||
{file = "types_Pillow-9.2.2.1-py3-none-any.whl", hash = "sha256:3a6a871cade8428433a21ef459bb0a65532b87d05f9e836a0664431ce445bdcf"},
|
||||
{file = "types-Pillow-9.3.0.1.tar.gz", hash = "sha256:f3b7cada3fa496c78d75253c6b1f07a843d625f42e5639b320a72acaff6f7cfb"},
|
||||
{file = "types_Pillow-9.3.0.1-py3-none-any.whl", hash = "sha256:79837755fe9659f29efd1016e9903ac4a500e0c73260483f07296bd6ca47668b"},
|
||||
]
|
||||
types-psycopg2 = [
|
||||
{file = "types-psycopg2-2.9.21.1.tar.gz", hash = "sha256:f5532cf15afdc6b5ebb1e59b7d896617217321f488fd1fbd74e7efb94decfab6"},
|
||||
|
||||
@@ -46,11 +46,12 @@ import signedjson.key
|
||||
import signedjson.types
|
||||
import srvlookup
|
||||
import yaml
|
||||
from requests import PreparedRequest, Response
|
||||
from requests.adapters import HTTPAdapter
|
||||
from urllib3 import HTTPConnectionPool
|
||||
|
||||
# uncomment the following to enable debug logging of http requests
|
||||
# from httplib import HTTPConnection
|
||||
# from http.client import HTTPConnection
|
||||
# HTTPConnection.debuglevel = 1
|
||||
|
||||
|
||||
@@ -103,6 +104,7 @@ def request(
|
||||
destination: str,
|
||||
path: str,
|
||||
content: Optional[str],
|
||||
verify_tls: bool,
|
||||
) -> requests.Response:
|
||||
if method is None:
|
||||
if content is None:
|
||||
@@ -141,7 +143,6 @@ def request(
|
||||
s.mount("matrix://", MatrixConnectionAdapter())
|
||||
|
||||
headers: Dict[str, str] = {
|
||||
"Host": destination,
|
||||
"Authorization": authorization_headers[0],
|
||||
}
|
||||
|
||||
@@ -152,7 +153,7 @@ def request(
|
||||
method=method,
|
||||
url=dest,
|
||||
headers=headers,
|
||||
verify=False,
|
||||
verify=verify_tls,
|
||||
data=content,
|
||||
stream=True,
|
||||
)
|
||||
@@ -202,6 +203,12 @@ def main() -> None:
|
||||
|
||||
parser.add_argument("--body", help="Data to send as the body of the HTTP request")
|
||||
|
||||
parser.add_argument(
|
||||
"--insecure",
|
||||
action="store_true",
|
||||
help="Disable TLS certificate verification",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"path", help="request path, including the '/_matrix/federation/...' prefix."
|
||||
)
|
||||
@@ -227,6 +234,7 @@ def main() -> None:
|
||||
args.destination,
|
||||
args.path,
|
||||
content=args.body,
|
||||
verify_tls=not args.insecure,
|
||||
)
|
||||
|
||||
sys.stderr.write("Status Code: %d\n" % (result.status_code,))
|
||||
@@ -254,36 +262,93 @@ def read_args_from_config(args: argparse.Namespace) -> None:
|
||||
|
||||
|
||||
class MatrixConnectionAdapter(HTTPAdapter):
|
||||
@staticmethod
|
||||
def lookup(s: str, skip_well_known: bool = False) -> Tuple[str, int]:
|
||||
if s[-1] == "]":
|
||||
# ipv6 literal (with no port)
|
||||
return s, 8448
|
||||
def send(
|
||||
self,
|
||||
request: PreparedRequest,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
) -> Response:
|
||||
# overrides the send() method in the base class.
|
||||
|
||||
if ":" in s:
|
||||
out = s.rsplit(":", 1)
|
||||
# We need to look for .well-known redirects before passing the request up to
|
||||
# HTTPAdapter.send().
|
||||
assert isinstance(request.url, str)
|
||||
parsed = urlparse.urlsplit(request.url)
|
||||
server_name = parsed.netloc
|
||||
well_known = self._get_well_known(parsed.netloc)
|
||||
|
||||
if well_known:
|
||||
server_name = well_known
|
||||
|
||||
# replace the scheme in the uri with https, so that cert verification is done
|
||||
# also replace the hostname if we got a .well-known result
|
||||
request.url = urlparse.urlunsplit(
|
||||
("https", server_name, parsed.path, parsed.query, parsed.fragment)
|
||||
)
|
||||
|
||||
# at this point we also add the host header (otherwise urllib will add one
|
||||
# based on the `host` from the connection returned by `get_connection`,
|
||||
# which will be wrong if there is an SRV record).
|
||||
request.headers["Host"] = server_name
|
||||
|
||||
return super().send(request, *args, **kwargs)
|
||||
|
||||
def get_connection(
|
||||
self, url: str, proxies: Optional[Dict[str, str]] = None
|
||||
) -> HTTPConnectionPool:
|
||||
# overrides the get_connection() method in the base class
|
||||
parsed = urlparse.urlsplit(url)
|
||||
(host, port, ssl_server_name) = self._lookup(parsed.netloc)
|
||||
print(
|
||||
f"Connecting to {host}:{port} with SNI {ssl_server_name}", file=sys.stderr
|
||||
)
|
||||
return self.poolmanager.connection_from_host(
|
||||
host,
|
||||
port=port,
|
||||
scheme="https",
|
||||
pool_kwargs={"server_hostname": ssl_server_name},
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _lookup(server_name: str) -> Tuple[str, int, str]:
|
||||
"""
|
||||
Do an SRV lookup on a server name and return the host:port to connect to
|
||||
Given the server_name (after any .well-known lookup), return the host, port and
|
||||
the ssl server name
|
||||
"""
|
||||
if server_name[-1] == "]":
|
||||
# ipv6 literal (with no port)
|
||||
return server_name, 8448, server_name
|
||||
|
||||
if ":" in server_name:
|
||||
# explicit port
|
||||
out = server_name.rsplit(":", 1)
|
||||
try:
|
||||
port = int(out[1])
|
||||
except ValueError:
|
||||
raise ValueError("Invalid host:port '%s'" % s)
|
||||
return out[0], port
|
||||
|
||||
# try a .well-known lookup
|
||||
if not skip_well_known:
|
||||
well_known = MatrixConnectionAdapter.get_well_known(s)
|
||||
if well_known:
|
||||
return MatrixConnectionAdapter.lookup(well_known, skip_well_known=True)
|
||||
raise ValueError("Invalid host:port '%s'" % (server_name,))
|
||||
return out[0], port, out[0]
|
||||
|
||||
try:
|
||||
srv = srvlookup.lookup("matrix", "tcp", s)[0]
|
||||
return srv.host, srv.port
|
||||
srv = srvlookup.lookup("matrix", "tcp", server_name)[0]
|
||||
print(
|
||||
f"SRV lookup on _matrix._tcp.{server_name} gave {srv}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return srv.host, srv.port, server_name
|
||||
except Exception:
|
||||
return s, 8448
|
||||
return server_name, 8448, server_name
|
||||
|
||||
@staticmethod
|
||||
def get_well_known(server_name: str) -> Optional[str]:
|
||||
uri = "https://%s/.well-known/matrix/server" % (server_name,)
|
||||
print("fetching %s" % (uri,), file=sys.stderr)
|
||||
def _get_well_known(server_name: str) -> Optional[str]:
|
||||
if ":" in server_name:
|
||||
# explicit port, or ipv6 literal. Either way, no .well-known
|
||||
return None
|
||||
|
||||
# TODO: check for ipv4 literals
|
||||
|
||||
uri = f"https://{server_name}/.well-known/matrix/server"
|
||||
print(f"fetching {uri}", file=sys.stderr)
|
||||
|
||||
try:
|
||||
resp = requests.get(uri)
|
||||
@@ -304,19 +369,6 @@ class MatrixConnectionAdapter(HTTPAdapter):
|
||||
print("Invalid response from %s: %s" % (uri, e), file=sys.stderr)
|
||||
return None
|
||||
|
||||
def get_connection(
|
||||
self, url: str, proxies: Optional[Dict[str, str]] = None
|
||||
) -> HTTPConnectionPool:
|
||||
parsed = urlparse.urlparse(url)
|
||||
|
||||
(host, port) = self.lookup(parsed.netloc)
|
||||
netloc = "%s:%d" % (host, port)
|
||||
print("Connecting to %s" % (netloc,), file=sys.stderr)
|
||||
url = urlparse.urlunparse(
|
||||
("https", netloc, parsed.path, parsed.params, parsed.query, parsed.fragment)
|
||||
)
|
||||
return super().get_connection(url, proxies)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -505,6 +505,7 @@ class PerDestinationQueue:
|
||||
new_pdus = await filter_events_for_server(
|
||||
self._storage_controllers,
|
||||
self._destination,
|
||||
self._server_name,
|
||||
new_pdus,
|
||||
redact=False,
|
||||
)
|
||||
|
||||
@@ -379,6 +379,7 @@ class FederationHandler:
|
||||
filtered_extremities = await filter_events_for_server(
|
||||
self._storage_controllers,
|
||||
self.server_name,
|
||||
self.server_name,
|
||||
events_to_check,
|
||||
redact=False,
|
||||
check_history_visibility_only=True,
|
||||
@@ -1231,7 +1232,9 @@ class FederationHandler:
|
||||
async def on_backfill_request(
|
||||
self, origin: str, room_id: str, pdu_list: List[str], limit: int
|
||||
) -> List[EventBase]:
|
||||
await self._event_auth_handler.assert_host_in_room(room_id, origin)
|
||||
# We allow partially joined rooms since in this case we are filtering out
|
||||
# non-local events in `filter_events_for_server`.
|
||||
await self._event_auth_handler.assert_host_in_room(room_id, origin, True)
|
||||
|
||||
# Synapse asks for 100 events per backfill request. Do not allow more.
|
||||
limit = min(limit, 100)
|
||||
@@ -1252,7 +1255,7 @@ class FederationHandler:
|
||||
)
|
||||
|
||||
events = await filter_events_for_server(
|
||||
self._storage_controllers, origin, events
|
||||
self._storage_controllers, origin, self.server_name, events
|
||||
)
|
||||
|
||||
return events
|
||||
@@ -1283,7 +1286,7 @@ class FederationHandler:
|
||||
await self._event_auth_handler.assert_host_in_room(event.room_id, origin)
|
||||
|
||||
events = await filter_events_for_server(
|
||||
self._storage_controllers, origin, [event]
|
||||
self._storage_controllers, origin, self.server_name, [event]
|
||||
)
|
||||
event = events[0]
|
||||
return event
|
||||
@@ -1296,7 +1299,9 @@ class FederationHandler:
|
||||
latest_events: List[str],
|
||||
limit: int,
|
||||
) -> List[EventBase]:
|
||||
await self._event_auth_handler.assert_host_in_room(room_id, origin)
|
||||
# We allow partially joined rooms since in this case we are filtering out
|
||||
# non-local events in `filter_events_for_server`.
|
||||
await self._event_auth_handler.assert_host_in_room(room_id, origin, True)
|
||||
|
||||
# Only allow up to 20 events to be retrieved per request.
|
||||
limit = min(limit, 20)
|
||||
@@ -1309,7 +1314,7 @@ class FederationHandler:
|
||||
)
|
||||
|
||||
missing_events = await filter_events_for_server(
|
||||
self._storage_controllers, origin, missing_events
|
||||
self._storage_controllers, origin, self.server_name, missing_events
|
||||
)
|
||||
|
||||
return missing_events
|
||||
|
||||
@@ -580,7 +580,8 @@ def get_effective_room_visibility_from_state(state: StateMap[EventBase]) -> str:
|
||||
|
||||
async def filter_events_for_server(
|
||||
storage: StorageControllers,
|
||||
server_name: str,
|
||||
target_server_name: str,
|
||||
local_server_name: str,
|
||||
events: List[EventBase],
|
||||
redact: bool = True,
|
||||
check_history_visibility_only: bool = False,
|
||||
@@ -620,7 +621,7 @@ async def filter_events_for_server(
|
||||
# if the server is either in the room or has been invited
|
||||
# into the room.
|
||||
for ev in memberships.values():
|
||||
assert get_domain_from_id(ev.state_key) == server_name
|
||||
assert get_domain_from_id(ev.state_key) == target_server_name
|
||||
|
||||
memtype = ev.membership
|
||||
if memtype == Membership.JOIN:
|
||||
@@ -639,6 +640,24 @@ async def filter_events_for_server(
|
||||
# to no users having been erased.
|
||||
erased_senders = {}
|
||||
|
||||
# Filter out non-local events when we are in the middle of a partial join, since our servers
|
||||
# list can be out of date and we could leak events to servers not in the room anymore.
|
||||
# This can also be true for local events but we consider it to be an acceptable risk.
|
||||
|
||||
# We do this check as a first step and before retrieving membership events because
|
||||
# otherwise a room could be fully joined after we retrieve those, which would then bypass
|
||||
# this check but would base the filtering on an outdated view of the membership events.
|
||||
|
||||
partial_state_invisible_events = set()
|
||||
if not check_history_visibility_only:
|
||||
for e in events:
|
||||
sender_domain = get_domain_from_id(e.sender)
|
||||
if (
|
||||
sender_domain != local_server_name
|
||||
and await storage.main.is_partial_state_room(e.room_id)
|
||||
):
|
||||
partial_state_invisible_events.add(e)
|
||||
|
||||
# Let's check to see if all the events have a history visibility
|
||||
# of "shared" or "world_readable". If that's the case then we don't
|
||||
# need to check membership (as we know the server is in the room).
|
||||
@@ -653,7 +672,7 @@ async def filter_events_for_server(
|
||||
if event_to_history_vis[e.event_id]
|
||||
not in (HistoryVisibility.SHARED, HistoryVisibility.WORLD_READABLE)
|
||||
],
|
||||
server_name,
|
||||
target_server_name,
|
||||
)
|
||||
|
||||
to_return = []
|
||||
@@ -662,6 +681,10 @@ async def filter_events_for_server(
|
||||
visible = check_event_is_visible(
|
||||
event_to_history_vis[e.event_id], event_to_memberships.get(e.event_id, {})
|
||||
)
|
||||
|
||||
if e in partial_state_invisible_events:
|
||||
visible = False
|
||||
|
||||
if visible and not erased:
|
||||
to_return.append(e)
|
||||
elif redact:
|
||||
|
||||
@@ -61,7 +61,7 @@ class FilterEventsForServerTestCase(unittest.HomeserverTestCase):
|
||||
|
||||
filtered = self.get_success(
|
||||
filter_events_for_server(
|
||||
self._storage_controllers, "test_server", events_to_filter
|
||||
self._storage_controllers, "test_server", "hs", events_to_filter
|
||||
)
|
||||
)
|
||||
|
||||
@@ -83,7 +83,7 @@ class FilterEventsForServerTestCase(unittest.HomeserverTestCase):
|
||||
self.assertEqual(
|
||||
self.get_success(
|
||||
filter_events_for_server(
|
||||
self._storage_controllers, "remote_hs", [outlier]
|
||||
self._storage_controllers, "remote_hs", "hs", [outlier]
|
||||
)
|
||||
),
|
||||
[outlier],
|
||||
@@ -94,7 +94,7 @@ class FilterEventsForServerTestCase(unittest.HomeserverTestCase):
|
||||
|
||||
filtered = self.get_success(
|
||||
filter_events_for_server(
|
||||
self._storage_controllers, "remote_hs", [outlier, evt]
|
||||
self._storage_controllers, "remote_hs", "local_hs", [outlier, evt]
|
||||
)
|
||||
)
|
||||
self.assertEqual(len(filtered), 2, f"expected 2 results, got: {filtered}")
|
||||
@@ -106,7 +106,7 @@ class FilterEventsForServerTestCase(unittest.HomeserverTestCase):
|
||||
# be redacted)
|
||||
filtered = self.get_success(
|
||||
filter_events_for_server(
|
||||
self._storage_controllers, "other_server", [outlier, evt]
|
||||
self._storage_controllers, "other_server", "local_hs", [outlier, evt]
|
||||
)
|
||||
)
|
||||
self.assertEqual(filtered[0], outlier)
|
||||
@@ -141,7 +141,7 @@ class FilterEventsForServerTestCase(unittest.HomeserverTestCase):
|
||||
# ... and the filtering happens.
|
||||
filtered = self.get_success(
|
||||
filter_events_for_server(
|
||||
self._storage_controllers, "test_server", events_to_filter
|
||||
self._storage_controllers, "test_server", "local_hs", events_to_filter
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user