1 files changed, 40 insertions, 0 deletions
diff --git a/synapse/rest/admin/users.py b/synapse/rest/admin/users.py
index 73878dd99d..9900498fbe 100644
--- a/synapse/rest/admin/users.py
+++ b/synapse/rest/admin/users.py
@@ -1270,6 +1270,46 @@ class AccountDataRestServlet(RestServlet):
}
+class UserReplaceMasterCrossSigningKeyRestServlet(RestServlet):
+ """Allow a given user to replace their master cross-signing key without UIA.
+
+ This replacement is permitted for a limited period (currently 10 minutes).
+
+ While this is exposed via the admin API, this is intended for use by the
+ Matrix Authentication Service rather than server admins.
+ """
+
+ PATTERNS = admin_patterns(
+ "/users/(?P<user_id>[^/]*)/_allow_cross_signing_replacement_without_uia"
+ )
+ REPLACEMENT_PERIOD_MS = 10 * 60 * 1000 # 10 minutes
+
+ def __init__(self, hs: "HomeServer"):
+ self._auth = hs.get_auth()
+ self._store = hs.get_datastores().main
+
+ async def on_POST(
+ self,
+ request: SynapseRequest,
+ user_id: str,
+ ) -> Tuple[int, JsonDict]:
+ await assert_requester_is_admin(self._auth, request)
+
+ if user_id is None:
+ raise NotFoundError("User not found")
+
+ timestamp = (
+ await self._store.allow_master_cross_signing_key_replacement_without_uia(
+ user_id, self.REPLACEMENT_PERIOD_MS
+ )
+ )
+
+ if timestamp is None:
+ raise NotFoundError("User has no master cross-signing key")
+
+ return HTTPStatus.OK, {"updatable_without_uia_before_ms": timestamp}
+
+
class UserByExternalId(RestServlet):
"""Find a user based on an external ID from an auth provider"""
|