diff --git a/synapse/api/auth.py b/synapse/api/auth.py index 86f145649c..ac062b57ca 100644 --- a/synapse/api/auth.py +++ b/synapse/api/auth.py @@ -519,6 +519,15 @@ class Auth(object): if not ret: defer.returnValue(None) + if ret.get("expired", False): + logger.warn("Doing soft logout on user") + raise AuthError( + 401, + "Token soft logged out", + errcode=Codes.UNKNOWN_TOKEN, + softLogout=true, + ) + # we use ret.get() below because *lots* of unit tests stub out # get_user_by_access_token in a way where it only returns a couple of # the fields. diff --git a/synapse/api/errors.py b/synapse/api/errors.py index 28b5c2af9b..6d88fda38b 100644 --- a/synapse/api/errors.py +++ b/synapse/api/errors.py @@ -85,7 +85,7 @@ class SynapseError(CodeMessageException): errcode (str): Matrix error code e.g 'M_FORBIDDEN' """ - def __init__(self, code, msg, errcode=Codes.UNKNOWN): + def __init__(self, code, msg, errcode=Codes.UNKNOWN, softLogout=False): """Constructs a synapse error. Args: @@ -97,7 +97,7 @@ class SynapseError(CodeMessageException): self.errcode = errcode def error_dict(self): - return cs_error(self.msg, self.errcode) + return cs_error(self.msg, self.errcode, self.softLogout) class ProxiedRequestError(SynapseError): @@ -383,7 +383,7 @@ class RequestSendFailed(RuntimeError): self.can_retry = can_retry -def cs_error(msg, code=Codes.UNKNOWN, **kwargs): +def cs_error(msg, code=Codes.UNKNOWN, softLogout=False, **kwargs): """ Utility method for constructing an error response for client-server interactions. @@ -394,7 +394,7 @@ def cs_error(msg, code=Codes.UNKNOWN, **kwargs): Returns: A dict representing the error response JSON. """ - err = {"error": msg, "errcode": code} + err = {"error": msg, "errcode": code, "soft_logout": softLogout} for key, value in iteritems(kwargs): err[key] = value return err diff --git a/synapse/storage/registration.py b/synapse/storage/registration.py index 13a3d5208b..d6513fd8f3 100644 --- a/synapse/storage/registration.py +++ b/synapse/storage/registration.py @@ -284,7 +284,7 @@ class RegistrationWorkerStore(SQLBaseStore): def _query_for_auth(self, txn, token): sql = ( "SELECT users.name, users.is_guest, access_tokens.id as token_id," - " access_tokens.device_id" + " access_tokens.device_id, access_tokens.expired" " FROM users" " INNER JOIN access_tokens on users.name = access_tokens.user_id" " WHERE token = ?" diff --git a/synapse/storage/schema/delta/55/add_expired_to_access_tokens.sql b/synapse/storage/schema/delta/55/add_expired_to_access_tokens.sql new file mode 100644 index 0000000000..80ca9d1e9a --- /dev/null +++ b/synapse/storage/schema/delta/55/add_expired_to_access_tokens.sql @@ -0,0 +1,16 @@ +/* Copyright 2019 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +ALTER TABLE access_tokens ADD expired SMALLINT DEFAULT 0 NOT NULL;