From 3b0a477db32c03096e3130ea5c233ddbf2d171bf Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Thu, 6 Jun 2019 15:53:40 +0100 Subject: Fix bugs with database --- synapse/app/homeserver.py | 1 + synapse/handlers/auth.py | 15 ++++-- synapse/rest/client/v2_alpha/account.py | 5 +- synapse/storage/registration.py | 89 +++++++++++---------------------- 4 files changed, 41 insertions(+), 69 deletions(-) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index 1045d28949..df524a23dd 100755 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -176,6 +176,7 @@ class SynapseHomeServer(HomeServer): resources.update({ "/_matrix/client/api/v1": client_resource, + "/_synapse/password_reset": client_resource, "/_matrix/client/r0": client_resource, "/_matrix/client/unstable": client_resource, "/_matrix/client/v2_alpha": client_resource, diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py index 96f4521dcd..8dda8a7fd9 100644 --- a/synapse/handlers/auth.py +++ b/synapse/handlers/auth.py @@ -477,24 +477,29 @@ class AuthHandler(BaseHandler): identity_handler = self.hs.get_handlers().identity_handler logger.info("Getting validated threepid. threepidcreds: %r", (threepid_creds,)) - if password_servlet and not self.hs.config.email_enable_password_reset_from_is: + if password_servlet and self.hs.config.email_password_reset_behaviour == "local": row = yield self.store.get_threepid_validation_session( medium, threepid_creds["client_secret"], sid=threepid_creds["sid"], ) + logger.info("STUFF: %s", medium) + logger.info("ROW: %s", row) + threepid = { "medium": row["medium"], "address": row["address"], "validated_at": row["validated_at"], } if row else None - # Valid threepid returned, delete from the db - yield self.store.delete_threepid_session(threepid_creds["sid"]) - else: - logger.info("Using IS") + if row: + # Valid threepid returned, delete from the db + yield self.store.delete_threepid_session(threepid_creds["sid"]) + elif self.hs.config.password_reset_behaviour == "remote": threepid = yield identity_handler.threepid_from_creds(threepid_creds) + else: + raise SynapseError(400, "Password resets are not enabled on this homeserver") if not threepid: raise LoginError(401, "", errcode=Codes.UNAUTHORIZED) diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 3e33b5b551..657afb495a 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -176,6 +176,7 @@ class EmailPasswordRequestTokenRestServlet(RestServlet): token_expires = (self.hs.clock.time_msec() + self.config.email_validation_token_lifetime) + logger.info("lifetime: %s", self.config.email_validation_token_lifetime) yield self.datastore.start_or_continue_validation_session( "email", email, session_id, client_secret, send_attempt, @@ -260,10 +261,6 @@ class ThreepidSubmitTokenServlet(RestServlet): self.clock.time_msec(), ) - # Delete associated session tokens from the db as we have no - # further use for them - yield self.datastore.delete_threepid_tokens(sid) - # Perform a 302 redirect if next_link is set if next_link: if next_link.startswith("file:///"): diff --git a/synapse/storage/registration.py b/synapse/storage/registration.py index 43650d7a48..9b41cbd757 100644 --- a/synapse/storage/registration.py +++ b/synapse/storage/registration.py @@ -1021,19 +1021,20 @@ class RegistrationStore( keyvalues = { "medium": medium, "client_secret": client_secret, - "session_id": sid, - "address": address, } - cols_to_return = [ - "session_id", "medium", "address", - "client_secret", "last_send_attempt", "validated_at", - ] + if address: + keyvalues["address"] = address + if sid: + keyvalues["session_id"] = sid + + assert(address or sid) def get_threepid_validation_session_txn(txn): - sql = "SELECT %s FROM threepid_validation_session WHERE %s" % ( - ", ".join(cols_to_return), - " AND ".join("%s = ?" % k for k in iterkeys(keyvalues)), - ) + sql = """ + SELECT address, session_id, medium, client_secret, + last_send_attempt, validated_at + FROM threepid_validation_session WHERE %s + """ % (" AND ".join("%s = ?" % k for k in iterkeys(keyvalues)),) if validated is not None: sql += " AND validated_at IS " + ("NOT NULL" if validated else "NULL") @@ -1088,10 +1089,6 @@ class RegistrationStore( retrieved_client_secret = row["client_secret"] validated_at = row["validated_at"] - if validated_at: - raise ThreepidValidationError( - 400, "This session has already been validated", - ) if retrieved_client_secret != client_secret: raise ThreepidValidationError( 400, "This client_secret does not match the provided session_id", @@ -1112,6 +1109,10 @@ class RegistrationStore( expires = row["expires"] next_link = row["next_link"] + # If the session is already validated, no need to revalidate + if validated_at: + return next_link + if expires <= current_ts: raise ThreepidValidationError( 400, "This token has expired. Please request a new one", @@ -1228,35 +1229,6 @@ class RegistrationStore( start_or_continue_validation_session_txn, ) - def insert_threepid_validation_token( - self, - session_id, - token, - expires, - next_link=None, - ): - """Insert a new 3PID validation token and details - - Args: - session_id (str): The id of the validation session this attempt - is related to - token (str): The validation token - expires (int): The timestamp for which after this token will no - longer be valid - next_link (str|None): The link to redirect the user to upon successful - validation - """ - return self._simple_insert( - table="threepid_validation_token", - values={ - "session_id": session_id, - "token": token, - "next_link": next_link, - "expires": expires, - }, - desc="insert_threepid_validation_token", - ) - def cull_expired_threepid_validation_tokens(self): """Remove threepid validation tokens with expiry dates that have passed""" def cull_expired_threepid_validation_tokens_txn(txn, ts): @@ -1280,22 +1252,19 @@ class RegistrationStore( Args: session_id (str): The ID of the session to delete """ - return self._simple_delete( - table="threepid_validation_session", - keyvalues={"session_id": session_id}, - desc="delete_threepid_session", - ) - - def delete_threepid_tokens(self, session_id): - """Removes threepid validation tokens from the database which match a - given session ID. + def delete_threepid_session_txn(txn): + self._simple_delete_txn( + txn, + table="threepid_validation_token", + keyvalues={"session_id": session_id}, + ) + self._simple_delete_txn( + txn, + table="threepid_validation_session", + keyvalues={"session_id": session_id}, + ) - Args: - session_id (str): The ID of the session to delete - """ - # Delete tokens associated with this session id - return self._simple_delete_one( - table="threepid_validation_token", - keyvalues={"session_id": session_id}, - desc="delete_threepid_session_tokens", + return self.runInteraction( + "delete_threepid_session", + delete_threepid_session_txn, ) -- cgit 1.4.1