コード例 #1
0
ファイル: register.py プロジェクト: alisheikh/synapse
    def register(self, localpart=None, password=None):
        """Registers a new client on the server.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be randomly generated.
            password (str) : The password to assign to this user so they can
            login again.
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """
        yield run_on_reactor()
        password_hash = None
        if password:
            password_hash = bcrypt.hashpw(password, bcrypt.gensalt())

        if localpart:
            user = UserID(localpart, self.hs.hostname)
            user_id = user.to_string()

            token = self._generate_token(user_id)
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=password_hash
            )

            yield self.distributor.fire("registered_user", user)
        else:
            # autogen a random user ID
            attempts = 0
            user_id = None
            token = None
            while not user_id and not token:
                try:
                    localpart = self._generate_user_id()
                    user = UserID(localpart, self.hs.hostname)
                    user_id = user.to_string()

                    token = self._generate_token(user_id)
                    yield self.store.register(
                        user_id=user_id,
                        token=token,
                        password_hash=password_hash)

                    self.distributor.fire("registered_user", user)
                except SynapseError:
                    # if user id is taken, just generate another
                    user_id = None
                    token = None
                    attempts += 1
                    if attempts > 5:
                        raise RegistrationError(
                            500, "Cannot generate user ID.")

        defer.returnValue((user_id, token))
コード例 #2
0
ファイル: register.py プロジェクト: Xe/synapse
    def register_saml2(self, localpart):
        """
        Registers email_id as SAML2 Based Auth.
        """
        if urllib.quote(localpart) != localpart:
            raise SynapseError(
                400,
                "User ID must only contain characters which do not"
                " require URL encoding."
                )
        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()

        yield self.check_user_id_is_valid(user_id)
        token = self.auth_handler().generate_access_token(user_id)
        try:
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=None
            )
            yield self.distributor.fire("registered_user", user)
        except Exception, e:
            yield self.store.add_access_token_to_user(user_id, token)
            # Ignore Registration errors
            logger.exception(e)
コード例 #3
0
ファイル: register.py プロジェクト: 0-T-0/synapse
    def appservice_register(self, user_localpart, as_token):
        user = UserID(user_localpart, self.hs.hostname)
        user_id = user.to_string()
        service = yield self.store.get_app_service_by_token(as_token)
        if not service:
            raise AuthError(403, "Invalid application service token.")
        if not service.is_interested_in_user(user_id):
            raise SynapseError(
                400, "Invalid user localpart for this application service.",
                errcode=Codes.EXCLUSIVE
            )

        service_id = service.id if service.is_exclusive_user(user_id) else None

        yield self.check_user_id_not_appservice_exclusive(
            user_id, allowed_appservice=service
        )

        token = self.auth_handler().generate_access_token(user_id)
        yield self.store.register(
            user_id=user_id,
            token=token,
            password_hash="",
            appservice_id=service_id,
        )
        yield registered_user(self.distributor, user)
        defer.returnValue((user_id, token))
コード例 #4
0
ファイル: register.py プロジェクト: matrix-org/synapse
    def appservice_register(self, user_localpart, as_token):
        user = UserID(user_localpart, self.hs.hostname)
        user_id = user.to_string()
        service = self.store.get_app_service_by_token(as_token)
        if not service:
            raise AuthError(403, "Invalid application service token.")
        if not service.is_interested_in_user(user_id):
            raise SynapseError(
                400, "Invalid user localpart for this application service.",
                errcode=Codes.EXCLUSIVE
            )

        service_id = service.id if service.is_exclusive_user(user_id) else None

        yield self.check_user_id_not_appservice_exclusive(
            user_id, allowed_appservice=service
        )

        yield self.register_with_store(
            user_id=user_id,
            password_hash="",
            appservice_id=service_id,
            create_profile_with_displayname=user.localpart,
        )
        defer.returnValue(user_id)
コード例 #5
0
ファイル: register.py プロジェクト: gergelypolonkai/synapse
    def register_saml2(self, localpart):
        """
        Registers email_id as SAML2 Based Auth.
        """
        if types.contains_invalid_mxid_characters(localpart):
            raise SynapseError(
                400,
                "User ID can only contain characters a-z, 0-9, or '=_-./'",
            )
        yield self.auth.check_auth_blocking()
        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()

        yield self.check_user_id_not_appservice_exclusive(user_id)
        token = self.macaroon_gen.generate_access_token(user_id)
        try:
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=None,
                create_profile_with_localpart=user.localpart,
            )
        except Exception as e:
            yield self.store.add_access_token_to_user(user_id, token)
            # Ignore Registration errors
            logger.exception(e)
        defer.returnValue((user_id, token))
コード例 #6
0
ファイル: register.py プロジェクト: JigmeDatse/synapse
    def register_saml2(self, localpart):
        """
        Registers email_id as SAML2 Based Auth.
        """
        if urllib.quote(localpart) != localpart:
            raise SynapseError(
                400,
                "User ID must only contain characters which do not"
                " require URL encoding."
            )
        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()

        yield self.check_user_id_not_appservice_exclusive(user_id)
        token = self.auth_handler().generate_access_token(user_id)
        try:
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=None,
                create_profile_with_localpart=user.localpart,
            )
        except Exception as e:
            yield self.store.add_access_token_to_user(user_id, token)
            # Ignore Registration errors
            logger.exception(e)
        defer.returnValue((user_id, token))
コード例 #7
0
ファイル: register.py プロジェクト: Vutsuak16/synapse
    def check_username(self, localpart, guest_access_token=None):
        yield run_on_reactor()

        if urllib.quote(localpart.encode('utf-8')) != localpart:
            raise SynapseError(
                400,
                "User ID can only contain characters a-z, 0-9, or '_-./'",
                Codes.INVALID_USERNAME
            )

        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()

        yield self.check_user_id_is_valid(user_id)

        users = yield self.store.get_users_by_id_case_insensitive(user_id)
        if users:
            if not guest_access_token:
                raise SynapseError(
                    400,
                    "User ID already taken.",
                    errcode=Codes.USER_IN_USE,
                )
            user_data = yield self.auth.get_user_from_macaroon(guest_access_token)
            if not user_data["is_guest"] or user_data["user"].localpart != localpart:
                raise AuthError(
                    403,
                    "Cannot register taken user ID without valid guest "
                    "credentials for that user.",
                    errcode=Codes.FORBIDDEN,
                )
コード例 #8
0
ファイル: register.py プロジェクト: rrix/synapse
 def appservice_register(self, user_localpart, as_token):
     user = UserID(user_localpart, self.hs.hostname)
     user_id = user.to_string()
     service = yield self.store.get_app_service_by_token(as_token)
     if not service:
         raise AuthError(403, "Invalid application service token.")
     if not service.is_interested_in_user(user_id):
         raise SynapseError(400, "Invalid user localpart for this application service.", errcode=Codes.EXCLUSIVE)
     token = self.generate_token(user_id)
     yield self.store.register(user_id=user_id, token=token, password_hash="")
     self.distributor.fire("registered_user", user)
     defer.returnValue((user_id, token))
コード例 #9
0
ファイル: register.py プロジェクト: DoubleMalt/synapse
    def check_username(self, localpart, guest_access_token=None,
                       assigned_user_id=None):
        if types.contains_invalid_mxid_characters(localpart):
            raise SynapseError(
                400,
                "User ID can only contain characters a-z, 0-9, or '=_-./'",
                Codes.INVALID_USERNAME
            )

        if not localpart:
            raise SynapseError(
                400,
                "User ID cannot be empty",
                Codes.INVALID_USERNAME
            )

        if localpart[0] == '_':
            raise SynapseError(
                400,
                "User ID may not begin with _",
                Codes.INVALID_USERNAME
            )

        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()

        if assigned_user_id:
            if user_id == assigned_user_id:
                return
            else:
                raise SynapseError(
                    400,
                    "A different user ID has already been registered for this session",
                )

        self.check_user_id_not_appservice_exclusive(user_id)

        users = yield self.store.get_users_by_id_case_insensitive(user_id)
        if users:
            if not guest_access_token:
                raise SynapseError(
                    400,
                    "User ID already taken.",
                    errcode=Codes.USER_IN_USE,
                )
            user_data = yield self.auth.get_user_by_access_token(guest_access_token)
            if not user_data["is_guest"] or user_data["user"].localpart != localpart:
                raise AuthError(
                    403,
                    "Cannot register taken user ID without valid guest "
                    "credentials for that user.",
                    errcode=Codes.FORBIDDEN,
                )
コード例 #10
0
ファイル: register.py プロジェクト: 0-T-0/synapse
    def get_or_create_user(self, localpart, displayname, duration_seconds):
        """Creates a new user if the user does not exist,
        else revokes all previous access tokens and generates a new one.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be randomly generated.
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """
        yield run_on_reactor()

        if localpart is None:
            raise SynapseError(400, "Request must include user id")

        need_register = True

        try:
            yield self.check_username(localpart)
        except SynapseError as e:
            if e.errcode == Codes.USER_IN_USE:
                need_register = False
            else:
                raise

        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()
        auth_handler = self.hs.get_handlers().auth_handler
        token = auth_handler.generate_short_term_login_token(user_id, duration_seconds)

        if need_register:
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=None
            )

            yield registered_user(self.distributor, user)
        else:
            yield self.store.user_delete_access_tokens(user_id=user_id)
            yield self.store.add_access_token_to_user(user_id=user_id, token=token)

        if displayname is not None:
            logger.info("setting user display name: %s -> %s", user_id, displayname)
            profile_handler = self.hs.get_handlers().profile_handler
            yield profile_handler.set_displayname(
                user, Requester(user, token, False), displayname
            )

        defer.returnValue((user_id, token))
コード例 #11
0
ファイル: register.py プロジェクト: rrix/synapse
    def check_username(self, localpart):
        yield run_on_reactor()

        if urllib.quote(localpart) != localpart:
            raise SynapseError(400, "User ID must only contain characters which do not" " require URL encoding.")

        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()

        yield self.check_user_id_is_valid(user_id)

        users = yield self.store.get_users_by_id_case_insensitive(user_id)
        if users:
            raise SynapseError(400, "User ID already taken.", errcode=Codes.USER_IN_USE)
コード例 #12
0
ファイル: register.py プロジェクト: rubo77/synapse
    def get_or_create_user(self, requester, localpart, displayname,
                           password_hash=None):
        """Creates a new user if the user does not exist,
        else revokes all previous access tokens and generates a new one.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be randomly generated.
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """
        yield run_on_reactor()

        if localpart is None:
            raise SynapseError(400, "Request must include user id")

        need_register = True

        try:
            yield self.check_username(localpart)
        except SynapseError as e:
            if e.errcode == Codes.USER_IN_USE:
                need_register = False
            else:
                raise

        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()
        token = self.macaroon_gen.generate_access_token(user_id)

        if need_register:
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=password_hash,
                create_profile_with_localpart=user.localpart,
            )
        else:
            yield self._auth_handler.delete_access_tokens_for_user(user_id)
            yield self.store.add_access_token_to_user(user_id=user_id, token=token)

        if displayname is not None:
            logger.info("setting user display name: %s -> %s", user_id, displayname)
            yield self.profile_handler.set_displayname(
                user, requester, displayname, by_admin=True,
            )

        defer.returnValue((user_id, token))
コード例 #13
0
ファイル: register.py プロジェクト: soumahorojean/synapse
    def check_username(self, localpart, guest_access_token=None,
                       assigned_user_id=None):
        yield run_on_reactor()

        if urllib.quote(localpart.encode('utf-8')) != localpart:
            raise SynapseError(
                400,
                "User ID can only contain characters a-z, 0-9, or '_-./'",
                Codes.INVALID_USERNAME
            )

        if localpart[0] == '_':
            raise SynapseError(
                400,
                "User ID may not begin with _",
                Codes.INVALID_USERNAME
            )

        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()

        if assigned_user_id:
            if user_id == assigned_user_id:
                return
            else:
                raise SynapseError(
                    400,
                    "A different user ID has already been registered for this session",
                )

        yield self.check_user_id_not_appservice_exclusive(user_id)

        users = yield self.store.get_users_by_id_case_insensitive(user_id)
        if users:
            if not guest_access_token:
                raise SynapseError(
                    400,
                    "User ID already taken.",
                    errcode=Codes.USER_IN_USE,
                )
            user_data = yield self.auth.get_user_from_macaroon(guest_access_token)
            if not user_data["is_guest"] or user_data["user"].localpart != localpart:
                raise AuthError(
                    403,
                    "Cannot register taken user ID without valid guest "
                    "credentials for that user.",
                    errcode=Codes.FORBIDDEN,
                )
コード例 #14
0
ファイル: register.py プロジェクト: ysoffner/synapse
    def get_or_create_user(self, requester, localpart, displayname,
                           password_hash=None):
        """Creates a new user if the user does not exist,
        else revokes all previous access tokens and generates a new one.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be randomly generated.
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """
        if localpart is None:
            raise SynapseError(400, "Request must include user id")

        need_register = True

        try:
            yield self.check_username(localpart)
        except SynapseError as e:
            if e.errcode == Codes.USER_IN_USE:
                need_register = False
            else:
                raise

        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()
        token = self.macaroon_gen.generate_access_token(user_id)

        if need_register:
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=password_hash,
                create_profile_with_localpart=user.localpart,
            )
        else:
            yield self._auth_handler.delete_access_tokens_for_user(user_id)
            yield self.store.add_access_token_to_user(user_id=user_id, token=token)

        if displayname is not None:
            logger.info("setting user display name: %s -> %s", user_id, displayname)
            yield self.profile_handler.set_displayname(
                user, requester, displayname, by_admin=True,
            )

        defer.returnValue((user_id, token))
コード例 #15
0
    async def forget(self, user: UserID, room_id: str) -> None:
        user_id = user.to_string()

        member = await self.state_handler.get_current_state(
            room_id=room_id, event_type=EventTypes.Member, state_key=user_id
        )
        membership = member.membership if member else None

        if membership is not None and membership not in [
            Membership.LEAVE,
            Membership.BAN,
        ]:
            raise SynapseError(400, "User %s in room %s" % (user_id, room_id))

        if membership:
            await self.store.forget(user_id, room_id)
コード例 #16
0
ファイル: appservice.py プロジェクト: MorganBauer/synapse
    def _load_appservice(cls, hostname, as_info, config_filename):
        required_string_fields = [
            "id", "url", "as_token", "hs_token", "sender_localpart"
        ]
        for field in required_string_fields:
            if not isinstance(as_info.get(field), basestring):
                raise KeyError("Required string field: '%s' (%s)" % (
                    field, config_filename,
                ))

        localpart = as_info["sender_localpart"]
        if urllib.quote(localpart) != localpart:
            raise ValueError(
                "sender_localpart needs characters which are not URL encoded."
            )
        user = UserID(localpart, hostname)
        user_id = user.to_string()

        # namespace checks
        if not isinstance(as_info.get("namespaces"), dict):
            raise KeyError("Requires 'namespaces' object.")
        for ns in ApplicationService.NS_LIST:
            # specific namespaces are optional
            if ns in as_info["namespaces"]:
                # expect a list of dicts with exclusive and regex keys
                for regex_obj in as_info["namespaces"][ns]:
                    if not isinstance(regex_obj, dict):
                        raise ValueError(
                            "Expected namespace entry in %s to be an object,"
                            " but got %s", ns, regex_obj
                        )
                    if not isinstance(regex_obj.get("regex"), basestring):
                        raise ValueError(
                            "Missing/bad type 'regex' key in %s", regex_obj
                        )
                    if not isinstance(regex_obj.get("exclusive"), bool):
                        raise ValueError(
                            "Missing/bad type 'exclusive' key in %s", regex_obj
                        )
        return ApplicationService(
            token=as_info["as_token"],
            url=as_info["url"],
            namespaces=as_info["namespaces"],
            hs_token=as_info["hs_token"],
            sender=user_id,
            id=as_info["id"],
        )
コード例 #17
0
ファイル: receipts.py プロジェクト: mjattiot/synapse
    async def get_new_events(
        self, from_key: int, room_ids: List[str], user: UserID, **kwargs
    ) -> Tuple[List[JsonDict], int]:
        from_key = int(from_key)
        to_key = self.get_current_key()

        if from_key == to_key:
            return [], to_key

        events = await self.store.get_linearized_receipts_for_rooms(
            room_ids, from_key=from_key, to_key=to_key
        )

        if self.config.experimental.msc2285_enabled:
            events = ReceiptEventSource.filter_out_hidden(events, user.to_string())

        return (events, to_key)
コード例 #18
0
 def appservice_register(self, user_localpart, as_token):
     user = UserID(user_localpart, self.hs.hostname)
     user_id = user.to_string()
     service = yield self.store.get_app_service_by_token(as_token)
     if not service:
         raise AuthError(403, "Invalid application service token.")
     if not service.is_interested_in_user(user_id):
         raise SynapseError(
             400,
             "Invalid user localpart for this application service.",
             errcode=Codes.EXCLUSIVE)
     token = self._generate_token(user_id)
     yield self.store.register(user_id=user_id,
                               token=token,
                               password_hash="")
     self.distributor.fire("registered_user", user)
     defer.returnValue((user_id, token))
コード例 #19
0
    def _load_appservice(self, as_info):
        required_string_fields = [
            "url", "as_token", "hs_token", "sender_localpart"
        ]
        for field in required_string_fields:
            if not isinstance(as_info.get(field), basestring):
                raise KeyError("Required string field: '%s'", field)

        localpart = as_info["sender_localpart"]
        if urllib.quote(localpart) != localpart:
            raise ValueError(
                "sender_localpart needs characters which are not URL encoded."
            )
        user = UserID(localpart, self.hostname)
        user_id = user.to_string()

        # namespace checks
        if not isinstance(as_info.get("namespaces"), dict):
            raise KeyError("Requires 'namespaces' object.")
        for ns in ApplicationService.NS_LIST:
            # specific namespaces are optional
            if ns in as_info["namespaces"]:
                # expect a list of dicts with exclusive and regex keys
                for regex_obj in as_info["namespaces"][ns]:
                    if not isinstance(regex_obj, dict):
                        raise ValueError(
                            "Expected namespace entry in %s to be an object,"
                            " but got %s", ns, regex_obj
                        )
                    if not isinstance(regex_obj.get("regex"), basestring):
                        raise ValueError(
                            "Missing/bad type 'regex' key in %s", regex_obj
                        )
                    if not isinstance(regex_obj.get("exclusive"), bool):
                        raise ValueError(
                            "Missing/bad type 'exclusive' key in %s", regex_obj
                        )
        return ApplicationService(
            token=as_info["as_token"],
            url=as_info["url"],
            namespaces=as_info["namespaces"],
            hs_token=as_info["hs_token"],
            sender=user_id,
            id=as_info["as_token"]  # the token is the only unique thing here
        )
コード例 #20
0
    async def get_user_ip_and_agents(self,
                                     user: UserID,
                                     since_ts: int = 0
                                     ) -> List[LastConnectionInfo]:
        """Fetch the IPs and user agents for a user since the given timestamp.

        Args:
            user: The user for which to fetch IP addresses and user agents.
            since_ts: The timestamp after which to fetch IP addresses and user agents,
                in milliseconds.

        Returns:
            A list of dictionaries, each containing:
             * `access_token`: The access token used.
             * `ip`: The IP address used.
             * `user_agent`: The last user agent seen for this access token and IP
               address combination.
             * `last_seen`: The timestamp at which this access token and IP address
               combination was last seen, in milliseconds.

            Only the latest user agent for each access token and IP address combination
            is available.
        """
        results: Dict[Tuple[str, str], LastConnectionInfo] = {
            (connection["access_token"], connection["ip"]): connection
            for connection in await super().get_user_ip_and_agents(
                user, since_ts)
        }

        # Overlay data that is pending insertion on top of the results from the
        # database.
        user_id = user.to_string()
        for key in self._batch_row_update:
            uid, access_token, ip = key
            if uid == user_id:
                user_agent, _, last_seen = self._batch_row_update[key]
                if last_seen >= since_ts:
                    results[(access_token, ip)] = {
                        "access_token": access_token,
                        "ip": ip,
                        "user_agent": user_agent,
                        "last_seen": last_seen,
                    }

        return list(results.values())
コード例 #21
0
 async def _remote_reject_invite(
     self,
     requester: Requester,
     remote_room_hosts: List[str],
     room_id: str,
     target: UserID,
     content: dict,
 ) -> Tuple[Optional[str], int]:
     """Implements RoomMemberHandler._remote_reject_invite
     """
     ret = await self._remote_reject_client(
         requester=requester,
         remote_room_hosts=remote_room_hosts,
         room_id=room_id,
         user_id=target.to_string(),
         content=content,
     )
     return ret["event_id"], ret["stream_id"]
コード例 #22
0
    async def get_new_events(
        self,
        user: UserID,
        from_key: int,
        limit: Optional[int],
        room_ids: Collection[str],
        is_guest: bool,
        explicit_room_id: Optional[str] = None,
    ) -> Tuple[List[JsonDict], int]:
        user_id = user.to_string()
        last_stream_id = from_key

        current_stream_id = self.store.get_max_account_data_stream_id()

        results = []
        tags = await self.store.get_updated_tags(user_id, last_stream_id)

        for room_id, room_tags in tags.items():
            results.append({
                "type": "m.tag",
                "content": {
                    "tags": room_tags
                },
                "room_id": room_id
            })

        (
            account_data,
            room_account_data,
        ) = await self.store.get_updated_account_data_for_user(
            user_id, last_stream_id)

        for account_data_type, content in account_data.items():
            results.append({"type": account_data_type, "content": content})

        for room_id, account_data in room_account_data.items():
            for account_data_type, content in account_data.items():
                results.append({
                    "type": account_data_type,
                    "content": content,
                    "room_id": room_id
                })

        return results, current_stream_id
コード例 #23
0
    async def get_whois(self, user: UserID) -> JsonDict:
        connections = []

        sessions = await self.store.get_user_ip_and_agents(user)
        for session in sessions:
            connections.append(
                {
                    "ip": session["ip"],
                    "last_seen": session["last_seen"],
                    "user_agent": session["user_agent"],
                }
            )

        ret = {
            "user_id": user.to_string(),
            "devices": {"": {"sessions": [{"connections": connections}]}},
        }

        return ret
コード例 #24
0
    def create_and_send_event(
        self,
        room_id: str,
        user: UserID,
        soft_failed: bool = False,
        prev_event_ids: Optional[List[str]] = None,
    ) -> str:
        """
        Create and send an event.

        Args:
            soft_failed: Whether to create a soft failed event or not
            prev_event_ids: Explicitly set the prev events,
                or if None just use the default

        Returns:
            The new event's ID.
        """
        event_creator = self.hs.get_event_creation_handler()
        requester = create_requester(user)

        event, context = self.get_success(
            event_creator.create_event(
                requester,
                {
                    "type": EventTypes.Message,
                    "room_id": room_id,
                    "sender": user.to_string(),
                    "content": {
                        "body": secrets.token_hex(),
                        "msgtype": "m.text"
                    },
                },
                prev_event_ids=prev_event_ids,
            ))

        if soft_failed:
            event.internal_metadata.soft_failed = True

        self.get_success(
            event_creator.handle_new_client_event(requester, event, context))

        return event.event_id
コード例 #25
0
    def check_username(self, localpart):
        yield run_on_reactor()

        if urllib.quote(localpart) != localpart:
            raise SynapseError(
                400, "User ID must only contain characters which do not"
                " require URL encoding.")

        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()

        yield self.check_user_id_is_valid(user_id)

        u = yield self.store.get_user_by_id(user_id)
        if u:
            raise SynapseError(
                400,
                "User ID already taken.",
                errcode=Codes.USER_IN_USE,
            )
コード例 #26
0
    async def _remote_join(
        self,
        requester: Requester,
        remote_room_hosts: List[str],
        room_id: str,
        user: UserID,
        content: dict,
    ) -> Tuple[str, int]:
        """Implements RoomMemberHandler._remote_join"""
        if len(remote_room_hosts) == 0:
            raise SynapseError(404, "No known servers")

        ret = await self._remote_join_client(
            requester=requester,
            remote_room_hosts=remote_room_hosts,
            room_id=room_id,
            user_id=user.to_string(),
            content=content,
        )

        return ret["event_id"], ret["stream_id"]
コード例 #27
0
ファイル: register.py プロジェクト: ocd-shepherd/synapse
    def register_saml2(self, localpart):
        """
        Registers email_id as SAML2 Based Auth.
        """
        if urllib.quote(localpart) != localpart:
            raise SynapseError(
                400, "User ID must only contain characters which do not"
                " require URL encoding.")
        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()

        yield self.check_user_id_is_valid(user_id)
        token = self.generate_token(user_id)
        try:
            yield self.store.register(user_id=user_id,
                                      token=token,
                                      password_hash=None)
            yield self.distributor.fire("registered_user", user)
        except Exception, e:
            yield self.store.add_access_token_to_user(user_id, token)
            # Ignore Registration errors
            logger.exception(e)
コード例 #28
0
def format_push_rules_for_user(user: UserID,
                               ruleslist: List) -> Dict[str, Dict[str, list]]:
    """Converts a list of rawrules and a enabled map into nested dictionaries
    to match the Matrix client-server format for push rules"""

    # We're going to be mutating this a lot, so do a deep copy
    ruleslist = copy.deepcopy(ruleslist)

    rules: Dict[str, Dict[str, List[Dict[str, Any]]]] = {
        "global": {},
        "device": {},
    }

    rules["global"] = _add_empty_priority_class_arrays(rules["global"])

    for r in ruleslist:
        template_name = _priority_class_to_template_name(r["priority_class"])

        # Remove internal stuff.
        for c in r["conditions"]:
            c.pop("_id", None)

            pattern_type = c.pop("pattern_type", None)
            if pattern_type == "user_id":
                c["pattern"] = user.to_string()
            elif pattern_type == "user_localpart":
                c["pattern"] = user.localpart

        rulearray = rules["global"][template_name]

        template_rule = _rule_to_template(r)
        if template_rule:
            if "enabled" in r:
                template_rule["enabled"] = r["enabled"]
            else:
                template_rule["enabled"] = True
            rulearray.append(template_rule)

    return rules
コード例 #29
0
    async def _async_render_GET(self, request: Request) -> None:
        try:
            session_id = get_username_mapping_session_cookie_from_request(
                request)
            session = self._sso_handler.get_mapping_session(session_id)
        except SynapseError as e:
            logger.warning("Error fetching session: %s", e)
            self._sso_handler.render_error(request,
                                           "bad_session",
                                           e.msg,
                                           code=e.code)
            return

        # It should be impossible to get here without having first been through
        # the pick-a-username step, which ensures chosen_localpart gets set.
        if not session.chosen_localpart:
            logger.warning("Session has no user name selected")
            self._sso_handler.render_error(request,
                                           "no_user",
                                           "No user name has been selected.",
                                           code=400)
            return

        user_id = UserID(session.chosen_localpart, self._server_name)
        user_profile = {
            "display_name": session.display_name,
        }

        template_params = {
            "user_id": user_id.to_string(),
            "user_profile": user_profile,
            "consent_version": self._consent_version,
            "terms_url": "/_matrix/consent?v=%s" % (self._consent_version, ),
        }

        template = self._jinja_env.get_template("sso_new_user_consent.html")
        html = template.render(template_params)
        respond_with_html(request, 200, html)
コード例 #30
0
 async def store_local_media(
     self,
     media_id: str,
     media_type: str,
     time_now_ms: int,
     upload_name: Optional[str],
     media_length: int,
     user_id: UserID,
     url_cache: Optional[str] = None,
 ) -> None:
     await self.db_pool.simple_insert(
         "local_media_repository",
         {
             "media_id": media_id,
             "media_type": media_type,
             "created_ts": time_now_ms,
             "upload_name": upload_name,
             "media_length": media_length,
             "user_id": user_id.to_string(),
             "url_cache": url_cache,
         },
         desc="store_local_media",
     )
コード例 #31
0
    async def stopped_typing(self, target_user: UserID, requester: Requester,
                             room_id: str) -> None:
        target_user_id = target_user.to_string()
        auth_user_id = requester.user.to_string()

        if not self.is_mine_id(target_user_id):
            raise SynapseError(400, "User is not hosted on this homeserver")

        if target_user_id != auth_user_id:
            raise AuthError(400, "Cannot set another user's typing state")

        if requester.shadow_banned:
            # We randomly sleep a bit just to annoy the requester.
            await self.clock.sleep(random.randint(1, 10))
            raise ShadowBanError()

        await self.auth.check_user_in_room(room_id, target_user_id)

        logger.debug("%s has stopped typing in %s", target_user_id, room_id)

        member = RoomMember(room_id=room_id, user_id=target_user_id)

        self._stopped_typing(member)
コード例 #32
0
ファイル: receipts.py プロジェクト: samuelyi/synapse
    async def get_new_events(
        self,
        user: UserID,
        from_key: int,
        limit: Optional[int],
        room_ids: Iterable[str],
        is_guest: bool,
        explicit_room_id: Optional[str] = None,
    ) -> Tuple[List[JsonDict], int]:
        from_key = int(from_key)
        to_key = self.get_current_key()

        if from_key == to_key:
            return [], to_key

        events = await self.store.get_linearized_receipts_for_rooms(
            room_ids, from_key=from_key, to_key=to_key)

        if self.config.experimental.msc2285_enabled:
            events = ReceiptEventSource.filter_out_private_receipts(
                events, user.to_string())

        return events, to_key
コード例 #33
0
    def register_saml2(self, localpart):
        """
        Registers email_id as SAML2 Based Auth.
        """
        if types.contains_invalid_mxid_characters(localpart):
            raise SynapseError(
                400,
                "User ID can only contain characters a-z, 0-9, or '=_-./'",
            )
        yield self.auth.check_auth_blocking()
        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()

        yield self.check_user_id_not_appservice_exclusive(user_id)
        token = self.macaroon_gen.generate_access_token(user_id)
        try:
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=None,
                create_profile_with_localpart=user.localpart,
                # added by aditya
                gender="",
                dob="",
                address="",
                mobile_no="",
                place="",
                department="",
                branch="",
                # -----------------
            )
        except Exception as e:
            yield self.store.add_access_token_to_user(user_id, token)
            # Ignore Registration errors
            logger.exception(e)
        defer.returnValue((user_id, token))
コード例 #34
0
ファイル: auth.py プロジェクト: matrix-org/synapse
    async def check_can_change_room_list(self, room_id: str, user: UserID) -> bool:
        """Determine whether the user is allowed to edit the room's entry in the
        published room list.

        Args:
            room_id
            user
        """

        is_admin = await self.is_server_admin(user)
        if is_admin:
            return True

        user_id = user.to_string()
        await self.check_user_in_room(room_id, user_id)

        # We currently require the user is a "moderator" in the room. We do this
        # by checking if they would (theoretically) be able to change the
        # m.room.canonical_alias events

        power_level_event = (
            await self._storage_controllers.state.get_current_state_event(
                room_id, EventTypes.PowerLevels, ""
            )
        )

        auth_events = {}
        if power_level_event:
            auth_events[(EventTypes.PowerLevels, "")] = power_level_event

        send_level = event_auth.get_send_level(
            EventTypes.CanonicalAlias, "", power_level_event
        )
        user_level = event_auth.get_user_power_level(user_id, auth_events)

        return user_level >= send_level
コード例 #35
0
    async def _update_join_states(
        self,
        requester: Requester,
        target_user: UserID,
        ratelimit: bool = True,
    ) -> None:
        if not self.hs.is_mine(target_user):
            return

        if ratelimit:
            await self.request_ratelimiter.ratelimit(requester)

        # Do not actually update the room state for shadow-banned users.
        if requester.shadow_banned:
            # We randomly sleep a bit just to annoy the requester.
            await self.clock.sleep(random.randint(1, 10))
            return

        room_ids = await self.store.get_rooms_for_user(target_user.to_string())

        for room_id in room_ids:
            handler = self.hs.get_room_member_handler()
            try:
                # Assume the target_user isn't a guest,
                # because we don't let guests set profile or avatar data.
                await handler.update_membership(
                    requester,
                    target_user,
                    room_id,
                    "join",  # We treat a profile update like a join.
                    ratelimit=
                    False,  # Try to hide that these events aren't atomic.
                )
            except Exception as e:
                logger.warning("Failed to update join event for room %s - %s",
                               room_id, str(e))
コード例 #36
0
ファイル: register.py プロジェクト: xiu/synapse
    async def appservice_register(self, user_localpart, as_token):
        user = UserID(user_localpart, self.hs.hostname)
        user_id = user.to_string()
        service = self.store.get_app_service_by_token(as_token)
        if not service:
            raise AuthError(403, "Invalid application service token.")
        if not service.is_interested_in_user(user_id):
            raise SynapseError(
                400,
                "Invalid user localpart for this application service.",
                errcode=Codes.EXCLUSIVE,
            )

        service_id = service.id if service.is_exclusive_user(user_id) else None

        self.check_user_id_not_appservice_exclusive(user_id, allowed_appservice=service)

        await self.register_with_store(
            user_id=user_id,
            password_hash="",
            appservice_id=service_id,
            create_profile_with_displayname=user.localpart,
        )
        return user_id
コード例 #37
0
    async def _async_render_GET(self, request: Request) -> None:
        try:
            session_id = get_username_mapping_session_cookie_from_request(request)
            session = self._sso_handler.get_mapping_session(session_id)
        except SynapseError as e:
            logger.warning("Error fetching session: %s", e)
            self._sso_handler.render_error(request, "bad_session", e.msg, code=e.code)
            return

        user_id = UserID(session.chosen_localpart, self._server_name)
        user_profile = {
            "display_name": session.display_name,
        }

        template_params = {
            "user_id": user_id.to_string(),
            "user_profile": user_profile,
            "consent_version": self._consent_version,
            "terms_url": "/_matrix/consent?v=%s" % (self._consent_version,),
        }

        template = self._jinja_env.get_template("sso_new_user_consent.html")
        html = template.render(template_params)
        respond_with_html(request, 200, html)
コード例 #38
0
ファイル: register.py プロジェクト: roblabla/synapse
    def register(self, localpart=None, password=None, generate_token=True):
        """Registers a new client on the server.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be randomly generated.
            password (str) : The password to assign to this user so they can
            login again. This can be None which means they cannot login again
            via a password (e.g. the user is an application service user).
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """
        yield run_on_reactor()
        password_hash = None
        if password:
            password_hash = self.auth_handler().hash(password)

        if localpart:
            yield self.check_username(localpart)

            user = UserID(localpart, self.hs.hostname)
            user_id = user.to_string()

            token = None
            if generate_token:
                token = self.auth_handler().generate_access_token(user_id)
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=password_hash
            )

            yield registered_user(self.distributor, user)
        else:
            # autogen a random user ID
            attempts = 0
            user_id = None
            token = None
            while not user_id:
                try:
                    localpart = self._generate_user_id()
                    user = UserID(localpart, self.hs.hostname)
                    user_id = user.to_string()
                    yield self.check_user_id_is_valid(user_id)
                    if generate_token:
                        token = self.auth_handler().generate_access_token(user_id)
                    yield self.store.register(
                        user_id=user_id,
                        token=token,
                        password_hash=password_hash)

                    yield registered_user(self.distributor, user)
                except SynapseError:
                    # if user id is taken, just generate another
                    user_id = None
                    token = None
                    attempts += 1
                    if attempts > 5:
                        raise RegistrationError(
                            500, "Cannot generate user ID.")

        # We used to generate default identicons here, but nowadays
        # we want clients to generate their own as part of their branding
        # rather than there being consistent matrix-wide ones, so we don't.

        defer.returnValue((user_id, token))
コード例 #39
0
ファイル: register.py プロジェクト: xiu/synapse
    async def register_user(
        self,
        localpart=None,
        password_hash=None,
        guest_access_token=None,
        make_guest=False,
        admin=False,
        threepid=None,
        user_type=None,
        default_display_name=None,
        address=None,
        bind_emails=[],
        by_admin=False,
        user_agent_ips=None,
    ):
        """Registers a new client on the server.

        Args:
            localpart: The local part of the user ID to register. If None,
              one will be generated.
            password_hash (str|None): The hashed password to assign to this user so they can
              login again. This can be None which means they cannot login again
              via a password (e.g. the user is an application service user).
            user_type (str|None): type of user. One of the values from
              api.constants.UserTypes, or None for a normal user.
            default_display_name (unicode|None): if set, the new user's displayname
              will be set to this. Defaults to 'localpart'.
            address (str|None): the IP address used to perform the registration.
            bind_emails (List[str]): list of emails to bind to this account.
            by_admin (bool): True if this registration is being made via the
              admin api, otherwise False.
            user_agent_ips (List[(str, str)]): Tuples of IP addresses and user-agents used
                during the registration process.
        Returns:
            str: user_id
        Raises:
            SynapseError if there was a problem registering.
        """
        self.check_registration_ratelimit(address)

        result = self.spam_checker.check_registration_for_spam(
            threepid, localpart, user_agent_ips or [],
        )

        if result == RegistrationBehaviour.DENY:
            logger.info(
                "Blocked registration of %r", localpart,
            )
            # We return a 429 to make it not obvious that they've been
            # denied.
            raise SynapseError(429, "Rate limited")

        shadow_banned = result == RegistrationBehaviour.SHADOW_BAN
        if shadow_banned:
            logger.info(
                "Shadow banning registration of %r", localpart,
            )

        # do not check_auth_blocking if the call is coming through the Admin API
        if not by_admin:
            await self.auth.check_auth_blocking(threepid=threepid)

        if localpart is not None:
            await self.check_username(localpart, guest_access_token=guest_access_token)

            was_guest = guest_access_token is not None

            user = UserID(localpart, self.hs.hostname)
            user_id = user.to_string()

            if was_guest:
                # If the user was a guest then they already have a profile
                default_display_name = None

            elif default_display_name is None:
                default_display_name = localpart

            await self.register_with_store(
                user_id=user_id,
                password_hash=password_hash,
                was_guest=was_guest,
                make_guest=make_guest,
                create_profile_with_displayname=default_display_name,
                admin=admin,
                user_type=user_type,
                address=address,
                shadow_banned=shadow_banned,
            )

            if self.hs.config.user_directory_search_all_users:
                profile = await self.store.get_profileinfo(localpart)
                await self.user_directory_handler.handle_local_profile_change(
                    user_id, profile
                )

        else:
            # autogen a sequential user ID
            fail_count = 0
            user = None
            while not user:
                # Fail after being unable to find a suitable ID a few times
                if fail_count > 10:
                    raise SynapseError(500, "Unable to find a suitable guest user ID")

                localpart = await self.store.generate_user_id()
                user = UserID(localpart, self.hs.hostname)
                user_id = user.to_string()
                self.check_user_id_not_appservice_exclusive(user_id)
                if default_display_name is None:
                    default_display_name = localpart
                try:
                    await self.register_with_store(
                        user_id=user_id,
                        password_hash=password_hash,
                        make_guest=make_guest,
                        create_profile_with_displayname=default_display_name,
                        address=address,
                        shadow_banned=shadow_banned,
                    )

                    # Successfully registered
                    break
                except SynapseError:
                    # if user id is taken, just generate another
                    user = None
                    user_id = None
                    fail_count += 1

        if not self.hs.config.user_consent_at_registration:
            if not self.hs.config.auto_join_rooms_for_guests and make_guest:
                logger.info(
                    "Skipping auto-join for %s because auto-join for guests is disabled",
                    user_id,
                )
            else:
                await self._auto_join_rooms(user_id)
        else:
            logger.info(
                "Skipping auto-join for %s because consent is required at registration",
                user_id,
            )

        # Bind any specified emails to this account
        current_time = self.hs.get_clock().time_msec()
        for email in bind_emails:
            # generate threepid dict
            threepid_dict = {
                "medium": "email",
                "address": email,
                "validated_at": current_time,
            }

            # Bind email to new account
            await self._register_email_threepid(user_id, threepid_dict, None)

        return user_id
コード例 #40
0
ファイル: register.py プロジェクト: rubo77/synapse
    def register(
        self,
        localpart=None,
        password=None,
        generate_token=True,
        guest_access_token=None,
        make_guest=False,
        admin=False,
    ):
        """Registers a new client on the server.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be generated.
            password (str) : The password to assign to this user so they can
              login again. This can be None which means they cannot login again
              via a password (e.g. the user is an application service user).
            generate_token (bool): Whether a new access token should be
              generated. Having this be True should be considered deprecated,
              since it offers no means of associating a device_id with the
              access_token. Instead you should call auth_handler.issue_access_token
              after registration.
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """
        yield run_on_reactor()
        password_hash = None
        if password:
            password_hash = yield self.auth_handler().hash(password)

        if localpart:
            yield self.check_username(localpart, guest_access_token=guest_access_token)

            was_guest = guest_access_token is not None

            if not was_guest:
                try:
                    int(localpart)
                    raise RegistrationError(
                        400,
                        "Numeric user IDs are reserved for guest users."
                    )
                except ValueError:
                    pass

            user = UserID(localpart, self.hs.hostname)
            user_id = user.to_string()

            token = None
            if generate_token:
                token = self.macaroon_gen.generate_access_token(user_id)
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=password_hash,
                was_guest=was_guest,
                make_guest=make_guest,
                create_profile_with_localpart=(
                    # If the user was a guest then they already have a profile
                    None if was_guest else user.localpart
                ),
                admin=admin,
            )

            if self.hs.config.user_directory_search_all_users:
                profile = yield self.store.get_profileinfo(localpart)
                yield self.user_directory_handler.handle_local_profile_change(
                    user_id, profile
                )

        else:
            # autogen a sequential user ID
            attempts = 0
            token = None
            user = None
            while not user:
                localpart = yield self._generate_user_id(attempts > 0)
                user = UserID(localpart, self.hs.hostname)
                user_id = user.to_string()
                yield self.check_user_id_not_appservice_exclusive(user_id)
                if generate_token:
                    token = self.macaroon_gen.generate_access_token(user_id)
                try:
                    yield self.store.register(
                        user_id=user_id,
                        token=token,
                        password_hash=password_hash,
                        make_guest=make_guest,
                        create_profile_with_localpart=user.localpart,
                    )
                except SynapseError:
                    # if user id is taken, just generate another
                    user = None
                    user_id = None
                    token = None
                    attempts += 1

        # auto-join the user to any rooms we're supposed to dump them into
        fake_requester = create_requester(user_id)
        for r in self.hs.config.auto_join_rooms:
            try:
                yield self._join_user_to_room(fake_requester, r)
            except Exception as e:
                logger.error("Failed to join new user to %r: %r", r, e)

        # We used to generate default identicons here, but nowadays
        # we want clients to generate their own as part of their branding
        # rather than there being consistent matrix-wide ones, so we don't.
        defer.returnValue((user_id, token))
コード例 #41
0
def _load_appservice(hostname: str, as_info: JsonDict,
                     config_filename: str) -> ApplicationService:
    required_string_fields = ["id", "as_token", "hs_token", "sender_localpart"]
    for field in required_string_fields:
        if not isinstance(as_info.get(field), str):
            raise KeyError("Required string field: '%s' (%s)" %
                           (field, config_filename))

    # 'url' must either be a string or explicitly null, not missing
    # to avoid accidentally turning off push for ASes.
    if not isinstance(as_info.get("url"), str) and as_info.get("url",
                                                               "") is not None:
        raise KeyError("Required string field or explicit null: 'url' (%s)" %
                       (config_filename, ))

    localpart = as_info["sender_localpart"]
    if urlparse.quote(localpart) != localpart:
        raise ValueError(
            "sender_localpart needs characters which are not URL encoded.")
    user = UserID(localpart, hostname)
    user_id = user.to_string()

    # Rate limiting for users of this AS is on by default (excludes sender)
    rate_limited = as_info.get("rate_limited")
    if not isinstance(rate_limited, bool):
        rate_limited = True

    # namespace checks
    if not isinstance(as_info.get("namespaces"), dict):
        raise KeyError("Requires 'namespaces' object.")
    for ns in ApplicationService.NS_LIST:
        # specific namespaces are optional
        if ns in as_info["namespaces"]:
            # expect a list of dicts with exclusive and regex keys
            for regex_obj in as_info["namespaces"][ns]:
                if not isinstance(regex_obj, dict):
                    raise ValueError(
                        "Expected namespace entry in %s to be an object, but got %s",
                        ns,
                        regex_obj,
                    )
                if not isinstance(regex_obj.get("regex"), str):
                    raise ValueError("Missing/bad type 'regex' key in %s",
                                     regex_obj)
                if not isinstance(regex_obj.get("exclusive"), bool):
                    raise ValueError("Missing/bad type 'exclusive' key in %s",
                                     regex_obj)
    # protocols check
    protocols = as_info.get("protocols")
    if protocols:
        if not isinstance(protocols, list):
            raise KeyError("Optional 'protocols' must be a list if present.")
        for p in protocols:
            if not isinstance(p, str):
                raise KeyError("Bad value for 'protocols' item")

    if as_info["url"] is None:
        logger.info(
            "(%s) Explicitly empty 'url' provided. This application service"
            " will not receive events or queries.",
            config_filename,
        )

    ip_range_whitelist = None
    if as_info.get("ip_range_whitelist"):
        ip_range_whitelist = IPSet(as_info.get("ip_range_whitelist"))

    supports_ephemeral = as_info.get("de.sorunome.msc2409.push_ephemeral",
                                     False)

    # Opt-in flag for the MSC3202-specific transactional behaviour.
    # When enabled, appservice transactions contain the following information:
    #  - device One-Time Key counts
    #  - device unused fallback key usage states
    #  - device list changes
    msc3202_transaction_extensions = as_info.get("org.matrix.msc3202", False)
    if not isinstance(msc3202_transaction_extensions, bool):
        raise ValueError(
            "The `org.matrix.msc3202` option should be true or false if specified."
        )

    return ApplicationService(
        token=as_info["as_token"],
        url=as_info["url"],
        namespaces=as_info["namespaces"],
        hs_token=as_info["hs_token"],
        sender=user_id,
        id=as_info["id"],
        protocols=protocols,
        rate_limited=rate_limited,
        ip_range_whitelist=ip_range_whitelist,
        supports_ephemeral=supports_ephemeral,
        msc3202_transaction_extensions=msc3202_transaction_extensions,
    )
コード例 #42
0
ファイル: presence.py プロジェクト: xorob0/synapse
 async def get_state(self, target_user: UserID) -> UserPresenceState:
     results = await self.get_states([target_user.to_string()])
     return results[0]
コード例 #43
0
    def register(
        self,
        localpart=None,
        password=None,
        generate_token=True,
        guest_access_token=None,
        make_guest=False,
        admin=False,
    ):
        """Registers a new client on the server.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be generated.
            password (str) : The password to assign to this user so they can
              login again. This can be None which means they cannot login again
              via a password (e.g. the user is an application service user).
            generate_token (bool): Whether a new access token should be
              generated. Having this be True should be considered deprecated,
              since it offers no means of associating a device_id with the
              access_token. Instead you should call auth_handler.issue_access_token
              after registration.
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """
        yield run_on_reactor()
        password_hash = None
        if password:
            password_hash = self.auth_handler().hash(password)

        if localpart:
            yield self.check_username(localpart, guest_access_token=guest_access_token)

            was_guest = guest_access_token is not None

            if not was_guest:
                try:
                    int(localpart)
                    raise RegistrationError(
                        400,
                        "Numeric user IDs are reserved for guest users."
                    )
                except ValueError:
                    pass

            user = UserID(localpart, self.hs.hostname)
            user_id = user.to_string()

            token = None
            if generate_token:
                token = self.macaroon_gen.generate_access_token(user_id)
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=password_hash,
                was_guest=was_guest,
                make_guest=make_guest,
                create_profile_with_localpart=(
                    # If the user was a guest then they already have a profile
                    None if was_guest else user.localpart
                ),
                admin=admin,
            )
        else:
            # autogen a sequential user ID
            attempts = 0
            token = None
            user = None
            while not user:
                localpart = yield self._generate_user_id(attempts > 0)
                user = UserID(localpart, self.hs.hostname)
                user_id = user.to_string()
                yield self.check_user_id_not_appservice_exclusive(user_id)
                if generate_token:
                    token = self.macaroon_gen.generate_access_token(user_id)
                try:
                    yield self.store.register(
                        user_id=user_id,
                        token=token,
                        password_hash=password_hash,
                        make_guest=make_guest,
                        create_profile_with_localpart=user.localpart,
                    )
                except SynapseError:
                    # if user id is taken, just generate another
                    user = None
                    user_id = None
                    token = None
                    attempts += 1

        # We used to generate default identicons here, but nowadays
        # we want clients to generate their own as part of their branding
        # rather than there being consistent matrix-wide ones, so we don't.

        defer.returnValue((user_id, token))
コード例 #44
0
ファイル: test_types.py プロジェクト: heavenlyhash/synapse
    def test_build(self):
        user = UserID("5678efgh", "my.domain")

        self.assertEquals(user.to_string(), "@5678efgh:my.domain")
コード例 #45
0
ファイル: register.py プロジェクト: gergelypolonkai/synapse
    def register(
        self,
        localpart=None,
        password=None,
        generate_token=True,
        guest_access_token=None,
        make_guest=False,
        admin=False,
        threepid=None,
    ):
        """Registers a new client on the server.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be generated.
            password (unicode) : The password to assign to this user so they can
              login again. This can be None which means they cannot login again
              via a password (e.g. the user is an application service user).
            generate_token (bool): Whether a new access token should be
              generated. Having this be True should be considered deprecated,
              since it offers no means of associating a device_id with the
              access_token. Instead you should call auth_handler.issue_access_token
              after registration.
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """

        yield self.auth.check_auth_blocking(threepid=threepid)
        password_hash = None
        if password:
            password_hash = yield self.auth_handler().hash(password)

        if localpart:
            yield self.check_username(localpart, guest_access_token=guest_access_token)

            was_guest = guest_access_token is not None

            if not was_guest:
                try:
                    int(localpart)
                    raise RegistrationError(
                        400,
                        "Numeric user IDs are reserved for guest users."
                    )
                except ValueError:
                    pass

            user = UserID(localpart, self.hs.hostname)
            user_id = user.to_string()

            token = None
            if generate_token:
                token = self.macaroon_gen.generate_access_token(user_id)
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=password_hash,
                was_guest=was_guest,
                make_guest=make_guest,
                create_profile_with_localpart=(
                    # If the user was a guest then they already have a profile
                    None if was_guest else user.localpart
                ),
                admin=admin,
            )

            if self.hs.config.user_directory_search_all_users:
                profile = yield self.store.get_profileinfo(localpart)
                yield self.user_directory_handler.handle_local_profile_change(
                    user_id, profile
                )

        else:
            # autogen a sequential user ID
            attempts = 0
            token = None
            user = None
            while not user:
                localpart = yield self._generate_user_id(attempts > 0)
                user = UserID(localpart, self.hs.hostname)
                user_id = user.to_string()
                yield self.check_user_id_not_appservice_exclusive(user_id)
                if generate_token:
                    token = self.macaroon_gen.generate_access_token(user_id)
                try:
                    yield self.store.register(
                        user_id=user_id,
                        token=token,
                        password_hash=password_hash,
                        make_guest=make_guest,
                        create_profile_with_localpart=user.localpart,
                    )
                except SynapseError:
                    # if user id is taken, just generate another
                    user = None
                    user_id = None
                    token = None
                    attempts += 1

        # auto-join the user to any rooms we're supposed to dump them into
        fake_requester = create_requester(user_id)

        # try to create the room if we're the first user on the server
        should_auto_create_rooms = False
        if self.hs.config.autocreate_auto_join_rooms:
            count = yield self.store.count_all_users()
            should_auto_create_rooms = count == 1

        for r in self.hs.config.auto_join_rooms:
            try:
                if should_auto_create_rooms:
                    room_alias = RoomAlias.from_string(r)
                    if self.hs.hostname != room_alias.domain:
                        logger.warning(
                            'Cannot create room alias %s, '
                            'it does not match server domain',
                            r,
                        )
                    else:
                        # create room expects the localpart of the room alias
                        room_alias_localpart = room_alias.localpart

                        # getting the RoomCreationHandler during init gives a dependency
                        # loop
                        yield self.hs.get_room_creation_handler().create_room(
                            fake_requester,
                            config={
                                "preset": "public_chat",
                                "room_alias_name": room_alias_localpart
                            },
                            ratelimit=False,
                        )
                else:
                    yield self._join_user_to_room(fake_requester, r)
            except Exception as e:
                logger.error("Failed to join new user to %r: %r", r, e)

        defer.returnValue((user_id, token))
コード例 #46
0
ファイル: register.py プロジェクト: 0-T-0/synapse
    def register(
        self,
        localpart=None,
        password=None,
        generate_token=True,
        guest_access_token=None,
        make_guest=False
    ):
        """Registers a new client on the server.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be generated.
            password (str) : The password to assign to this user so they can
            login again. This can be None which means they cannot login again
            via a password (e.g. the user is an application service user).
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """
        yield run_on_reactor()
        password_hash = None
        if password:
            password_hash = self.auth_handler().hash(password)

        if localpart:
            yield self.check_username(localpart, guest_access_token=guest_access_token)

            was_guest = guest_access_token is not None

            if not was_guest:
                try:
                    int(localpart)
                    raise RegistrationError(
                        400,
                        "Numeric user IDs are reserved for guest users."
                    )
                except ValueError:
                    pass

            user = UserID(localpart, self.hs.hostname)
            user_id = user.to_string()

            token = None
            if generate_token:
                token = self.auth_handler().generate_access_token(user_id)
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=password_hash,
                was_guest=was_guest,
                make_guest=make_guest,
            )

            yield registered_user(self.distributor, user)
        else:
            # autogen a sequential user ID
            attempts = 0
            token = None
            user = None
            while not user:
                localpart = yield self._generate_user_id(attempts > 0)
                user = UserID(localpart, self.hs.hostname)
                user_id = user.to_string()
                yield self.check_user_id_not_appservice_exclusive(user_id)
                if generate_token:
                    token = self.auth_handler().generate_access_token(user_id)
                try:
                    yield self.store.register(
                        user_id=user_id,
                        token=token,
                        password_hash=password_hash,
                        make_guest=make_guest
                    )
                except SynapseError:
                    # if user id is taken, just generate another
                    user = None
                    user_id = None
                    token = None
                    attempts += 1
            yield registered_user(self.distributor, user)

        # We used to generate default identicons here, but nowadays
        # we want clients to generate their own as part of their branding
        # rather than there being consistent matrix-wide ones, so we don't.

        defer.returnValue((user_id, token))
コード例 #47
0
ファイル: appservice.py プロジェクト: gergelypolonkai/synapse
def _load_appservice(hostname, as_info, config_filename):
    required_string_fields = [
        "id", "as_token", "hs_token", "sender_localpart"
    ]
    for field in required_string_fields:
        if not isinstance(as_info.get(field), string_types):
            raise KeyError("Required string field: '%s' (%s)" % (
                field, config_filename,
            ))

    # 'url' must either be a string or explicitly null, not missing
    # to avoid accidentally turning off push for ASes.
    if (not isinstance(as_info.get("url"), string_types) and
            as_info.get("url", "") is not None):
        raise KeyError(
            "Required string field or explicit null: 'url' (%s)" % (config_filename,)
        )

    localpart = as_info["sender_localpart"]
    if urlparse.quote(localpart) != localpart:
        raise ValueError(
            "sender_localpart needs characters which are not URL encoded."
        )
    user = UserID(localpart, hostname)
    user_id = user.to_string()

    # Rate limiting for users of this AS is on by default (excludes sender)
    rate_limited = True
    if isinstance(as_info.get("rate_limited"), bool):
        rate_limited = as_info.get("rate_limited")

    # namespace checks
    if not isinstance(as_info.get("namespaces"), dict):
        raise KeyError("Requires 'namespaces' object.")
    for ns in ApplicationService.NS_LIST:
        # specific namespaces are optional
        if ns in as_info["namespaces"]:
            # expect a list of dicts with exclusive and regex keys
            for regex_obj in as_info["namespaces"][ns]:
                if not isinstance(regex_obj, dict):
                    raise ValueError(
                        "Expected namespace entry in %s to be an object,"
                        " but got %s", ns, regex_obj
                    )
                if not isinstance(regex_obj.get("regex"), string_types):
                    raise ValueError(
                        "Missing/bad type 'regex' key in %s", regex_obj
                    )
                if not isinstance(regex_obj.get("exclusive"), bool):
                    raise ValueError(
                        "Missing/bad type 'exclusive' key in %s", regex_obj
                    )
    # protocols check
    protocols = as_info.get("protocols")
    if protocols:
        # Because strings are lists in python
        if isinstance(protocols, str) or not isinstance(protocols, list):
            raise KeyError("Optional 'protocols' must be a list if present.")
        for p in protocols:
            if not isinstance(p, str):
                raise KeyError("Bad value for 'protocols' item")

    if as_info["url"] is None:
        logger.info(
            "(%s) Explicitly empty 'url' provided. This application service"
            " will not receive events or queries.",
            config_filename,
        )

    ip_range_whitelist = None
    if as_info.get('ip_range_whitelist'):
        ip_range_whitelist = IPSet(
            as_info.get('ip_range_whitelist')
        )

    return ApplicationService(
        token=as_info["as_token"],
        hostname=hostname,
        url=as_info["url"],
        namespaces=as_info["namespaces"],
        hs_token=as_info["hs_token"],
        sender=user_id,
        id=as_info["id"],
        protocols=protocols,
        rate_limited=rate_limited,
        ip_range_whitelist=ip_range_whitelist,
    )
コード例 #48
0
ファイル: register.py プロジェクト: xiu/synapse
    async def check_username(
        self, localpart, guest_access_token=None, assigned_user_id=None
    ):
        if types.contains_invalid_mxid_characters(localpart):
            raise SynapseError(
                400,
                "User ID can only contain characters a-z, 0-9, or '=_-./'",
                Codes.INVALID_USERNAME,
            )

        if not localpart:
            raise SynapseError(400, "User ID cannot be empty", Codes.INVALID_USERNAME)

        if localpart[0] == "_":
            raise SynapseError(
                400, "User ID may not begin with _", Codes.INVALID_USERNAME
            )

        user = UserID(localpart, self.hs.hostname)
        user_id = user.to_string()

        if assigned_user_id:
            if user_id == assigned_user_id:
                return
            else:
                raise SynapseError(
                    400,
                    "A different user ID has already been registered for this session",
                )

        self.check_user_id_not_appservice_exclusive(user_id)

        if len(user_id) > MAX_USERID_LENGTH:
            raise SynapseError(
                400,
                "User ID may not be longer than %s characters" % (MAX_USERID_LENGTH,),
                Codes.INVALID_USERNAME,
            )

        users = await self.store.get_users_by_id_case_insensitive(user_id)
        if users:
            if not guest_access_token:
                raise SynapseError(
                    400, "User ID already taken.", errcode=Codes.USER_IN_USE
                )
            user_data = await self.auth.get_user_by_access_token(guest_access_token)
            if not user_data["is_guest"] or user_data["user"].localpart != localpart:
                raise AuthError(
                    403,
                    "Cannot register taken user ID without valid guest "
                    "credentials for that user.",
                    errcode=Codes.FORBIDDEN,
                )

        if guest_access_token is None:
            try:
                int(localpart)
                raise SynapseError(
                    400,
                    "Numeric user IDs are reserved for guest users.",
                    errcode=Codes.INVALID_USERNAME,
                )
            except ValueError:
                pass
コード例 #49
0
ファイル: register.py プロジェクト: martindale/synapse
    def register(self, localpart=None, password=None, threepidCreds=None, 
                 captcha_info={}):
        """Registers a new client on the server.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be randomly generated.
            password (str) : The password to assign to this user so they can
            login again.
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """
        if captcha_info:
            captcha_response = yield self._validate_captcha(
                captcha_info["ip"], 
                captcha_info["private_key"],
                captcha_info["challenge"],
                captcha_info["response"]
            )
            if not captcha_response["valid"]:
                logger.info("Invalid captcha entered from %s. Error: %s", 
                            captcha_info["ip"], captcha_response["error_url"])
                raise InvalidCaptchaError(
                    error_url=captcha_response["error_url"]
                )
            else:
                logger.info("Valid captcha entered from %s", captcha_info["ip"])

        if threepidCreds:
            for c in threepidCreds:
                logger.info("validating theeepidcred sid %s on id server %s",
                            c['sid'], c['idServer'])
                try:
                    threepid = yield self._threepid_from_creds(c)
                except:
                    logger.err()
                    raise RegistrationError(400, "Couldn't validate 3pid")
                    
                if not threepid:
                    raise RegistrationError(400, "Couldn't validate 3pid")
                logger.info("got threepid medium %s address %s", 
                            threepid['medium'], threepid['address'])

        password_hash = None
        if password:
            password_hash = bcrypt.hashpw(password, bcrypt.gensalt())

        if localpart:
            user = UserID(localpart, self.hs.hostname, True)
            user_id = user.to_string()

            token = self._generate_token(user_id)
            yield self.store.register(user_id=user_id,
                token=token,
                password_hash=password_hash)

            self.distributor.fire("registered_user", user)
        else:
            # autogen a random user ID
            attempts = 0
            user_id = None
            token = None
            while not user_id and not token:
                try:
                    localpart = self._generate_user_id()
                    user = UserID(localpart, self.hs.hostname, True)
                    user_id = user.to_string()

                    token = self._generate_token(user_id)
                    yield self.store.register(
                        user_id=user_id,
                        token=token,
                        password_hash=password_hash)

                    self.distributor.fire("registered_user", user)
                except SynapseError:
                    # if user id is taken, just generate another
                    user_id = None
                    token = None
                    attempts += 1
                    if attempts > 5:
                        raise RegistrationError(
                            500, "Cannot generate user ID.")

        # Now we have a matrix ID, bind it to the threepids we were given
        if threepidCreds:
            for c in threepidCreds:
                # XXX: This should be a deferred list, shouldn't it?
                yield self._bind_threepid(c, user_id)
                

        defer.returnValue((user_id, token))
コード例 #50
0
ファイル: register.py プロジェクト: cryptoempathy/synapse
    def register(self, localpart=None, password=None):
        """Registers a new client on the server.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be randomly generated.
            password (str) : The password to assign to this user so they can
            login again.
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """
        yield run_on_reactor()
        password_hash = None
        if password:
            password_hash = bcrypt.hashpw(password, bcrypt.gensalt())

        if localpart:
            if localpart and urllib.quote(localpart) != localpart:
                raise SynapseError(
                    400,
                    "User ID must only contain characters which do not"
                    " require URL encoding."
                )

            user = UserID(localpart, self.hs.hostname)
            user_id = user.to_string()

            yield self.check_user_id_is_valid(user_id)

            token = self._generate_token(user_id)
            yield self.store.register(
                user_id=user_id,
                token=token,
                password_hash=password_hash
            )

            yield self.distributor.fire("registered_user", user)
        else:
            # autogen a random user ID
            attempts = 0
            user_id = None
            token = None
            while not user_id and not token:
                try:
                    localpart = self._generate_user_id()
                    user = UserID(localpart, self.hs.hostname)
                    user_id = user.to_string()
                    yield self.check_user_id_is_valid(user_id)

                    token = self._generate_token(user_id)
                    yield self.store.register(
                        user_id=user_id,
                        token=token,
                        password_hash=password_hash)

                    self.distributor.fire("registered_user", user)
                except SynapseError:
                    # if user id is taken, just generate another
                    user_id = None
                    token = None
                    attempts += 1
                    if attempts > 5:
                        raise RegistrationError(
                            500, "Cannot generate user ID.")

        # create a default avatar for the user
        # XXX: ideally clients would explicitly specify one, but given they don't
        # and we want consistent and pretty identicons for random users, we'll
        # do it here.
        try:
            auth_user = UserID.from_string(user_id)
            media_repository = self.hs.get_resource_for_media_repository()
            identicon_resource = media_repository.getChildWithDefault("identicon", None)
            upload_resource = media_repository.getChildWithDefault("upload", None)
            identicon_bytes = identicon_resource.generate_identicon(user_id, 320, 320)
            content_uri = yield upload_resource.create_content(
                "image/png", None, identicon_bytes, len(identicon_bytes), auth_user
            )
            profile_handler = self.hs.get_handlers().profile_handler
            profile_handler.set_avatar_url(
                auth_user, auth_user, ("%s#auto" % (content_uri,))
            )
        except NotImplementedError:
            pass  # make tests pass without messing around creating default avatars

        defer.returnValue((user_id, token))
コード例 #51
0
ファイル: notifier.py プロジェクト: vansh-8502/synapse
    async def get_events_for(
        self,
        user: UserID,
        pagination_config: PaginationConfig,
        timeout: int,
        is_guest: bool = False,
        explicit_room_id: str = None,
    ) -> EventStreamResult:
        """ For the given user and rooms, return any new events for them. If
        there are no new events wait for up to `timeout` milliseconds for any
        new events to happen before returning.

        If explicit_room_id is not set, the user's joined rooms will be polled
        for events.
        If explicit_room_id is set, that room will be polled for events only if
        it is world readable or the user has joined the room.
        """
        from_token = pagination_config.from_token
        if not from_token:
            from_token = self.event_sources.get_current_token()

        limit = pagination_config.limit

        room_ids, is_joined = await self._get_room_ids(user, explicit_room_id)
        is_peeking = not is_joined

        async def check_for_updates(
            before_token: StreamToken, after_token: StreamToken
        ) -> EventStreamResult:
            if not after_token.is_after(before_token):
                return EventStreamResult([], (from_token, from_token))

            events = []  # type: List[EventBase]
            end_token = from_token

            for name, source in self.event_sources.sources.items():
                keyname = "%s_key" % name
                before_id = getattr(before_token, keyname)
                after_id = getattr(after_token, keyname)
                if before_id == after_id:
                    continue

                new_events, new_key = await source.get_new_events(
                    user=user,
                    from_key=getattr(from_token, keyname),
                    limit=limit,
                    is_guest=is_peeking,
                    room_ids=room_ids,
                    explicit_room_id=explicit_room_id,
                )

                if name == "room":
                    new_events = await filter_events_for_client(
                        self.storage,
                        user.to_string(),
                        new_events,
                        is_peeking=is_peeking,
                    )
                elif name == "presence":
                    now = self.clock.time_msec()
                    new_events[:] = [
                        {
                            "type": "m.presence",
                            "content": format_user_presence_state(event, now),
                        }
                        for event in new_events
                    ]

                events.extend(new_events)
                end_token = end_token.copy_and_replace(keyname, new_key)

            return EventStreamResult(events, (from_token, end_token))

        user_id_for_stream = user.to_string()
        if is_peeking:
            # Internally, the notifier keeps an event stream per user_id.
            # This is used by both /sync and /events.
            # We want /events to be used for peeking independently of /sync,
            # without polluting its contents. So we invent an illegal user ID
            # (which thus cannot clash with any real users) for keying peeking
            # over /events.
            #
            # I am sorry for what I have done.
            user_id_for_stream = "_PEEKING_%s_%s" % (
                explicit_room_id,
                user_id_for_stream,
            )

        result = await self.wait_for_events(
            user_id_for_stream,
            timeout,
            check_for_updates,
            room_ids=room_ids,
            from_token=from_token,
        )

        return result
コード例 #52
0
ファイル: register.py プロジェクト: matrix-org/synapse
    def register(
        self,
        localpart=None,
        password=None,
        generate_token=True,
        guest_access_token=None,
        make_guest=False,
        admin=False,
        threepid=None,
        user_type=None,
        default_display_name=None,
        address=None,
        bind_emails=[],
    ):
        """Registers a new client on the server.

        Args:
            localpart : The local part of the user ID to register. If None,
              one will be generated.
            password (unicode) : The password to assign to this user so they can
              login again. This can be None which means they cannot login again
              via a password (e.g. the user is an application service user).
            generate_token (bool): Whether a new access token should be
              generated. Having this be True should be considered deprecated,
              since it offers no means of associating a device_id with the
              access_token. Instead you should call auth_handler.issue_access_token
              after registration.
            user_type (str|None): type of user. One of the values from
              api.constants.UserTypes, or None for a normal user.
            default_display_name (unicode|None): if set, the new user's displayname
              will be set to this. Defaults to 'localpart'.
            address (str|None): the IP address used to perform the registration.
            bind_emails (List[str]): list of emails to bind to this account.
        Returns:
            A tuple of (user_id, access_token).
        Raises:
            RegistrationError if there was a problem registering.
        """

        yield self.auth.check_auth_blocking(threepid=threepid)
        password_hash = None
        if password:
            password_hash = yield self._auth_handler.hash(password)

        if localpart:
            yield self.check_username(localpart, guest_access_token=guest_access_token)

            was_guest = guest_access_token is not None

            if not was_guest:
                try:
                    int(localpart)
                    raise RegistrationError(
                        400,
                        "Numeric user IDs are reserved for guest users."
                    )
                except ValueError:
                    pass

            user = UserID(localpart, self.hs.hostname)
            user_id = user.to_string()

            if was_guest:
                # If the user was a guest then they already have a profile
                default_display_name = None

            elif default_display_name is None:
                default_display_name = localpart

            token = None
            if generate_token:
                token = self.macaroon_gen.generate_access_token(user_id)
            yield self.register_with_store(
                user_id=user_id,
                token=token,
                password_hash=password_hash,
                was_guest=was_guest,
                make_guest=make_guest,
                create_profile_with_displayname=default_display_name,
                admin=admin,
                user_type=user_type,
                address=address,
            )

            if self.hs.config.user_directory_search_all_users:
                profile = yield self.store.get_profileinfo(localpart)
                yield self.user_directory_handler.handle_local_profile_change(
                    user_id, profile
                )

        else:
            # autogen a sequential user ID
            attempts = 0
            token = None
            user = None
            while not user:
                localpart = yield self._generate_user_id(attempts > 0)
                user = UserID(localpart, self.hs.hostname)
                user_id = user.to_string()
                yield self.check_user_id_not_appservice_exclusive(user_id)
                if generate_token:
                    token = self.macaroon_gen.generate_access_token(user_id)
                if default_display_name is None:
                    default_display_name = localpart
                try:
                    yield self.register_with_store(
                        user_id=user_id,
                        token=token,
                        password_hash=password_hash,
                        make_guest=make_guest,
                        create_profile_with_displayname=default_display_name,
                        address=address,
                    )
                except SynapseError:
                    # if user id is taken, just generate another
                    user = None
                    user_id = None
                    token = None
                    attempts += 1
        if not self.hs.config.user_consent_at_registration:
            yield self._auto_join_rooms(user_id)

        # Bind any specified emails to this account
        current_time = self.hs.get_clock().time_msec()
        for email in bind_emails:
            # generate threepid dict
            threepid_dict = {
                "medium": "email",
                "address": email,
                "validated_at": current_time,
            }

            # Bind email to new account
            yield self._register_email_threepid(
                user_id, threepid_dict, None, False,
            )

        defer.returnValue((user_id, token))