Allow admins to require a manual approval process before new accounts can be used (using MSC3866) (#13556)

This commit is contained in:
Brendan Abolivier 2022-09-29 14:23:24 +01:00 committed by GitHub
parent 8625ad8099
commit be76cd8200
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 731 additions and 34 deletions

View file

@ -28,7 +28,14 @@ from typing import (
from typing_extensions import TypedDict
from synapse.api.errors import Codes, InvalidClientTokenError, LoginError, SynapseError
from synapse.api.constants import ApprovalNoticeMedium
from synapse.api.errors import (
Codes,
InvalidClientTokenError,
LoginError,
NotApprovedError,
SynapseError,
)
from synapse.api.ratelimiting import Ratelimiter
from synapse.api.urls import CLIENT_API_PREFIX
from synapse.appservice import ApplicationService
@ -55,11 +62,11 @@ logger = logging.getLogger(__name__)
class LoginResponse(TypedDict, total=False):
user_id: str
access_token: str
access_token: Optional[str]
home_server: str
expires_in_ms: Optional[int]
refresh_token: Optional[str]
device_id: str
device_id: Optional[str]
well_known: Optional[Dict[str, Any]]
@ -92,6 +99,12 @@ class LoginRestServlet(RestServlet):
hs.config.registration.refreshable_access_token_lifetime is not None
)
# Whether we need to check if the user has been approved or not.
self._require_approval = (
hs.config.experimental.msc3866.enabled
and hs.config.experimental.msc3866.require_approval_for_new_accounts
)
self.auth = hs.get_auth()
self.clock = hs.get_clock()
@ -220,6 +233,14 @@ class LoginRestServlet(RestServlet):
except KeyError:
raise SynapseError(400, "Missing JSON keys.")
if self._require_approval:
approved = await self.auth_handler.is_user_approved(result["user_id"])
if not approved:
raise NotApprovedError(
msg="This account is pending approval by a server administrator.",
approval_notice_medium=ApprovalNoticeMedium.NONE,
)
well_known_data = self._well_known_builder.get_well_known()
if well_known_data:
result["well_known"] = well_known_data
@ -356,6 +377,16 @@ class LoginRestServlet(RestServlet):
errcode=Codes.INVALID_PARAM,
)
if self._require_approval:
approved = await self.auth_handler.is_user_approved(user_id)
if not approved:
# If the user isn't approved (and needs to be) we won't allow them to
# actually log in, so we don't want to create a device/access token.
return LoginResponse(
user_id=user_id,
home_server=self.hs.hostname,
)
initial_display_name = login_submission.get("initial_device_display_name")
(
device_id,