Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit b8b905c

Browse files
authored
Fix inconsistent behavior of get_last_client_by_ip (#10970)
Make `get_last_client_by_ip` return the same dictionary structure regardless of whether the data has been persisted to the database. This change will allow slightly cleaner type hints to be applied later on.
1 parent 6b18eb4 commit b8b905c

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

changelog.d/10970.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix inconsistent behavior of `get_last_client_by_ip` when reporting data that has not been stored in the database yet.

synapse/storage/databases/main/client_ips.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -538,15 +538,20 @@ async def get_last_client_ip_by_device(
538538
"""
539539
ret = await super().get_last_client_ip_by_device(user_id, device_id)
540540

541-
# Update what is retrieved from the database with data which is pending insertion.
541+
# Update what is retrieved from the database with data which is pending
542+
# insertion, as if it has already been stored in the database.
542543
for key in self._batch_row_update:
543-
uid, access_token, ip = key
544+
uid, _access_token, ip = key
544545
if uid == user_id:
545546
user_agent, did, last_seen = self._batch_row_update[key]
547+
548+
if did is None:
549+
# These updates don't make it to the `devices` table
550+
continue
551+
546552
if not device_id or did == device_id:
547-
ret[(user_id, device_id)] = {
553+
ret[(user_id, did)] = {
548554
"user_id": user_id,
549-
"access_token": access_token,
550555
"ip": ip,
551556
"user_agent": user_agent,
552557
"device_id": did,

tests/storage/test_client_ips.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,49 @@ def test_insert_new_client_ip_none_device_id(self):
146146
],
147147
)
148148

149+
@parameterized.expand([(False,), (True,)])
150+
def test_get_last_client_ip_by_device(self, after_persisting: bool):
151+
"""Test `get_last_client_ip_by_device` for persisted and unpersisted data"""
152+
self.reactor.advance(12345678)
153+
154+
user_id = "@user:id"
155+
device_id = "MY_DEVICE"
156+
157+
# Insert a user IP
158+
self.get_success(
159+
self.store.store_device(
160+
user_id,
161+
device_id,
162+
"display name",
163+
)
164+
)
165+
self.get_success(
166+
self.store.insert_client_ip(
167+
user_id, "access_token", "ip", "user_agent", device_id
168+
)
169+
)
170+
171+
if after_persisting:
172+
# Trigger the storage loop
173+
self.reactor.advance(10)
174+
175+
result = self.get_success(
176+
self.store.get_last_client_ip_by_device(user_id, device_id)
177+
)
178+
179+
self.assertEqual(
180+
result,
181+
{
182+
(user_id, device_id): {
183+
"user_id": user_id,
184+
"device_id": device_id,
185+
"ip": "ip",
186+
"user_agent": "user_agent",
187+
"last_seen": 12345678000,
188+
},
189+
},
190+
)
191+
149192
@parameterized.expand([(False,), (True,)])
150193
def test_get_user_ip_and_agents(self, after_persisting: bool):
151194
"""Test `get_user_ip_and_agents` for persisted and unpersisted data"""

0 commit comments

Comments
 (0)