diff options
author | Erik Johnston <erik@matrix.org> | 2015-08-21 11:34:43 +0100 |
---|---|---|
committer | Erik Johnston <erik@matrix.org> | 2015-08-21 11:38:44 +0100 |
commit | 42f12ad92f5bc372569f15ffc81e9cf8146d2ac6 (patch) | |
tree | 5b9e4d484c7a3e0110c8fafeed2428fb00a20b8b /synapse/handlers | |
parent | Don't allow people to register user ids which only differ by case to an exist... (diff) | |
download | synapse-42f12ad92f5bc372569f15ffc81e9cf8146d2ac6.tar.xz |
When logging in fetch user by user_id case insensitively, *unless* there are multiple case insensitive matches, in which case require the exact user_id
Diffstat (limited to 'synapse/handlers')
-rw-r--r-- | synapse/handlers/auth.py | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py index ff2c66f442..058a0f416d 100644 --- a/synapse/handlers/auth.py +++ b/synapse/handlers/auth.py @@ -162,7 +162,8 @@ class AuthHandler(BaseHandler): if not user_id.startswith('@'): user_id = UserID.create(user_id, self.hs.hostname).to_string() - yield self._check_password(user_id, password) + user_id, password_hash = yield self._find_user_id_and_pwd_hash(user_id) + self._check_password(user_id, password, password_hash) defer.returnValue(user_id) @defer.inlineCallbacks @@ -283,23 +284,37 @@ class AuthHandler(BaseHandler): StoreError if there was a problem storing the token. LoginError if there was an authentication problem. """ - yield self._check_password(user_id, password) + user_id, password_hash = yield self._find_user_id_and_pwd_hash(user_id) + self._check_password(user_id, password, password_hash) reg_handler = self.hs.get_handlers().registration_handler access_token = reg_handler.generate_token(user_id) logger.info("Logging in user %s", user_id) yield self.store.add_access_token_to_user(user_id, access_token) - defer.returnValue(access_token) + defer.returnValue((user_id, access_token)) @defer.inlineCallbacks - def _check_password(self, user_id, password): - """Checks that user_id has passed password, raises LoginError if not.""" - user_info = yield self.store.get_user_by_id(user_id=user_id) - if not user_info: + def _find_user_id_and_pwd_hash(self, user_id): + user_infos = yield self.store.get_users_by_id_case_insensitive(user_id) + if not user_infos: logger.warn("Attempted to login as %s but they do not exist", user_id) raise LoginError(403, "", errcode=Codes.FORBIDDEN) - stored_hash = user_info["password_hash"] + if len(user_infos) > 1: + if user_id not in user_infos: + logger.warn( + "Attempted to login as %s but it matches more than one user " + "inexactly: %r", + user_id, user_infos.keys() + ) + raise LoginError(403, "", errcode=Codes.FORBIDDEN) + + defer.returnValue((user_id, user_infos[user_id])) + else: + defer.returnValue(user_infos.popitem()) + + def _check_password(self, user_id, password, stored_hash): + """Checks that user_id has passed password, raises LoginError if not.""" if not bcrypt.checkpw(password, stored_hash): logger.warn("Failed password login for user %s", user_id) raise LoginError(403, "", errcode=Codes.FORBIDDEN) |