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

Commit c1e244c

Browse files
authored
Make cached account data/tags/admin types immutable (#16325)
1 parent 85bfd47 commit c1e244c

File tree

9 files changed

+55
-50
lines changed

9 files changed

+55
-50
lines changed

changelog.d/16325.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve type hints.

synapse/app/admin_cmd.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import os
1818
import sys
1919
import tempfile
20-
from typing import List, Mapping, Optional
20+
from typing import List, Mapping, Optional, Sequence
2121

2222
from twisted.internet import defer, task
2323

@@ -57,7 +57,7 @@
5757
from synapse.storage.databases.main.stream import StreamWorkerStore
5858
from synapse.storage.databases.main.tags import TagsWorkerStore
5959
from synapse.storage.databases.main.user_erasure_store import UserErasureWorkerStore
60-
from synapse.types import JsonDict, StateMap
60+
from synapse.types import JsonMapping, StateMap
6161
from synapse.util import SYNAPSE_VERSION
6262
from synapse.util.logcontext import LoggingContext
6363

@@ -198,15 +198,15 @@ def write_knock(
198198
for event in state.values():
199199
json.dump(event, fp=f)
200200

201-
def write_profile(self, profile: JsonDict) -> None:
201+
def write_profile(self, profile: JsonMapping) -> None:
202202
user_directory = os.path.join(self.base_directory, "user_data")
203203
os.makedirs(user_directory, exist_ok=True)
204204
profile_file = os.path.join(user_directory, "profile")
205205

206206
with open(profile_file, "a") as f:
207207
json.dump(profile, fp=f)
208208

209-
def write_devices(self, devices: List[JsonDict]) -> None:
209+
def write_devices(self, devices: Sequence[JsonMapping]) -> None:
210210
user_directory = os.path.join(self.base_directory, "user_data")
211211
os.makedirs(user_directory, exist_ok=True)
212212
device_file = os.path.join(user_directory, "devices")
@@ -215,7 +215,7 @@ def write_devices(self, devices: List[JsonDict]) -> None:
215215
with open(device_file, "a") as f:
216216
json.dump(device, fp=f)
217217

218-
def write_connections(self, connections: List[JsonDict]) -> None:
218+
def write_connections(self, connections: Sequence[JsonMapping]) -> None:
219219
user_directory = os.path.join(self.base_directory, "user_data")
220220
os.makedirs(user_directory, exist_ok=True)
221221
connection_file = os.path.join(user_directory, "connections")
@@ -225,7 +225,7 @@ def write_connections(self, connections: List[JsonDict]) -> None:
225225
json.dump(connection, fp=f)
226226

227227
def write_account_data(
228-
self, file_name: str, account_data: Mapping[str, JsonDict]
228+
self, file_name: str, account_data: Mapping[str, JsonMapping]
229229
) -> None:
230230
account_data_directory = os.path.join(
231231
self.base_directory, "user_data", "account_data"
@@ -237,7 +237,7 @@ def write_account_data(
237237
with open(account_data_file, "a") as f:
238238
json.dump(account_data, fp=f)
239239

240-
def write_media_id(self, media_id: str, media_metadata: JsonDict) -> None:
240+
def write_media_id(self, media_id: str, media_metadata: JsonMapping) -> None:
241241
file_directory = os.path.join(self.base_directory, "media_ids")
242242
os.makedirs(file_directory, exist_ok=True)
243243
media_id_file = os.path.join(file_directory, media_id)

synapse/handlers/admin.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414

1515
import abc
1616
import logging
17-
from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Set
17+
from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Sequence, Set
1818

1919
from synapse.api.constants import Direction, Membership
2020
from synapse.events import EventBase
21-
from synapse.types import JsonDict, RoomStreamToken, StateMap, UserID, UserInfo
21+
from synapse.types import JsonMapping, RoomStreamToken, StateMap, UserID, UserInfo
2222
from synapse.visibility import filter_events_for_client
2323

2424
if TYPE_CHECKING:
@@ -35,7 +35,7 @@ def __init__(self, hs: "HomeServer"):
3535
self._state_storage_controller = self._storage_controllers.state
3636
self._msc3866_enabled = hs.config.experimental.msc3866.enabled
3737

38-
async def get_whois(self, user: UserID) -> JsonDict:
38+
async def get_whois(self, user: UserID) -> JsonMapping:
3939
connections = []
4040

4141
sessions = await self._store.get_user_ip_and_agents(user)
@@ -55,7 +55,7 @@ async def get_whois(self, user: UserID) -> JsonDict:
5555

5656
return ret
5757

58-
async def get_user(self, user: UserID) -> Optional[JsonDict]:
58+
async def get_user(self, user: UserID) -> Optional[JsonMapping]:
5959
"""Function to get user details"""
6060
user_info: Optional[UserInfo] = await self._store.get_user_by_id(
6161
user.to_string()
@@ -344,7 +344,7 @@ def write_knock(
344344
raise NotImplementedError()
345345

346346
@abc.abstractmethod
347-
def write_profile(self, profile: JsonDict) -> None:
347+
def write_profile(self, profile: JsonMapping) -> None:
348348
"""Write the profile of a user.
349349
350350
Args:
@@ -353,7 +353,7 @@ def write_profile(self, profile: JsonDict) -> None:
353353
raise NotImplementedError()
354354

355355
@abc.abstractmethod
356-
def write_devices(self, devices: List[JsonDict]) -> None:
356+
def write_devices(self, devices: Sequence[JsonMapping]) -> None:
357357
"""Write the devices of a user.
358358
359359
Args:
@@ -362,7 +362,7 @@ def write_devices(self, devices: List[JsonDict]) -> None:
362362
raise NotImplementedError()
363363

364364
@abc.abstractmethod
365-
def write_connections(self, connections: List[JsonDict]) -> None:
365+
def write_connections(self, connections: Sequence[JsonMapping]) -> None:
366366
"""Write the connections of a user.
367367
368368
Args:
@@ -372,7 +372,7 @@ def write_connections(self, connections: List[JsonDict]) -> None:
372372

373373
@abc.abstractmethod
374374
def write_account_data(
375-
self, file_name: str, account_data: Mapping[str, JsonDict]
375+
self, file_name: str, account_data: Mapping[str, JsonMapping]
376376
) -> None:
377377
"""Write the account data of a user.
378378
@@ -383,7 +383,7 @@ def write_account_data(
383383
raise NotImplementedError()
384384

385385
@abc.abstractmethod
386-
def write_media_id(self, media_id: str, media_metadata: JsonDict) -> None:
386+
def write_media_id(self, media_id: str, media_metadata: JsonMapping) -> None:
387387
"""Write the media's metadata of a user.
388388
Exports only the metadata, as this can be fetched from the database via
389389
read only. In order to access the files, a connection to the correct

synapse/handlers/sync.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
from synapse.types import (
5858
DeviceListUpdates,
5959
JsonDict,
60+
JsonMapping,
6061
MutableStateMap,
6162
Requester,
6263
RoomStreamToken,
@@ -1793,19 +1794,23 @@ async def _generate_sync_entry_for_account_data(
17931794
)
17941795

17951796
if push_rules_changed:
1796-
global_account_data = dict(global_account_data)
1797-
global_account_data[
1798-
AccountDataTypes.PUSH_RULES
1799-
] = await self._push_rules_handler.push_rules_for_user(sync_config.user)
1797+
global_account_data = {
1798+
AccountDataTypes.PUSH_RULES: await self._push_rules_handler.push_rules_for_user(
1799+
sync_config.user
1800+
),
1801+
**global_account_data,
1802+
}
18001803
else:
18011804
all_global_account_data = await self.store.get_global_account_data_for_user(
18021805
user_id
18031806
)
18041807

1805-
global_account_data = dict(all_global_account_data)
1806-
global_account_data[
1807-
AccountDataTypes.PUSH_RULES
1808-
] = await self._push_rules_handler.push_rules_for_user(sync_config.user)
1808+
global_account_data = {
1809+
AccountDataTypes.PUSH_RULES: await self._push_rules_handler.push_rules_for_user(
1810+
sync_config.user
1811+
),
1812+
**all_global_account_data,
1813+
}
18091814

18101815
account_data_for_user = (
18111816
await sync_config.filter_collection.filter_global_account_data(
@@ -1909,7 +1914,7 @@ async def _generate_sync_entry_for_rooms(
19091914
blocks_all_rooms
19101915
or sync_result_builder.sync_config.filter_collection.blocks_all_room_account_data()
19111916
):
1912-
account_data_by_room: Mapping[str, Mapping[str, JsonDict]] = {}
1917+
account_data_by_room: Mapping[str, Mapping[str, JsonMapping]] = {}
19131918
elif since_token and not sync_result_builder.full_state:
19141919
account_data_by_room = (
19151920
await self.store.get_updated_room_account_data_for_user(
@@ -2349,8 +2354,8 @@ async def _generate_room_entry(
23492354
sync_result_builder: "SyncResultBuilder",
23502355
room_builder: "RoomSyncResultBuilder",
23512356
ephemeral: List[JsonDict],
2352-
tags: Optional[Mapping[str, Mapping[str, Any]]],
2353-
account_data: Mapping[str, JsonDict],
2357+
tags: Optional[Mapping[str, JsonMapping]],
2358+
account_data: Mapping[str, JsonMapping],
23542359
always_include: bool = False,
23552360
) -> None:
23562361
"""Populates the `joined` and `archived` section of `sync_result_builder`

synapse/rest/admin/users.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from synapse.rest.client._base import client_patterns
4040
from synapse.storage.databases.main.registration import ExternalIDReuseException
4141
from synapse.storage.databases.main.stats import UserSortOrder
42-
from synapse.types import JsonDict, UserID
42+
from synapse.types import JsonDict, JsonMapping, UserID
4343

4444
if TYPE_CHECKING:
4545
from synapse.server import HomeServer
@@ -211,7 +211,7 @@ def __init__(self, hs: "HomeServer"):
211211

212212
async def on_GET(
213213
self, request: SynapseRequest, user_id: str
214-
) -> Tuple[int, JsonDict]:
214+
) -> Tuple[int, JsonMapping]:
215215
await assert_requester_is_admin(self.auth, request)
216216

217217
target_user = UserID.from_string(user_id)
@@ -226,7 +226,7 @@ async def on_GET(
226226

227227
async def on_PUT(
228228
self, request: SynapseRequest, user_id: str
229-
) -> Tuple[int, JsonDict]:
229+
) -> Tuple[int, JsonMapping]:
230230
requester = await self.auth.get_user_by_req(request)
231231
await assert_user_is_admin(self.auth, requester)
232232

@@ -658,7 +658,7 @@ def __init__(self, hs: "HomeServer"):
658658

659659
async def on_GET(
660660
self, request: SynapseRequest, user_id: str
661-
) -> Tuple[int, JsonDict]:
661+
) -> Tuple[int, JsonMapping]:
662662
target_user = UserID.from_string(user_id)
663663
requester = await self.auth.get_user_by_req(request)
664664

synapse/rest/client/account_data.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from synapse.http.server import HttpServer
2121
from synapse.http.servlet import RestServlet, parse_json_object_from_request
2222
from synapse.http.site import SynapseRequest
23-
from synapse.types import JsonDict, RoomID
23+
from synapse.types import JsonDict, JsonMapping, RoomID
2424

2525
from ._base import client_patterns
2626

@@ -95,7 +95,7 @@ async def on_PUT(
9595

9696
async def on_GET(
9797
self, request: SynapseRequest, user_id: str, account_data_type: str
98-
) -> Tuple[int, JsonDict]:
98+
) -> Tuple[int, JsonMapping]:
9999
requester = await self.auth.get_user_by_req(request)
100100
if user_id != requester.user.to_string():
101101
raise AuthError(403, "Cannot get account data for other users.")
@@ -106,7 +106,7 @@ async def on_GET(
106106
and account_data_type == AccountDataTypes.PUSH_RULES
107107
):
108108
account_data: Optional[
109-
JsonDict
109+
JsonMapping
110110
] = await self._push_rules_handler.push_rules_for_user(requester.user)
111111
else:
112112
account_data = await self.store.get_global_account_data_by_type_for_user(
@@ -236,7 +236,7 @@ async def on_GET(
236236
user_id: str,
237237
room_id: str,
238238
account_data_type: str,
239-
) -> Tuple[int, JsonDict]:
239+
) -> Tuple[int, JsonMapping]:
240240
requester = await self.auth.get_user_by_req(request)
241241
if user_id != requester.user.to_string():
242242
raise AuthError(403, "Cannot get account data for other users.")
@@ -253,7 +253,7 @@ async def on_GET(
253253
self._hs.config.experimental.msc4010_push_rules_account_data
254254
and account_data_type == AccountDataTypes.PUSH_RULES
255255
):
256-
account_data: Optional[JsonDict] = {}
256+
account_data: Optional[JsonMapping] = {}
257257
else:
258258
account_data = await self.store.get_account_data_for_room_and_type(
259259
user_id, room_id, account_data_type

synapse/storage/databases/main/account_data.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
MultiWriterIdGenerator,
4444
StreamIdGenerator,
4545
)
46-
from synapse.types import JsonDict
46+
from synapse.types import JsonDict, JsonMapping
4747
from synapse.util import json_encoder
4848
from synapse.util.caches.descriptors import cached
4949
from synapse.util.caches.stream_change_cache import StreamChangeCache
@@ -119,7 +119,7 @@ def get_max_account_data_stream_id(self) -> int:
119119
@cached()
120120
async def get_global_account_data_for_user(
121121
self, user_id: str
122-
) -> Mapping[str, JsonDict]:
122+
) -> Mapping[str, JsonMapping]:
123123
"""
124124
Get all the global client account_data for a user.
125125
@@ -164,7 +164,7 @@ def get_global_account_data_for_user(
164164
@cached()
165165
async def get_room_account_data_for_user(
166166
self, user_id: str
167-
) -> Mapping[str, Mapping[str, JsonDict]]:
167+
) -> Mapping[str, Mapping[str, JsonMapping]]:
168168
"""
169169
Get all of the per-room client account_data for a user.
170170
@@ -213,7 +213,7 @@ def get_room_account_data_for_user_txn(
213213
@cached(num_args=2, max_entries=5000, tree=True)
214214
async def get_global_account_data_by_type_for_user(
215215
self, user_id: str, data_type: str
216-
) -> Optional[JsonDict]:
216+
) -> Optional[JsonMapping]:
217217
"""
218218
Returns:
219219
The account data.
@@ -265,7 +265,7 @@ def get_latest_stream_id_for_global_account_data_by_type_for_user_txn(
265265
@cached(num_args=2, tree=True)
266266
async def get_account_data_for_room(
267267
self, user_id: str, room_id: str
268-
) -> Mapping[str, JsonDict]:
268+
) -> Mapping[str, JsonMapping]:
269269
"""Get all the client account_data for a user for a room.
270270
271271
Args:
@@ -296,7 +296,7 @@ def get_account_data_for_room_txn(
296296
@cached(num_args=3, max_entries=5000, tree=True)
297297
async def get_account_data_for_room_and_type(
298298
self, user_id: str, room_id: str, account_data_type: str
299-
) -> Optional[JsonDict]:
299+
) -> Optional[JsonMapping]:
300300
"""Get the client account_data of given type for a user for a room.
301301
302302
Args:
@@ -394,7 +394,7 @@ def get_updated_room_account_data_txn(
394394

395395
async def get_updated_global_account_data_for_user(
396396
self, user_id: str, stream_id: int
397-
) -> Dict[str, JsonDict]:
397+
) -> Mapping[str, JsonMapping]:
398398
"""Get all the global account_data that's changed for a user.
399399
400400
Args:

synapse/storage/databases/main/experimental_features.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import TYPE_CHECKING, Dict
15+
from typing import TYPE_CHECKING, Dict, FrozenSet
1616

1717
from synapse.storage.database import DatabasePool, LoggingDatabaseConnection
1818
from synapse.storage.databases.main import CacheInvalidationWorkerStore
19-
from synapse.types import StrCollection
2019
from synapse.util.caches.descriptors import cached
2120

2221
if TYPE_CHECKING:
@@ -34,7 +33,7 @@ def __init__(
3433
super().__init__(database, db_conn, hs)
3534

3635
@cached()
37-
async def list_enabled_features(self, user_id: str) -> StrCollection:
36+
async def list_enabled_features(self, user_id: str) -> FrozenSet[str]:
3837
"""
3938
Checks to see what features are enabled for a given user
4039
Args:
@@ -49,7 +48,7 @@ async def list_enabled_features(self, user_id: str) -> StrCollection:
4948
["feature"],
5049
)
5150

52-
return [feature["feature"] for feature in enabled]
51+
return frozenset(feature["feature"] for feature in enabled)
5352

5453
async def set_features_for_user(
5554
self,

0 commit comments

Comments
 (0)