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;
|