diff --git a/sydent/db/threepid_validation.sql b/sydent/db/threepid_validation.sql index ae655279..f7c104d1 100644 --- a/sydent/db/threepid_validation.sql +++ b/sydent/db/threepid_validation.sql @@ -17,3 +17,5 @@ limitations under the License. CREATE TABLE IF NOT EXISTS threepid_validation_sessions (id integer primary key, medium varchar(16) not null, address varchar(256) not null, clientSecret varchar(32) not null, validated int default 0, mtime bigint not null); CREATE TABLE IF NOT EXISTS threepid_token_auths (id integer primary key, validationSession integer not null, token varchar(32) not null, sendAttemptNumber integer not null, foreign key (validationSession) references threepid_validations(id)); +-- Used to find and delete expired sessions +CREATE INDEX IF NOT EXISTS threepid_validation_sessions_mtime ON threepid_validation_sessions(mtime); diff --git a/sydent/db/valsession.py b/sydent/db/valsession.py index 8d5a1ea0..2a261bd7 100644 --- a/sydent/db/valsession.py +++ b/sydent/db/valsession.py @@ -14,6 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from twisted.internet import task + import sydent.util.tokenutils from sydent.validators import ValidationSession, IncorrectClientSecretException, InvalidSessionIdException, \ @@ -25,6 +27,10 @@ class ThreePidValSessionStore: def __init__(self, syd): self.sydent = syd + # Clean up old sessions every N minutes + cb = task.LoopingCall(self.deleteOldSessions) + cb.start(10 * 60.0) + def getOrCreateTokenSession(self, medium, address, clientSecret): cur = self.sydent.db.cursor() @@ -127,3 +133,27 @@ def getValidatedSession(self, sid, clientSecret): raise SessionNotValidatedException() return s + + def deleteOldSessions(self): + """Delete old threepid validation sessions that are long expired. + """ + + cur = self.sydent.db.cursor() + + delete_before_ts = time_msec() - 5 * ValidationSession.THREEPID_SESSION_VALID_LIFETIME_MS + + sql = """ + DELETE FROM threepid_validation_sessions + WHERE mtime < ? + """ + cur.execute(sql, (delete_before_ts,)) + + sql = """ + DELETE FROM threepid_token_auths + WHERE validationSession NOT IN ( + SELECT id FROM threepid_validation_sessions + ) + """ + cur.execute(sql, (delete_before_ts,)) + + self.sydent.db.commit()