def register_email(self, threepidCreds): """ Registers emails with an identity server. Used only by c/s api v1 """ for c in threepidCreds: logger.info("validating threepidcred sid %s on id server %s", c['sid'], c['idServer']) try: identity_handler = self.hs.get_handlers().identity_handler threepid = yield identity_handler.threepid_from_creds(c) except Exception: logger.exception("Couldn't validate 3pid") raise RegistrationError(400, "Couldn't validate 3pid") if not threepid: raise RegistrationError(400, "Couldn't validate 3pid") logger.info("got threepid with medium '%s' and address '%s'", threepid['medium'], threepid['address']) if not check_3pid_allowed(self.hs, threepid['medium'], threepid['address']): raise RegistrationError( 403, "Third party identifier is not allowed")
def register_email(self, threepidCreds): """Registers emails with an identity server.""" 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'])
def _check_mau_limits(self): """ Do not accept registrations if monthly active user limits exceeded and limiting is enabled """ if self.hs.config.limit_usage_by_mau is True: current_mau = yield self.store.count_monthly_users() if current_mau >= self.hs.config.max_mau_value: raise RegistrationError(403, "MAU Limit Exceeded", Codes.MAU_LIMIT_EXCEEDED)
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))
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))
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 if not self.hs.config.user_consent_at_registration: yield self._auto_join_rooms(user_id) defer.returnValue((user_id, token))
def register_user( self, localpart=None, password=None, 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). 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: Deferred[str]: user_id Raises: RegistrationError if there was a problem registering. """ yield self.check_registration_ratelimit(address) 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 yield 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, ) 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 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 = yield self._generate_user_id() user = UserID(localpart, self.hs.hostname) user_id = user.to_string() yield self.check_user_id_not_appservice_exclusive(user_id) if default_display_name is None: default_display_name = localpart try: yield 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, ) # 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: yield 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 yield self._register_email_threepid(user_id, threepid_dict, None) return user_id
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: yield self.check_username(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() 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))
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))
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))
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))
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))