diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py
index d5d2072436..2e138f328f 100644
--- a/synapse/handlers/auth.py
+++ b/synapse/handlers/auth.py
@@ -77,6 +77,7 @@ class AuthHandler(BaseHandler):
self.ldap_bind_password = hs.config.ldap_bind_password
self.hs = hs # FIXME better possibility to access registrationHandler later?
+ self.device_handler = hs.get_device_handler()
@defer.inlineCallbacks
def check_auth(self, flows, clientdict, clientip):
@@ -374,7 +375,8 @@ class AuthHandler(BaseHandler):
return self._check_password(user_id, password)
@defer.inlineCallbacks
- def get_login_tuple_for_user_id(self, user_id, device_id=None):
+ def get_login_tuple_for_user_id(self, user_id, device_id=None,
+ initial_display_name=None):
"""
Gets login tuple for the user with the given user ID.
@@ -383,9 +385,15 @@ class AuthHandler(BaseHandler):
The user is assumed to have been authenticated by some other
machanism (e.g. CAS), and the user_id converted to the canonical case.
+ The device will be recorded in the table if it is not there already.
+
Args:
user_id (str): canonical User ID
- device_id (str): the device ID to associate with the access token
+ device_id (str|None): the device ID to associate with the tokens.
+ None to leave the tokens unassociated with a device (deprecated:
+ we should always have a device ID)
+ initial_display_name (str): display name to associate with the
+ device if it needs re-registering
Returns:
A tuple of:
The access token for the user's session.
@@ -397,6 +405,16 @@ class AuthHandler(BaseHandler):
logger.info("Logging in user %s on device %s", user_id, device_id)
access_token = yield self.issue_access_token(user_id, device_id)
refresh_token = yield self.issue_refresh_token(user_id, device_id)
+
+ # the device *should* have been registered before we got here; however,
+ # it's possible we raced against a DELETE operation. The thing we
+ # really don't want is active access_tokens without a record of the
+ # device, so we double-check it here.
+ if device_id is not None:
+ yield self.device_handler.check_device_registered(
+ user_id, device_id, initial_display_name
+ )
+
defer.returnValue((access_token, refresh_token))
@defer.inlineCallbacks
diff --git a/synapse/handlers/device.py b/synapse/handlers/device.py
index 1f9e15c33c..a7a192e1c9 100644
--- a/synapse/handlers/device.py
+++ b/synapse/handlers/device.py
@@ -100,7 +100,7 @@ class DeviceHandler(BaseHandler):
Args:
user_id (str):
- device_id (str)
+ device_id (str):
Returns:
defer.Deferred: dict[str, X]: info on the device
@@ -117,6 +117,31 @@ class DeviceHandler(BaseHandler):
_update_device_from_client_ips(device, ips)
defer.returnValue(device)
+ @defer.inlineCallbacks
+ def delete_device(self, user_id, device_id):
+ """ Delete the given device
+
+ Args:
+ user_id (str):
+ device_id (str):
+
+ Returns:
+ defer.Deferred:
+ """
+
+ try:
+ yield self.store.delete_device(user_id, device_id)
+ except errors.StoreError, e:
+ if e.code == 404:
+ # no match
+ pass
+ else:
+ raise
+
+ yield self.store.user_delete_access_tokens(user_id,
+ device_id=device_id)
+
+
def _update_device_from_client_ips(device, client_ips):
ip = client_ips.get((device["user_id"], device["device_id"]), {})
|