2019-02-18 07:12:57 -05:00
|
|
|
#
|
2023-11-21 15:29:58 -05:00
|
|
|
# This file is licensed under the Affero General Public License (AGPL) version 3.
|
|
|
|
#
|
|
|
|
# Copyright (C) 2023 New Vector, Ltd
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU Affero General Public License as
|
|
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
|
|
# License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# See the GNU Affero General Public License for more details:
|
|
|
|
# <https://www.gnu.org/licenses/agpl-3.0.html>.
|
|
|
|
#
|
|
|
|
# Originally licensed under the Apache License, Version 2.0:
|
|
|
|
# <http://www.apache.org/licenses/LICENSE-2.0>.
|
|
|
|
#
|
|
|
|
# [This file includes modifications made by New Vector Limited]
|
2019-02-18 07:12:57 -05:00
|
|
|
#
|
|
|
|
#
|
|
|
|
|
|
|
|
import logging
|
2022-02-08 07:44:39 -05:00
|
|
|
from typing import TYPE_CHECKING, Optional, Tuple
|
2019-02-18 07:12:57 -05:00
|
|
|
|
2022-02-08 07:44:39 -05:00
|
|
|
from twisted.web.server import Request
|
|
|
|
|
|
|
|
from synapse.http.server import HttpServer
|
2019-02-18 07:12:57 -05:00
|
|
|
from synapse.replication.http._base import ReplicationEndpoint
|
2022-02-08 07:44:39 -05:00
|
|
|
from synapse.types import JsonDict
|
2019-02-18 07:12:57 -05:00
|
|
|
|
2021-10-22 13:15:41 -04:00
|
|
|
if TYPE_CHECKING:
|
|
|
|
from synapse.server import HomeServer
|
|
|
|
|
2019-02-18 07:12:57 -05:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class ReplicationRegisterServlet(ReplicationEndpoint):
|
|
|
|
"""Register a new user"""
|
|
|
|
|
|
|
|
NAME = "register_user"
|
|
|
|
PATH_ARGS = ("user_id",)
|
|
|
|
|
2021-10-22 13:15:41 -04:00
|
|
|
def __init__(self, hs: "HomeServer"):
|
2020-09-18 09:56:44 -04:00
|
|
|
super().__init__(hs)
|
2022-02-23 06:04:02 -05:00
|
|
|
self.store = hs.get_datastores().main
|
2019-03-05 09:25:33 -05:00
|
|
|
self.registration_handler = hs.get_registration_handler()
|
2019-02-18 07:12:57 -05:00
|
|
|
|
2022-10-11 08:41:06 -04:00
|
|
|
# Default value if the worker that sent the replication request did not include
|
|
|
|
# an 'approved' property.
|
|
|
|
if (
|
|
|
|
hs.config.experimental.msc3866.enabled
|
|
|
|
and hs.config.experimental.msc3866.require_approval_for_new_accounts
|
|
|
|
):
|
|
|
|
self._approval_default = False
|
|
|
|
else:
|
|
|
|
self._approval_default = True
|
|
|
|
|
2019-02-18 07:12:57 -05:00
|
|
|
@staticmethod
|
2022-02-08 07:44:39 -05:00
|
|
|
async def _serialize_payload( # type: ignore[override]
|
|
|
|
user_id: str,
|
|
|
|
password_hash: Optional[str],
|
|
|
|
was_guest: bool,
|
|
|
|
make_guest: bool,
|
|
|
|
appservice_id: Optional[str],
|
|
|
|
create_profile_with_displayname: Optional[str],
|
|
|
|
admin: bool,
|
|
|
|
user_type: Optional[str],
|
|
|
|
address: Optional[str],
|
|
|
|
shadow_banned: bool,
|
2022-09-29 09:23:24 -04:00
|
|
|
approved: bool,
|
2022-02-08 07:44:39 -05:00
|
|
|
) -> JsonDict:
|
2019-02-18 07:12:57 -05:00
|
|
|
"""
|
|
|
|
Args:
|
2022-02-08 07:44:39 -05:00
|
|
|
user_id: The desired user ID to register.
|
|
|
|
password_hash: Optional. The password hash for this user.
|
|
|
|
was_guest: Optional. Whether this is a guest account being upgraded
|
|
|
|
to a non-guest account.
|
|
|
|
make_guest: True if the the new user should be guest, false to add a
|
|
|
|
regular user account.
|
|
|
|
appservice_id: The ID of the appservice registering the user.
|
|
|
|
create_profile_with_displayname: Optionally create a profile for the
|
|
|
|
user, setting their displayname to the given value
|
|
|
|
admin: is an admin user?
|
|
|
|
user_type: type of user. One of the values from api.constants.UserTypes,
|
|
|
|
or None for a normal user.
|
|
|
|
address: the IP address used to perform the regitration.
|
|
|
|
shadow_banned: Whether to shadow-ban the user
|
2022-09-29 09:23:24 -04:00
|
|
|
approved: Whether the user should be considered already approved by an
|
|
|
|
administrator.
|
2019-02-18 07:12:57 -05:00
|
|
|
"""
|
|
|
|
return {
|
|
|
|
"password_hash": password_hash,
|
|
|
|
"was_guest": was_guest,
|
|
|
|
"make_guest": make_guest,
|
|
|
|
"appservice_id": appservice_id,
|
|
|
|
"create_profile_with_displayname": create_profile_with_displayname,
|
|
|
|
"admin": admin,
|
|
|
|
"user_type": user_type,
|
2019-03-05 09:25:33 -05:00
|
|
|
"address": address,
|
2020-08-14 12:37:59 -04:00
|
|
|
"shadow_banned": shadow_banned,
|
2022-09-29 09:23:24 -04:00
|
|
|
"approved": approved,
|
2019-02-18 07:12:57 -05:00
|
|
|
}
|
|
|
|
|
2022-02-08 07:44:39 -05:00
|
|
|
async def _handle_request( # type: ignore[override]
|
2023-01-18 14:35:29 -05:00
|
|
|
self, request: Request, content: JsonDict, user_id: str
|
2022-02-08 07:44:39 -05:00
|
|
|
) -> Tuple[int, JsonDict]:
|
2021-03-30 07:06:09 -04:00
|
|
|
await self.registration_handler.check_registration_ratelimit(content["address"])
|
2019-11-06 07:01:54 -05:00
|
|
|
|
2022-10-11 08:41:06 -04:00
|
|
|
# Always default admin users to approved (since it means they were created by
|
|
|
|
# an admin).
|
|
|
|
approved_default = self._approval_default
|
|
|
|
if content["admin"]:
|
|
|
|
approved_default = True
|
|
|
|
|
2019-10-29 09:00:51 -04:00
|
|
|
await self.registration_handler.register_with_store(
|
2019-02-18 07:12:57 -05:00
|
|
|
user_id=user_id,
|
|
|
|
password_hash=content["password_hash"],
|
|
|
|
was_guest=content["was_guest"],
|
|
|
|
make_guest=content["make_guest"],
|
|
|
|
appservice_id=content["appservice_id"],
|
|
|
|
create_profile_with_displayname=content["create_profile_with_displayname"],
|
|
|
|
admin=content["admin"],
|
|
|
|
user_type=content["user_type"],
|
2019-03-05 09:25:33 -05:00
|
|
|
address=content["address"],
|
2020-08-14 12:37:59 -04:00
|
|
|
shadow_banned=content["shadow_banned"],
|
2022-10-11 08:41:06 -04:00
|
|
|
approved=content.get("approved", approved_default),
|
2019-02-18 07:12:57 -05:00
|
|
|
)
|
|
|
|
|
2019-08-30 11:28:26 -04:00
|
|
|
return 200, {}
|
2019-02-18 07:12:57 -05:00
|
|
|
|
|
|
|
|
2019-02-20 02:47:31 -05:00
|
|
|
class ReplicationPostRegisterActionsServlet(ReplicationEndpoint):
|
|
|
|
"""Run any post registration actions"""
|
|
|
|
|
|
|
|
NAME = "post_register"
|
|
|
|
PATH_ARGS = ("user_id",)
|
|
|
|
|
2021-10-22 13:15:41 -04:00
|
|
|
def __init__(self, hs: "HomeServer"):
|
2020-09-18 09:56:44 -04:00
|
|
|
super().__init__(hs)
|
2022-02-23 06:04:02 -05:00
|
|
|
self.store = hs.get_datastores().main
|
2019-02-20 02:47:31 -05:00
|
|
|
self.registration_handler = hs.get_registration_handler()
|
|
|
|
|
|
|
|
@staticmethod
|
2022-02-08 07:44:39 -05:00
|
|
|
async def _serialize_payload( # type: ignore[override]
|
|
|
|
user_id: str, auth_result: JsonDict, access_token: Optional[str]
|
|
|
|
) -> JsonDict:
|
2019-02-20 02:47:31 -05:00
|
|
|
"""
|
|
|
|
Args:
|
2022-02-08 07:44:39 -05:00
|
|
|
user_id: The user ID that consented
|
|
|
|
auth_result: The authenticated credentials of the newly registered user.
|
|
|
|
access_token: The access token of the newly logged in
|
2019-02-20 02:47:31 -05:00
|
|
|
device, or None if `inhibit_login` enabled.
|
|
|
|
"""
|
2019-09-04 13:24:23 -04:00
|
|
|
return {"auth_result": auth_result, "access_token": access_token}
|
2019-02-20 02:47:31 -05:00
|
|
|
|
2022-02-08 07:44:39 -05:00
|
|
|
async def _handle_request( # type: ignore[override]
|
2023-01-18 14:35:29 -05:00
|
|
|
self, request: Request, content: JsonDict, user_id: str
|
2022-02-08 07:44:39 -05:00
|
|
|
) -> Tuple[int, JsonDict]:
|
2019-02-20 02:47:31 -05:00
|
|
|
auth_result = content["auth_result"]
|
|
|
|
access_token = content["access_token"]
|
|
|
|
|
2019-10-29 09:00:51 -04:00
|
|
|
await self.registration_handler.post_registration_actions(
|
2019-09-04 13:24:23 -04:00
|
|
|
user_id=user_id, auth_result=auth_result, access_token=access_token
|
2019-02-20 02:47:31 -05:00
|
|
|
)
|
|
|
|
|
2019-08-30 11:28:26 -04:00
|
|
|
return 200, {}
|
2019-02-20 02:47:31 -05:00
|
|
|
|
|
|
|
|
2022-02-08 07:44:39 -05:00
|
|
|
def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None:
|
2019-02-18 07:12:57 -05:00
|
|
|
ReplicationRegisterServlet(hs).register(http_server)
|
2019-02-20 02:47:31 -05:00
|
|
|
ReplicationPostRegisterActionsServlet(hs).register(http_server)
|