mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-09-21 08:44:35 -04:00
Add device_id support to /login
Add a 'devices' table to the storage, as well as a 'device_id' column to refresh_tokens. Allow the client to pass a device_id, and initial_device_display_name, to /login. If login is successful, then register the device in the devices table if it wasn't known already. If no device_id was supplied, make one up. Associate the device_id with the access token and refresh token, so that we can get at it again later. Ensure that the device_id is copied from the refresh token to the access_token when the token is refreshed.
This commit is contained in:
parent
93efcb8526
commit
f863a52cea
12 changed files with 354 additions and 31 deletions
75
tests/handlers/test_device.py
Normal file
75
tests/handlers/test_device.py
Normal file
|
@ -0,0 +1,75 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
#
|
||||
# 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.
|
||||
|
||||
from twisted.internet import defer
|
||||
|
||||
from synapse.handlers.device import DeviceHandler
|
||||
from tests import unittest
|
||||
from tests.utils import setup_test_homeserver
|
||||
|
||||
|
||||
class DeviceHandlers(object):
|
||||
def __init__(self, hs):
|
||||
self.device_handler = DeviceHandler(hs)
|
||||
|
||||
|
||||
class DeviceTestCase(unittest.TestCase):
|
||||
@defer.inlineCallbacks
|
||||
def setUp(self):
|
||||
self.hs = yield setup_test_homeserver(handlers=None)
|
||||
self.hs.handlers = handlers = DeviceHandlers(self.hs)
|
||||
self.handler = handlers.device_handler
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_device_is_created_if_doesnt_exist(self):
|
||||
res = yield self.handler.check_device_registered(
|
||||
user_id="boris",
|
||||
device_id="fco",
|
||||
initial_device_display_name="display name"
|
||||
)
|
||||
self.assertEqual(res, "fco")
|
||||
|
||||
dev = yield self.handler.store.get_device("boris", "fco")
|
||||
self.assertEqual(dev["display_name"], "display name")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_device_is_preserved_if_exists(self):
|
||||
res1 = yield self.handler.check_device_registered(
|
||||
user_id="boris",
|
||||
device_id="fco",
|
||||
initial_device_display_name="display name"
|
||||
)
|
||||
self.assertEqual(res1, "fco")
|
||||
|
||||
res2 = yield self.handler.check_device_registered(
|
||||
user_id="boris",
|
||||
device_id="fco",
|
||||
initial_device_display_name="new display name"
|
||||
)
|
||||
self.assertEqual(res2, "fco")
|
||||
|
||||
dev = yield self.handler.store.get_device("boris", "fco")
|
||||
self.assertEqual(dev["display_name"], "display name")
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_device_id_is_made_up_if_unspecified(self):
|
||||
device_id = yield self.handler.check_device_registered(
|
||||
user_id="theresa",
|
||||
device_id=None,
|
||||
initial_device_display_name="display"
|
||||
)
|
||||
|
||||
dev = yield self.handler.store.get_device("theresa", device_id)
|
||||
self.assertEqual(dev["display_name"], "display")
|
|
@ -38,6 +38,7 @@ class RegistrationStoreTestCase(unittest.TestCase):
|
|||
"BcDeFgHiJkLmNoPqRsTuVwXyZa"
|
||||
]
|
||||
self.pwhash = "{xx1}123456789"
|
||||
self.device_id = "akgjhdjklgshg"
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_register(self):
|
||||
|
@ -64,13 +65,15 @@ class RegistrationStoreTestCase(unittest.TestCase):
|
|||
@defer.inlineCallbacks
|
||||
def test_add_tokens(self):
|
||||
yield self.store.register(self.user_id, self.tokens[0], self.pwhash)
|
||||
yield self.store.add_access_token_to_user(self.user_id, self.tokens[1])
|
||||
yield self.store.add_access_token_to_user(self.user_id, self.tokens[1],
|
||||
self.device_id)
|
||||
|
||||
result = yield self.store.get_user_by_access_token(self.tokens[1])
|
||||
|
||||
self.assertDictContainsSubset(
|
||||
{
|
||||
"name": self.user_id,
|
||||
"device_id": self.device_id,
|
||||
},
|
||||
result
|
||||
)
|
||||
|
@ -80,20 +83,24 @@ class RegistrationStoreTestCase(unittest.TestCase):
|
|||
@defer.inlineCallbacks
|
||||
def test_exchange_refresh_token_valid(self):
|
||||
uid = stringutils.random_string(32)
|
||||
device_id = stringutils.random_string(16)
|
||||
generator = TokenGenerator()
|
||||
last_token = generator.generate(uid)
|
||||
|
||||
self.db_pool.runQuery(
|
||||
"INSERT INTO refresh_tokens(user_id, token) VALUES(?,?)",
|
||||
(uid, last_token,))
|
||||
"INSERT INTO refresh_tokens(user_id, token, device_id) "
|
||||
"VALUES(?,?,?)",
|
||||
(uid, last_token, device_id))
|
||||
|
||||
(found_user_id, refresh_token) = yield self.store.exchange_refresh_token(
|
||||
last_token, generator.generate)
|
||||
(found_user_id, refresh_token, device_id) = \
|
||||
yield self.store.exchange_refresh_token(last_token,
|
||||
generator.generate)
|
||||
self.assertEqual(uid, found_user_id)
|
||||
|
||||
rows = yield self.db_pool.runQuery(
|
||||
"SELECT token FROM refresh_tokens WHERE user_id = ?", (uid, ))
|
||||
self.assertEqual([(refresh_token,)], rows)
|
||||
"SELECT token, device_id FROM refresh_tokens WHERE user_id = ?",
|
||||
(uid, ))
|
||||
self.assertEqual([(refresh_token, device_id)], rows)
|
||||
# We issued token 1, then exchanged it for token 2
|
||||
expected_refresh_token = u"%s-%d" % (uid, 2,)
|
||||
self.assertEqual(expected_refresh_token, refresh_token)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue