diff --git a/synapse/util/caches/deferred_cache.py b/synapse/util/caches/deferred_cache.py
index 377c9a282a..1d6ec22191 100644
--- a/synapse/util/caches/deferred_cache.py
+++ b/synapse/util/caches/deferred_cache.py
@@ -81,13 +81,14 @@ class DeferredCache(Generic[KT, VT]):
Args:
name: The name of the cache
max_entries: Maximum amount of entries that the cache will hold
- keylen: The length of the tuple used as the cache key. Ignored unless
- `tree` is True.
tree: Use a TreeCache instead of a dict as the underlying cache type
iterable: If True, count each item in the cached object as an entry,
rather than each cached object
apply_cache_factor_from_config: Whether cache factors specified in the
config file affect `max_entries`
+ prune_unread_entries: If True, cache entries that haven't been read recently
+ will be evicted from the cache in the background. Set to False to
+ opt-out of this behaviour.
"""
cache_type = TreeCache if tree else dict
diff --git a/synapse/util/caches/descriptors.py b/synapse/util/caches/descriptors.py
index 375cd443f1..df4fb156c2 100644
--- a/synapse/util/caches/descriptors.py
+++ b/synapse/util/caches/descriptors.py
@@ -254,9 +254,17 @@ class DeferredCacheDescriptor(_CacheDescriptorBase):
return r1 + r2
Args:
+ orig:
+ max_entries:
num_args: number of positional arguments (excluding ``self`` and
``cache_context``) to use as cache keys. Defaults to all named
args of the function.
+ tree:
+ cache_context:
+ iterable:
+ prune_unread_entries: If True, cache entries that haven't been read recently
+ will be evicted from the cache in the background. Set to False to opt-out
+ of this behaviour.
"""
def __init__(
diff --git a/synapse/util/caches/lrucache.py b/synapse/util/caches/lrucache.py
index 3f11a2f9dd..7548b38548 100644
--- a/synapse/util/caches/lrucache.py
+++ b/synapse/util/caches/lrucache.py
@@ -340,6 +340,12 @@ class LruCache(Generic[KT, VT]):
apply_cache_factor_from_config (bool): If true, `max_size` will be
multiplied by a cache factor derived from the homeserver config
+
+ clock:
+
+ prune_unread_entries: If True, cache entries that haven't been read recently
+ will be evicted from the cache in the background. Set to False to
+ opt-out of this behaviour.
"""
# Default `clock` to something sensible. Note that we rename it to
# `real_clock` so that mypy doesn't think its still `Optional`.
diff --git a/synapse/util/stringutils.py b/synapse/util/stringutils.py
index ea1032b4fc..b26546aecd 100644
--- a/synapse/util/stringutils.py
+++ b/synapse/util/stringutils.py
@@ -16,8 +16,7 @@ import itertools
import re
import secrets
import string
-from collections.abc import Iterable
-from typing import Optional, Tuple
+from typing import Iterable, Optional, Tuple
from netaddr import valid_ipv6
@@ -197,7 +196,7 @@ def shortstr(iterable: Iterable, maxitems: int = 5) -> str:
"""If iterable has maxitems or fewer, return the stringification of a list
containing those items.
- Otherwise, return the stringification of a a list with the first maxitems items,
+ Otherwise, return the stringification of a list with the first maxitems items,
followed by "...".
Args:
diff --git a/synapse/util/threepids.py b/synapse/util/threepids.py
index 389adf00f6..1e9c2faa64 100644
--- a/synapse/util/threepids.py
+++ b/synapse/util/threepids.py
@@ -32,7 +32,12 @@ logger = logging.getLogger(__name__)
MAX_EMAIL_ADDRESS_LENGTH = 500
-def check_3pid_allowed(hs: "HomeServer", medium: str, address: str) -> bool:
+async def check_3pid_allowed(
+ hs: "HomeServer",
+ medium: str,
+ address: str,
+ registration: bool = False,
+) -> bool:
"""Checks whether a given format of 3PID is allowed to be used on this HS
Args:
@@ -40,9 +45,15 @@ def check_3pid_allowed(hs: "HomeServer", medium: str, address: str) -> bool:
medium: 3pid medium - e.g. email, msisdn
address: address within that medium (e.g. "wotan@matrix.org")
msisdns need to first have been canonicalised
+ registration: whether we want to bind the 3PID as part of registering a new user.
+
Returns:
bool: whether the 3PID medium/address is allowed to be added to this HS
"""
+ if not await hs.get_password_auth_provider().is_3pid_allowed(
+ medium, address, registration
+ ):
+ return False
if hs.config.registration.allowed_local_3pids:
for constraint in hs.config.registration.allowed_local_3pids:
diff --git a/synapse/util/versionstring.py b/synapse/util/versionstring.py
deleted file mode 100644
index c144ff62c1..0000000000
--- a/synapse/util/versionstring.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright 2016 OpenMarket Ltd
-# Copyright 2021 The Matrix.org Foundation C.I.C.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import logging
-import os
-import subprocess
-from types import ModuleType
-from typing import Dict
-
-logger = logging.getLogger(__name__)
-
-version_cache: Dict[ModuleType, str] = {}
-
-
-def get_version_string(module: ModuleType) -> str:
- """Given a module calculate a git-aware version string for it.
-
- If called on a module not in a git checkout will return `__version__`.
-
- Args:
- module: The module to check the version of. Must declare a __version__
- attribute.
-
- Returns:
- The module version (as a string).
- """
-
- cached_version = version_cache.get(module)
- if cached_version is not None:
- return cached_version
-
- # We want this to fail loudly with an AttributeError. Type-ignore this so
- # mypy only considers the happy path.
- version_string = module.__version__ # type: ignore[attr-defined]
-
- try:
- cwd = os.path.dirname(os.path.abspath(module.__file__))
-
- def _run_git_command(prefix: str, *params: str) -> str:
- try:
- result = (
- subprocess.check_output(
- ["git", *params], stderr=subprocess.DEVNULL, cwd=cwd
- )
- .strip()
- .decode("ascii")
- )
- return prefix + result
- except (subprocess.CalledProcessError, FileNotFoundError):
- return ""
-
- git_branch = _run_git_command("b=", "rev-parse", "--abbrev-ref", "HEAD")
- git_tag = _run_git_command("t=", "describe", "--exact-match")
- git_commit = _run_git_command("", "rev-parse", "--short", "HEAD")
-
- dirty_string = "-this_is_a_dirty_checkout"
- is_dirty = _run_git_command("", "describe", "--dirty=" + dirty_string).endswith(
- dirty_string
- )
- git_dirty = "dirty" if is_dirty else ""
-
- if git_branch or git_tag or git_commit or git_dirty:
- git_version = ",".join(
- s for s in (git_branch, git_tag, git_commit, git_dirty) if s
- )
-
- version_string = f"{version_string} ({git_version})"
- except Exception as e:
- logger.info("Failed to check for git repository: %s", e)
-
- version_cache[module] = version_string
-
- return version_string
|