From 1527ef5d7ede23b6418db587a350e7a7e72272e5 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 12 Jul 2019 12:09:14 +0100 Subject: [PATCH 1/4] Return a different error from Invalid Password when a user is deactivated --- synapse/api/errors.py | 18 ++++++++++++++++++ synapse/handlers/auth.py | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/synapse/api/errors.py b/synapse/api/errors.py index 28b5c2af9b39..be5e058959f4 100644 --- a/synapse/api/errors.py +++ b/synapse/api/errors.py @@ -138,6 +138,24 @@ def __init__(self, msg, consent_uri): def error_dict(self): return cs_error(self.msg, self.errcode, consent_uri=self._consent_uri) +class UserDeactivatedError(SynapseError): + """The error returned to the client when the user attempted to access an + authenticated endpoint, but the account has been deactivated. + """ + + def __init__(self, msg): + """Constructs a UserDeactivatedError + + Args: + msg (str): The human-readable error message + """ + super(UserDeactivatedError, self).__init__( + code=http_client.FORBIDDEN, msg=msg, errcode=Codes.UNKNOWN + ) + + def error_dict(self): + return cs_error(self.msg, self.errcode) + class RegistrationError(SynapseError): """An error raised when a registration event fails.""" diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py index ef5585aa9912..e6afc2e4ebec 100644 --- a/synapse/handlers/auth.py +++ b/synapse/handlers/auth.py @@ -34,6 +34,7 @@ LoginError, StoreError, SynapseError, + UserDeactivatedError, ) from synapse.api.ratelimiting import Ratelimiter from synapse.logging.context import defer_to_thread @@ -610,6 +611,7 @@ def check_user_exists(self, user_id): Raises: LimitExceededError if the ratelimiter's login requests count for this user is too high too proceed. + UserDeactivatedError if a user is found but is deactivated. """ self.ratelimit_login_per_account(user_id) res = yield self._find_user_id_and_pwd_hash(user_id) @@ -825,6 +827,15 @@ def _check_local_password(self, user_id, password): if not lookupres: defer.returnValue(None) (user_id, password_hash) = lookupres + + # If the password hash is None, the account has likely been deactivated + if not password_hash: + deactivated = yield self.store.get_user_deactivated_status(user_id) + if deactivated: + raise UserDeactivatedError( + "This account has been deactivated" + ) + result = yield self.validate_hash(password, password_hash) if not result: logger.warn("Failed password login for user %s", user_id) From be093b618610c643c672cf037315fd4eb6e09e2f Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 12 Jul 2019 12:15:32 +0100 Subject: [PATCH 2/4] Add changelog --- changelog.d/5674.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5674.feature diff --git a/changelog.d/5674.feature b/changelog.d/5674.feature new file mode 100644 index 000000000000..04bdfa4ad5eb --- /dev/null +++ b/changelog.d/5674.feature @@ -0,0 +1 @@ +Return "This account has been deactivated" when a deactivated user tries to login. From ba5a909c5954d6a69e7bcd7350a5c1527db6dc2c Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 12 Jul 2019 12:16:31 +0100 Subject: [PATCH 3/4] lint --- synapse/api/errors.py | 1 + synapse/handlers/auth.py | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/synapse/api/errors.py b/synapse/api/errors.py index be5e058959f4..6ed9356a7010 100644 --- a/synapse/api/errors.py +++ b/synapse/api/errors.py @@ -138,6 +138,7 @@ def __init__(self, msg, consent_uri): def error_dict(self): return cs_error(self.msg, self.errcode, consent_uri=self._consent_uri) + class UserDeactivatedError(SynapseError): """The error returned to the client when the user attempted to access an authenticated endpoint, but the account has been deactivated. diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py index e6afc2e4ebec..8c00b1e1cc9a 100644 --- a/synapse/handlers/auth.py +++ b/synapse/handlers/auth.py @@ -832,9 +832,7 @@ def _check_local_password(self, user_id, password): if not password_hash: deactivated = yield self.store.get_user_deactivated_status(user_id) if deactivated: - raise UserDeactivatedError( - "This account has been deactivated" - ) + raise UserDeactivatedError("This account has been deactivated") result = yield self.validate_hash(password, password_hash) if not result: From 41117394db1ebde7a4d09423ddc136ba0d2a40a5 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Mon, 15 Jul 2019 11:22:15 +0100 Subject: [PATCH 4/4] Remove redundant error_dict --- synapse/api/errors.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/synapse/api/errors.py b/synapse/api/errors.py index 6ed9356a7010..49716212f9a1 100644 --- a/synapse/api/errors.py +++ b/synapse/api/errors.py @@ -154,9 +154,6 @@ def __init__(self, msg): code=http_client.FORBIDDEN, msg=msg, errcode=Codes.UNKNOWN ) - def error_dict(self): - return cs_error(self.msg, self.errcode) - class RegistrationError(SynapseError): """An error raised when a registration event fails."""