matrix-synapse 1.142.0rc3__cp314-abi3-musllinux_1_2_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of matrix-synapse might be problematic. Click here for more details.

Files changed (1057) hide show
  1. matrix_synapse-1.142.0rc3.dist-info/AUTHORS.rst +51 -0
  2. matrix_synapse-1.142.0rc3.dist-info/LICENSE-AGPL-3.0 +661 -0
  3. matrix_synapse-1.142.0rc3.dist-info/LICENSE-COMMERCIAL +6 -0
  4. matrix_synapse-1.142.0rc3.dist-info/METADATA +375 -0
  5. matrix_synapse-1.142.0rc3.dist-info/RECORD +1057 -0
  6. matrix_synapse-1.142.0rc3.dist-info/WHEEL +4 -0
  7. matrix_synapse-1.142.0rc3.dist-info/entry_points.txt +14 -0
  8. matrix_synapse.libs/libgcc_s-2d945d6c.so.1 +0 -0
  9. synapse/__init__.py +97 -0
  10. synapse/_scripts/__init__.py +0 -0
  11. synapse/_scripts/export_signing_key.py +109 -0
  12. synapse/_scripts/generate_config.py +83 -0
  13. synapse/_scripts/generate_log_config.py +56 -0
  14. synapse/_scripts/generate_signing_key.py +55 -0
  15. synapse/_scripts/generate_workers_map.py +318 -0
  16. synapse/_scripts/hash_password.py +95 -0
  17. synapse/_scripts/move_remote_media_to_new_store.py +128 -0
  18. synapse/_scripts/register_new_matrix_user.py +374 -0
  19. synapse/_scripts/review_recent_signups.py +212 -0
  20. synapse/_scripts/synapse_port_db.py +1603 -0
  21. synapse/_scripts/synctl.py +365 -0
  22. synapse/_scripts/update_synapse_database.py +130 -0
  23. synapse/api/__init__.py +20 -0
  24. synapse/api/auth/__init__.py +207 -0
  25. synapse/api/auth/base.py +406 -0
  26. synapse/api/auth/internal.py +299 -0
  27. synapse/api/auth/mas.py +457 -0
  28. synapse/api/auth/msc3861_delegated.py +617 -0
  29. synapse/api/auth_blocking.py +144 -0
  30. synapse/api/constants.py +362 -0
  31. synapse/api/errors.py +907 -0
  32. synapse/api/filtering.py +539 -0
  33. synapse/api/presence.py +104 -0
  34. synapse/api/ratelimiting.py +482 -0
  35. synapse/api/room_versions.py +535 -0
  36. synapse/api/urls.py +119 -0
  37. synapse/app/__init__.py +60 -0
  38. synapse/app/_base.py +866 -0
  39. synapse/app/admin_cmd.py +388 -0
  40. synapse/app/appservice.py +30 -0
  41. synapse/app/client_reader.py +30 -0
  42. synapse/app/complement_fork_starter.py +206 -0
  43. synapse/app/event_creator.py +29 -0
  44. synapse/app/federation_reader.py +30 -0
  45. synapse/app/federation_sender.py +30 -0
  46. synapse/app/frontend_proxy.py +30 -0
  47. synapse/app/generic_worker.py +475 -0
  48. synapse/app/homeserver.py +504 -0
  49. synapse/app/media_repository.py +30 -0
  50. synapse/app/phone_stats_home.py +296 -0
  51. synapse/app/pusher.py +30 -0
  52. synapse/app/synchrotron.py +30 -0
  53. synapse/app/user_dir.py +31 -0
  54. synapse/appservice/__init__.py +461 -0
  55. synapse/appservice/api.py +569 -0
  56. synapse/appservice/scheduler.py +567 -0
  57. synapse/config/__init__.py +27 -0
  58. synapse/config/__main__.py +62 -0
  59. synapse/config/_base.py +1108 -0
  60. synapse/config/_base.pyi +217 -0
  61. synapse/config/_util.py +99 -0
  62. synapse/config/account_validity.py +116 -0
  63. synapse/config/api.py +141 -0
  64. synapse/config/appservice.py +210 -0
  65. synapse/config/auth.py +80 -0
  66. synapse/config/auto_accept_invites.py +43 -0
  67. synapse/config/background_updates.py +44 -0
  68. synapse/config/cache.py +231 -0
  69. synapse/config/captcha.py +90 -0
  70. synapse/config/cas.py +116 -0
  71. synapse/config/consent.py +73 -0
  72. synapse/config/database.py +184 -0
  73. synapse/config/emailconfig.py +367 -0
  74. synapse/config/experimental.py +595 -0
  75. synapse/config/federation.py +114 -0
  76. synapse/config/homeserver.py +141 -0
  77. synapse/config/jwt.py +55 -0
  78. synapse/config/key.py +447 -0
  79. synapse/config/logger.py +390 -0
  80. synapse/config/mas.py +191 -0
  81. synapse/config/matrixrtc.py +66 -0
  82. synapse/config/metrics.py +84 -0
  83. synapse/config/modules.py +40 -0
  84. synapse/config/oembed.py +185 -0
  85. synapse/config/oidc.py +509 -0
  86. synapse/config/password_auth_providers.py +82 -0
  87. synapse/config/push.py +64 -0
  88. synapse/config/ratelimiting.py +254 -0
  89. synapse/config/redis.py +74 -0
  90. synapse/config/registration.py +296 -0
  91. synapse/config/repository.py +311 -0
  92. synapse/config/retention.py +162 -0
  93. synapse/config/room.py +88 -0
  94. synapse/config/room_directory.py +165 -0
  95. synapse/config/saml2.py +251 -0
  96. synapse/config/server.py +1170 -0
  97. synapse/config/server_notices.py +84 -0
  98. synapse/config/spam_checker.py +66 -0
  99. synapse/config/sso.py +121 -0
  100. synapse/config/stats.py +54 -0
  101. synapse/config/third_party_event_rules.py +40 -0
  102. synapse/config/tls.py +192 -0
  103. synapse/config/tracer.py +71 -0
  104. synapse/config/user_directory.py +47 -0
  105. synapse/config/user_types.py +44 -0
  106. synapse/config/voip.py +59 -0
  107. synapse/config/workers.py +642 -0
  108. synapse/crypto/__init__.py +20 -0
  109. synapse/crypto/context_factory.py +278 -0
  110. synapse/crypto/event_signing.py +194 -0
  111. synapse/crypto/keyring.py +931 -0
  112. synapse/event_auth.py +1266 -0
  113. synapse/events/__init__.py +668 -0
  114. synapse/events/auto_accept_invites.py +216 -0
  115. synapse/events/builder.py +387 -0
  116. synapse/events/presence_router.py +245 -0
  117. synapse/events/snapshot.py +559 -0
  118. synapse/events/utils.py +928 -0
  119. synapse/events/validator.py +305 -0
  120. synapse/federation/__init__.py +22 -0
  121. synapse/federation/federation_base.py +383 -0
  122. synapse/federation/federation_client.py +2134 -0
  123. synapse/federation/federation_server.py +1544 -0
  124. synapse/federation/persistence.py +71 -0
  125. synapse/federation/send_queue.py +532 -0
  126. synapse/federation/sender/__init__.py +1165 -0
  127. synapse/federation/sender/per_destination_queue.py +884 -0
  128. synapse/federation/sender/transaction_manager.py +210 -0
  129. synapse/federation/transport/__init__.py +28 -0
  130. synapse/federation/transport/client.py +1201 -0
  131. synapse/federation/transport/server/__init__.py +334 -0
  132. synapse/federation/transport/server/_base.py +429 -0
  133. synapse/federation/transport/server/federation.py +912 -0
  134. synapse/federation/units.py +133 -0
  135. synapse/handlers/__init__.py +20 -0
  136. synapse/handlers/account.py +162 -0
  137. synapse/handlers/account_data.py +362 -0
  138. synapse/handlers/account_validity.py +361 -0
  139. synapse/handlers/admin.py +618 -0
  140. synapse/handlers/appservice.py +991 -0
  141. synapse/handlers/auth.py +2494 -0
  142. synapse/handlers/cas.py +413 -0
  143. synapse/handlers/deactivate_account.py +363 -0
  144. synapse/handlers/delayed_events.py +635 -0
  145. synapse/handlers/device.py +1873 -0
  146. synapse/handlers/devicemessage.py +399 -0
  147. synapse/handlers/directory.py +554 -0
  148. synapse/handlers/e2e_keys.py +1834 -0
  149. synapse/handlers/e2e_room_keys.py +455 -0
  150. synapse/handlers/event_auth.py +390 -0
  151. synapse/handlers/events.py +201 -0
  152. synapse/handlers/federation.py +2043 -0
  153. synapse/handlers/federation_event.py +2420 -0
  154. synapse/handlers/identity.py +812 -0
  155. synapse/handlers/initial_sync.py +528 -0
  156. synapse/handlers/jwt.py +120 -0
  157. synapse/handlers/message.py +2347 -0
  158. synapse/handlers/oidc.py +1803 -0
  159. synapse/handlers/pagination.py +768 -0
  160. synapse/handlers/password_policy.py +102 -0
  161. synapse/handlers/presence.py +2638 -0
  162. synapse/handlers/profile.py +655 -0
  163. synapse/handlers/push_rules.py +164 -0
  164. synapse/handlers/read_marker.py +79 -0
  165. synapse/handlers/receipts.py +351 -0
  166. synapse/handlers/register.py +1060 -0
  167. synapse/handlers/relations.py +624 -0
  168. synapse/handlers/reports.py +98 -0
  169. synapse/handlers/room.py +2447 -0
  170. synapse/handlers/room_list.py +632 -0
  171. synapse/handlers/room_member.py +2365 -0
  172. synapse/handlers/room_member_worker.py +146 -0
  173. synapse/handlers/room_policy.py +186 -0
  174. synapse/handlers/room_summary.py +1057 -0
  175. synapse/handlers/saml.py +524 -0
  176. synapse/handlers/search.py +723 -0
  177. synapse/handlers/send_email.py +209 -0
  178. synapse/handlers/set_password.py +71 -0
  179. synapse/handlers/sliding_sync/__init__.py +1701 -0
  180. synapse/handlers/sliding_sync/extensions.py +970 -0
  181. synapse/handlers/sliding_sync/room_lists.py +2266 -0
  182. synapse/handlers/sliding_sync/store.py +128 -0
  183. synapse/handlers/sso.py +1292 -0
  184. synapse/handlers/state_deltas.py +82 -0
  185. synapse/handlers/stats.py +322 -0
  186. synapse/handlers/sync.py +3109 -0
  187. synapse/handlers/thread_subscriptions.py +190 -0
  188. synapse/handlers/typing.py +606 -0
  189. synapse/handlers/ui_auth/__init__.py +48 -0
  190. synapse/handlers/ui_auth/checkers.py +332 -0
  191. synapse/handlers/user_directory.py +783 -0
  192. synapse/handlers/worker_lock.py +365 -0
  193. synapse/http/__init__.py +106 -0
  194. synapse/http/additional_resource.py +62 -0
  195. synapse/http/client.py +1360 -0
  196. synapse/http/connectproxyclient.py +309 -0
  197. synapse/http/federation/__init__.py +19 -0
  198. synapse/http/federation/matrix_federation_agent.py +490 -0
  199. synapse/http/federation/srv_resolver.py +196 -0
  200. synapse/http/federation/well_known_resolver.py +367 -0
  201. synapse/http/matrixfederationclient.py +1875 -0
  202. synapse/http/proxy.py +290 -0
  203. synapse/http/proxyagent.py +497 -0
  204. synapse/http/replicationagent.py +203 -0
  205. synapse/http/request_metrics.py +309 -0
  206. synapse/http/server.py +1114 -0
  207. synapse/http/servlet.py +1019 -0
  208. synapse/http/site.py +825 -0
  209. synapse/http/types.py +27 -0
  210. synapse/logging/__init__.py +31 -0
  211. synapse/logging/_remote.py +261 -0
  212. synapse/logging/_terse_json.py +95 -0
  213. synapse/logging/context.py +1211 -0
  214. synapse/logging/formatter.py +63 -0
  215. synapse/logging/handlers.py +99 -0
  216. synapse/logging/loggers.py +25 -0
  217. synapse/logging/opentracing.py +1132 -0
  218. synapse/logging/scopecontextmanager.py +161 -0
  219. synapse/media/_base.py +827 -0
  220. synapse/media/filepath.py +417 -0
  221. synapse/media/media_repository.py +1580 -0
  222. synapse/media/media_storage.py +704 -0
  223. synapse/media/oembed.py +277 -0
  224. synapse/media/preview_html.py +559 -0
  225. synapse/media/storage_provider.py +195 -0
  226. synapse/media/thumbnailer.py +833 -0
  227. synapse/media/url_previewer.py +875 -0
  228. synapse/metrics/__init__.py +754 -0
  229. synapse/metrics/_gc.py +219 -0
  230. synapse/metrics/_reactor_metrics.py +171 -0
  231. synapse/metrics/_types.py +38 -0
  232. synapse/metrics/background_process_metrics.py +556 -0
  233. synapse/metrics/common_usage_metrics.py +94 -0
  234. synapse/metrics/jemalloc.py +248 -0
  235. synapse/module_api/__init__.py +2154 -0
  236. synapse/module_api/callbacks/__init__.py +50 -0
  237. synapse/module_api/callbacks/account_validity_callbacks.py +106 -0
  238. synapse/module_api/callbacks/media_repository_callbacks.py +160 -0
  239. synapse/module_api/callbacks/ratelimit_callbacks.py +79 -0
  240. synapse/module_api/callbacks/spamchecker_callbacks.py +1113 -0
  241. synapse/module_api/callbacks/third_party_event_rules_callbacks.py +599 -0
  242. synapse/module_api/errors.py +42 -0
  243. synapse/notifier.py +972 -0
  244. synapse/push/__init__.py +212 -0
  245. synapse/push/bulk_push_rule_evaluator.py +637 -0
  246. synapse/push/clientformat.py +126 -0
  247. synapse/push/emailpusher.py +333 -0
  248. synapse/push/httppusher.py +564 -0
  249. synapse/push/mailer.py +1012 -0
  250. synapse/push/presentable_names.py +216 -0
  251. synapse/push/push_tools.py +114 -0
  252. synapse/push/push_types.py +141 -0
  253. synapse/push/pusher.py +87 -0
  254. synapse/push/pusherpool.py +501 -0
  255. synapse/push/rulekinds.py +33 -0
  256. synapse/py.typed +0 -0
  257. synapse/replication/__init__.py +20 -0
  258. synapse/replication/http/__init__.py +68 -0
  259. synapse/replication/http/_base.py +468 -0
  260. synapse/replication/http/account_data.py +297 -0
  261. synapse/replication/http/deactivate_account.py +81 -0
  262. synapse/replication/http/delayed_events.py +62 -0
  263. synapse/replication/http/devices.py +254 -0
  264. synapse/replication/http/federation.py +334 -0
  265. synapse/replication/http/login.py +106 -0
  266. synapse/replication/http/membership.py +364 -0
  267. synapse/replication/http/presence.py +133 -0
  268. synapse/replication/http/push.py +156 -0
  269. synapse/replication/http/register.py +172 -0
  270. synapse/replication/http/send_events.py +182 -0
  271. synapse/replication/http/state.py +82 -0
  272. synapse/replication/http/streams.py +101 -0
  273. synapse/replication/tcp/__init__.py +56 -0
  274. synapse/replication/tcp/client.py +552 -0
  275. synapse/replication/tcp/commands.py +569 -0
  276. synapse/replication/tcp/context.py +41 -0
  277. synapse/replication/tcp/external_cache.py +156 -0
  278. synapse/replication/tcp/handler.py +942 -0
  279. synapse/replication/tcp/protocol.py +608 -0
  280. synapse/replication/tcp/redis.py +509 -0
  281. synapse/replication/tcp/resource.py +348 -0
  282. synapse/replication/tcp/streams/__init__.py +96 -0
  283. synapse/replication/tcp/streams/_base.py +766 -0
  284. synapse/replication/tcp/streams/events.py +287 -0
  285. synapse/replication/tcp/streams/federation.py +92 -0
  286. synapse/replication/tcp/streams/partial_state.py +80 -0
  287. synapse/res/providers.json +29 -0
  288. synapse/res/templates/_base.html +29 -0
  289. synapse/res/templates/account_previously_renewed.html +6 -0
  290. synapse/res/templates/account_renewed.html +6 -0
  291. synapse/res/templates/add_threepid.html +8 -0
  292. synapse/res/templates/add_threepid.txt +6 -0
  293. synapse/res/templates/add_threepid_failure.html +7 -0
  294. synapse/res/templates/add_threepid_success.html +6 -0
  295. synapse/res/templates/already_in_use.html +12 -0
  296. synapse/res/templates/already_in_use.txt +10 -0
  297. synapse/res/templates/auth_success.html +21 -0
  298. synapse/res/templates/invalid_token.html +6 -0
  299. synapse/res/templates/mail-Element.css +7 -0
  300. synapse/res/templates/mail-Vector.css +7 -0
  301. synapse/res/templates/mail-expiry.css +4 -0
  302. synapse/res/templates/mail.css +156 -0
  303. synapse/res/templates/notice_expiry.html +46 -0
  304. synapse/res/templates/notice_expiry.txt +7 -0
  305. synapse/res/templates/notif.html +51 -0
  306. synapse/res/templates/notif.txt +22 -0
  307. synapse/res/templates/notif_mail.html +59 -0
  308. synapse/res/templates/notif_mail.txt +10 -0
  309. synapse/res/templates/password_reset.html +10 -0
  310. synapse/res/templates/password_reset.txt +7 -0
  311. synapse/res/templates/password_reset_confirmation.html +15 -0
  312. synapse/res/templates/password_reset_failure.html +7 -0
  313. synapse/res/templates/password_reset_success.html +6 -0
  314. synapse/res/templates/recaptcha.html +42 -0
  315. synapse/res/templates/registration.html +12 -0
  316. synapse/res/templates/registration.txt +10 -0
  317. synapse/res/templates/registration_failure.html +6 -0
  318. synapse/res/templates/registration_success.html +6 -0
  319. synapse/res/templates/registration_token.html +18 -0
  320. synapse/res/templates/room.html +33 -0
  321. synapse/res/templates/room.txt +9 -0
  322. synapse/res/templates/sso.css +129 -0
  323. synapse/res/templates/sso_account_deactivated.html +25 -0
  324. synapse/res/templates/sso_auth_account_details.html +186 -0
  325. synapse/res/templates/sso_auth_account_details.js +116 -0
  326. synapse/res/templates/sso_auth_bad_user.html +26 -0
  327. synapse/res/templates/sso_auth_confirm.html +27 -0
  328. synapse/res/templates/sso_auth_success.html +26 -0
  329. synapse/res/templates/sso_error.html +71 -0
  330. synapse/res/templates/sso_footer.html +19 -0
  331. synapse/res/templates/sso_login_idp_picker.html +60 -0
  332. synapse/res/templates/sso_new_user_consent.html +30 -0
  333. synapse/res/templates/sso_partial_profile.html +19 -0
  334. synapse/res/templates/sso_redirect_confirm.html +39 -0
  335. synapse/res/templates/style.css +33 -0
  336. synapse/res/templates/terms.html +27 -0
  337. synapse/rest/__init__.py +197 -0
  338. synapse/rest/admin/__init__.py +390 -0
  339. synapse/rest/admin/_base.py +72 -0
  340. synapse/rest/admin/background_updates.py +171 -0
  341. synapse/rest/admin/devices.py +221 -0
  342. synapse/rest/admin/event_reports.py +173 -0
  343. synapse/rest/admin/events.py +69 -0
  344. synapse/rest/admin/experimental_features.py +137 -0
  345. synapse/rest/admin/federation.py +243 -0
  346. synapse/rest/admin/media.py +540 -0
  347. synapse/rest/admin/registration_tokens.py +358 -0
  348. synapse/rest/admin/rooms.py +1061 -0
  349. synapse/rest/admin/scheduled_tasks.py +70 -0
  350. synapse/rest/admin/server_notice_servlet.py +132 -0
  351. synapse/rest/admin/statistics.py +132 -0
  352. synapse/rest/admin/username_available.py +58 -0
  353. synapse/rest/admin/users.py +1608 -0
  354. synapse/rest/client/__init__.py +20 -0
  355. synapse/rest/client/_base.py +113 -0
  356. synapse/rest/client/account.py +930 -0
  357. synapse/rest/client/account_data.py +319 -0
  358. synapse/rest/client/account_validity.py +103 -0
  359. synapse/rest/client/appservice_ping.py +125 -0
  360. synapse/rest/client/auth.py +218 -0
  361. synapse/rest/client/auth_metadata.py +122 -0
  362. synapse/rest/client/capabilities.py +121 -0
  363. synapse/rest/client/delayed_events.py +111 -0
  364. synapse/rest/client/devices.py +587 -0
  365. synapse/rest/client/directory.py +211 -0
  366. synapse/rest/client/events.py +116 -0
  367. synapse/rest/client/filter.py +112 -0
  368. synapse/rest/client/initial_sync.py +65 -0
  369. synapse/rest/client/keys.py +678 -0
  370. synapse/rest/client/knock.py +104 -0
  371. synapse/rest/client/login.py +754 -0
  372. synapse/rest/client/login_token_request.py +127 -0
  373. synapse/rest/client/logout.py +93 -0
  374. synapse/rest/client/matrixrtc.py +52 -0
  375. synapse/rest/client/media.py +286 -0
  376. synapse/rest/client/mutual_rooms.py +93 -0
  377. synapse/rest/client/notifications.py +137 -0
  378. synapse/rest/client/openid.py +109 -0
  379. synapse/rest/client/password_policy.py +69 -0
  380. synapse/rest/client/presence.py +131 -0
  381. synapse/rest/client/profile.py +291 -0
  382. synapse/rest/client/push_rule.py +331 -0
  383. synapse/rest/client/pusher.py +181 -0
  384. synapse/rest/client/read_marker.py +104 -0
  385. synapse/rest/client/receipts.py +165 -0
  386. synapse/rest/client/register.py +1067 -0
  387. synapse/rest/client/relations.py +138 -0
  388. synapse/rest/client/rendezvous.py +76 -0
  389. synapse/rest/client/reporting.py +207 -0
  390. synapse/rest/client/room.py +1669 -0
  391. synapse/rest/client/room_keys.py +426 -0
  392. synapse/rest/client/room_upgrade_rest_servlet.py +112 -0
  393. synapse/rest/client/sendtodevice.py +85 -0
  394. synapse/rest/client/sync.py +1131 -0
  395. synapse/rest/client/tags.py +129 -0
  396. synapse/rest/client/thirdparty.py +130 -0
  397. synapse/rest/client/thread_subscriptions.py +247 -0
  398. synapse/rest/client/tokenrefresh.py +52 -0
  399. synapse/rest/client/transactions.py +149 -0
  400. synapse/rest/client/user_directory.py +90 -0
  401. synapse/rest/client/versions.py +191 -0
  402. synapse/rest/client/voip.py +88 -0
  403. synapse/rest/consent/__init__.py +0 -0
  404. synapse/rest/consent/consent_resource.py +210 -0
  405. synapse/rest/health.py +38 -0
  406. synapse/rest/key/__init__.py +20 -0
  407. synapse/rest/key/v2/__init__.py +40 -0
  408. synapse/rest/key/v2/local_key_resource.py +125 -0
  409. synapse/rest/key/v2/remote_key_resource.py +302 -0
  410. synapse/rest/media/__init__.py +0 -0
  411. synapse/rest/media/config_resource.py +53 -0
  412. synapse/rest/media/create_resource.py +90 -0
  413. synapse/rest/media/download_resource.py +110 -0
  414. synapse/rest/media/media_repository_resource.py +113 -0
  415. synapse/rest/media/preview_url_resource.py +77 -0
  416. synapse/rest/media/thumbnail_resource.py +142 -0
  417. synapse/rest/media/upload_resource.py +187 -0
  418. synapse/rest/media/v1/__init__.py +39 -0
  419. synapse/rest/media/v1/_base.py +23 -0
  420. synapse/rest/media/v1/media_storage.py +23 -0
  421. synapse/rest/media/v1/storage_provider.py +23 -0
  422. synapse/rest/synapse/__init__.py +20 -0
  423. synapse/rest/synapse/client/__init__.py +93 -0
  424. synapse/rest/synapse/client/federation_whitelist.py +66 -0
  425. synapse/rest/synapse/client/jwks.py +77 -0
  426. synapse/rest/synapse/client/new_user_consent.py +115 -0
  427. synapse/rest/synapse/client/oidc/__init__.py +45 -0
  428. synapse/rest/synapse/client/oidc/backchannel_logout_resource.py +42 -0
  429. synapse/rest/synapse/client/oidc/callback_resource.py +48 -0
  430. synapse/rest/synapse/client/password_reset.py +129 -0
  431. synapse/rest/synapse/client/pick_idp.py +107 -0
  432. synapse/rest/synapse/client/pick_username.py +153 -0
  433. synapse/rest/synapse/client/rendezvous.py +58 -0
  434. synapse/rest/synapse/client/saml2/__init__.py +42 -0
  435. synapse/rest/synapse/client/saml2/metadata_resource.py +46 -0
  436. synapse/rest/synapse/client/saml2/response_resource.py +52 -0
  437. synapse/rest/synapse/client/sso_register.py +56 -0
  438. synapse/rest/synapse/client/unsubscribe.py +88 -0
  439. synapse/rest/synapse/mas/__init__.py +71 -0
  440. synapse/rest/synapse/mas/_base.py +55 -0
  441. synapse/rest/synapse/mas/devices.py +239 -0
  442. synapse/rest/synapse/mas/users.py +469 -0
  443. synapse/rest/well_known.py +148 -0
  444. synapse/server.py +1258 -0
  445. synapse/server_notices/__init__.py +0 -0
  446. synapse/server_notices/consent_server_notices.py +136 -0
  447. synapse/server_notices/resource_limits_server_notices.py +215 -0
  448. synapse/server_notices/server_notices_manager.py +388 -0
  449. synapse/server_notices/server_notices_sender.py +67 -0
  450. synapse/server_notices/worker_server_notices_sender.py +46 -0
  451. synapse/spam_checker_api/__init__.py +31 -0
  452. synapse/state/__init__.py +1022 -0
  453. synapse/state/v1.py +370 -0
  454. synapse/state/v2.py +985 -0
  455. synapse/static/client/login/index.html +47 -0
  456. synapse/static/client/login/js/jquery-3.4.1.min.js +2 -0
  457. synapse/static/client/login/js/login.js +291 -0
  458. synapse/static/client/login/spinner.gif +0 -0
  459. synapse/static/client/login/style.css +79 -0
  460. synapse/static/index.html +63 -0
  461. synapse/storage/__init__.py +43 -0
  462. synapse/storage/_base.py +245 -0
  463. synapse/storage/admin_client_config.py +26 -0
  464. synapse/storage/background_updates.py +1189 -0
  465. synapse/storage/controllers/__init__.py +57 -0
  466. synapse/storage/controllers/persist_events.py +1239 -0
  467. synapse/storage/controllers/purge_events.py +456 -0
  468. synapse/storage/controllers/state.py +954 -0
  469. synapse/storage/controllers/stats.py +119 -0
  470. synapse/storage/database.py +2720 -0
  471. synapse/storage/databases/__init__.py +175 -0
  472. synapse/storage/databases/main/__init__.py +424 -0
  473. synapse/storage/databases/main/account_data.py +1060 -0
  474. synapse/storage/databases/main/appservice.py +473 -0
  475. synapse/storage/databases/main/cache.py +911 -0
  476. synapse/storage/databases/main/censor_events.py +225 -0
  477. synapse/storage/databases/main/client_ips.py +817 -0
  478. synapse/storage/databases/main/delayed_events.py +560 -0
  479. synapse/storage/databases/main/deviceinbox.py +1272 -0
  480. synapse/storage/databases/main/devices.py +2581 -0
  481. synapse/storage/databases/main/directory.py +212 -0
  482. synapse/storage/databases/main/e2e_room_keys.py +690 -0
  483. synapse/storage/databases/main/end_to_end_keys.py +1896 -0
  484. synapse/storage/databases/main/event_federation.py +2509 -0
  485. synapse/storage/databases/main/event_push_actions.py +1937 -0
  486. synapse/storage/databases/main/events.py +3746 -0
  487. synapse/storage/databases/main/events_bg_updates.py +2910 -0
  488. synapse/storage/databases/main/events_forward_extremities.py +126 -0
  489. synapse/storage/databases/main/events_worker.py +2784 -0
  490. synapse/storage/databases/main/experimental_features.py +130 -0
  491. synapse/storage/databases/main/filtering.py +231 -0
  492. synapse/storage/databases/main/keys.py +291 -0
  493. synapse/storage/databases/main/lock.py +553 -0
  494. synapse/storage/databases/main/media_repository.py +1070 -0
  495. synapse/storage/databases/main/metrics.py +460 -0
  496. synapse/storage/databases/main/monthly_active_users.py +443 -0
  497. synapse/storage/databases/main/openid.py +61 -0
  498. synapse/storage/databases/main/presence.py +511 -0
  499. synapse/storage/databases/main/profile.py +541 -0
  500. synapse/storage/databases/main/purge_events.py +511 -0
  501. synapse/storage/databases/main/push_rule.py +972 -0
  502. synapse/storage/databases/main/pusher.py +794 -0
  503. synapse/storage/databases/main/receipts.py +1342 -0
  504. synapse/storage/databases/main/registration.py +3076 -0
  505. synapse/storage/databases/main/rejections.py +38 -0
  506. synapse/storage/databases/main/relations.py +1118 -0
  507. synapse/storage/databases/main/room.py +2781 -0
  508. synapse/storage/databases/main/roommember.py +2112 -0
  509. synapse/storage/databases/main/search.py +941 -0
  510. synapse/storage/databases/main/session.py +151 -0
  511. synapse/storage/databases/main/signatures.py +94 -0
  512. synapse/storage/databases/main/sliding_sync.py +603 -0
  513. synapse/storage/databases/main/state.py +1006 -0
  514. synapse/storage/databases/main/state_deltas.py +329 -0
  515. synapse/storage/databases/main/stats.py +791 -0
  516. synapse/storage/databases/main/stream.py +2580 -0
  517. synapse/storage/databases/main/tags.py +360 -0
  518. synapse/storage/databases/main/task_scheduler.py +225 -0
  519. synapse/storage/databases/main/thread_subscriptions.py +591 -0
  520. synapse/storage/databases/main/transactions.py +681 -0
  521. synapse/storage/databases/main/ui_auth.py +420 -0
  522. synapse/storage/databases/main/user_directory.py +1331 -0
  523. synapse/storage/databases/main/user_erasure_store.py +117 -0
  524. synapse/storage/databases/state/__init__.py +22 -0
  525. synapse/storage/databases/state/bg_updates.py +499 -0
  526. synapse/storage/databases/state/deletion.py +558 -0
  527. synapse/storage/databases/state/store.py +949 -0
  528. synapse/storage/engines/__init__.py +70 -0
  529. synapse/storage/engines/_base.py +154 -0
  530. synapse/storage/engines/postgres.py +261 -0
  531. synapse/storage/engines/sqlite.py +199 -0
  532. synapse/storage/invite_rule.py +112 -0
  533. synapse/storage/keys.py +40 -0
  534. synapse/storage/prepare_database.py +731 -0
  535. synapse/storage/push_rule.py +28 -0
  536. synapse/storage/roommember.py +89 -0
  537. synapse/storage/schema/README.md +4 -0
  538. synapse/storage/schema/__init__.py +182 -0
  539. synapse/storage/schema/common/delta/25/00background_updates.sql +40 -0
  540. synapse/storage/schema/common/delta/35/00background_updates_add_col.sql +36 -0
  541. synapse/storage/schema/common/delta/58/00background_update_ordering.sql +38 -0
  542. synapse/storage/schema/common/full_schemas/72/full.sql.postgres +8 -0
  543. synapse/storage/schema/common/full_schemas/72/full.sql.sqlite +6 -0
  544. synapse/storage/schema/common/schema_version.sql +60 -0
  545. synapse/storage/schema/main/delta/12/v12.sql +82 -0
  546. synapse/storage/schema/main/delta/13/v13.sql +38 -0
  547. synapse/storage/schema/main/delta/14/v14.sql +42 -0
  548. synapse/storage/schema/main/delta/15/appservice_txns.sql +50 -0
  549. synapse/storage/schema/main/delta/15/presence_indices.sql +2 -0
  550. synapse/storage/schema/main/delta/15/v15.sql +24 -0
  551. synapse/storage/schema/main/delta/16/events_order_index.sql +4 -0
  552. synapse/storage/schema/main/delta/16/remote_media_cache_index.sql +2 -0
  553. synapse/storage/schema/main/delta/16/remove_duplicates.sql +9 -0
  554. synapse/storage/schema/main/delta/16/room_alias_index.sql +3 -0
  555. synapse/storage/schema/main/delta/16/unique_constraints.sql +72 -0
  556. synapse/storage/schema/main/delta/16/users.sql +56 -0
  557. synapse/storage/schema/main/delta/17/drop_indexes.sql +37 -0
  558. synapse/storage/schema/main/delta/17/server_keys.sql +43 -0
  559. synapse/storage/schema/main/delta/17/user_threepids.sql +9 -0
  560. synapse/storage/schema/main/delta/18/server_keys_bigger_ints.sql +51 -0
  561. synapse/storage/schema/main/delta/19/event_index.sql +38 -0
  562. synapse/storage/schema/main/delta/20/dummy.sql +1 -0
  563. synapse/storage/schema/main/delta/20/pushers.py +93 -0
  564. synapse/storage/schema/main/delta/21/end_to_end_keys.sql +53 -0
  565. synapse/storage/schema/main/delta/21/receipts.sql +57 -0
  566. synapse/storage/schema/main/delta/22/receipts_index.sql +41 -0
  567. synapse/storage/schema/main/delta/22/user_threepids_unique.sql +19 -0
  568. synapse/storage/schema/main/delta/24/stats_reporting.sql +37 -0
  569. synapse/storage/schema/main/delta/25/fts.py +81 -0
  570. synapse/storage/schema/main/delta/25/guest_access.sql +44 -0
  571. synapse/storage/schema/main/delta/25/history_visibility.sql +44 -0
  572. synapse/storage/schema/main/delta/25/tags.sql +57 -0
  573. synapse/storage/schema/main/delta/26/account_data.sql +36 -0
  574. synapse/storage/schema/main/delta/27/account_data.sql +55 -0
  575. synapse/storage/schema/main/delta/27/forgotten_memberships.sql +45 -0
  576. synapse/storage/schema/main/delta/27/ts.py +61 -0
  577. synapse/storage/schema/main/delta/28/event_push_actions.sql +46 -0
  578. synapse/storage/schema/main/delta/28/events_room_stream.sql +39 -0
  579. synapse/storage/schema/main/delta/28/public_roms_index.sql +39 -0
  580. synapse/storage/schema/main/delta/28/receipts_user_id_index.sql +41 -0
  581. synapse/storage/schema/main/delta/28/upgrade_times.sql +40 -0
  582. synapse/storage/schema/main/delta/28/users_is_guest.sql +41 -0
  583. synapse/storage/schema/main/delta/29/push_actions.sql +54 -0
  584. synapse/storage/schema/main/delta/30/alias_creator.sql +35 -0
  585. synapse/storage/schema/main/delta/30/as_users.py +82 -0
  586. synapse/storage/schema/main/delta/30/deleted_pushers.sql +44 -0
  587. synapse/storage/schema/main/delta/30/presence_stream.sql +49 -0
  588. synapse/storage/schema/main/delta/30/public_rooms.sql +42 -0
  589. synapse/storage/schema/main/delta/30/push_rule_stream.sql +57 -0
  590. synapse/storage/schema/main/delta/30/threepid_guest_access_tokens.sql +43 -0
  591. synapse/storage/schema/main/delta/31/invites.sql +61 -0
  592. synapse/storage/schema/main/delta/31/local_media_repository_url_cache.sql +46 -0
  593. synapse/storage/schema/main/delta/31/pushers_0.py +92 -0
  594. synapse/storage/schema/main/delta/31/pushers_index.sql +41 -0
  595. synapse/storage/schema/main/delta/31/search_update.py +65 -0
  596. synapse/storage/schema/main/delta/32/events.sql +35 -0
  597. synapse/storage/schema/main/delta/32/openid.sql +9 -0
  598. synapse/storage/schema/main/delta/32/pusher_throttle.sql +42 -0
  599. synapse/storage/schema/main/delta/32/remove_indices.sql +52 -0
  600. synapse/storage/schema/main/delta/32/reports.sql +44 -0
  601. synapse/storage/schema/main/delta/33/access_tokens_device_index.sql +36 -0
  602. synapse/storage/schema/main/delta/33/devices.sql +40 -0
  603. synapse/storage/schema/main/delta/33/devices_for_e2e_keys.sql +38 -0
  604. synapse/storage/schema/main/delta/33/devices_for_e2e_keys_clear_unknown_device.sql +39 -0
  605. synapse/storage/schema/main/delta/33/event_fields.py +61 -0
  606. synapse/storage/schema/main/delta/33/remote_media_ts.py +43 -0
  607. synapse/storage/schema/main/delta/33/user_ips_index.sql +36 -0
  608. synapse/storage/schema/main/delta/34/appservice_stream.sql +42 -0
  609. synapse/storage/schema/main/delta/34/cache_stream.py +50 -0
  610. synapse/storage/schema/main/delta/34/device_inbox.sql +43 -0
  611. synapse/storage/schema/main/delta/34/push_display_name_rename.sql +39 -0
  612. synapse/storage/schema/main/delta/34/received_txn_purge.py +36 -0
  613. synapse/storage/schema/main/delta/35/contains_url.sql +36 -0
  614. synapse/storage/schema/main/delta/35/device_outbox.sql +58 -0
  615. synapse/storage/schema/main/delta/35/device_stream_id.sql +40 -0
  616. synapse/storage/schema/main/delta/35/event_push_actions_index.sql +36 -0
  617. synapse/storage/schema/main/delta/35/public_room_list_change_stream.sql +52 -0
  618. synapse/storage/schema/main/delta/35/stream_order_to_extrem.sql +56 -0
  619. synapse/storage/schema/main/delta/36/readd_public_rooms.sql +45 -0
  620. synapse/storage/schema/main/delta/37/remove_auth_idx.py +89 -0
  621. synapse/storage/schema/main/delta/37/user_threepids.sql +71 -0
  622. synapse/storage/schema/main/delta/38/postgres_fts_gist.sql +38 -0
  623. synapse/storage/schema/main/delta/39/appservice_room_list.sql +48 -0
  624. synapse/storage/schema/main/delta/39/device_federation_stream_idx.sql +35 -0
  625. synapse/storage/schema/main/delta/39/event_push_index.sql +36 -0
  626. synapse/storage/schema/main/delta/39/federation_out_position.sql +41 -0
  627. synapse/storage/schema/main/delta/39/membership_profile.sql +39 -0
  628. synapse/storage/schema/main/delta/40/current_state_idx.sql +36 -0
  629. synapse/storage/schema/main/delta/40/device_inbox.sql +40 -0
  630. synapse/storage/schema/main/delta/40/device_list_streams.sql +79 -0
  631. synapse/storage/schema/main/delta/40/event_push_summary.sql +57 -0
  632. synapse/storage/schema/main/delta/40/pushers.sql +58 -0
  633. synapse/storage/schema/main/delta/41/device_list_stream_idx.sql +36 -0
  634. synapse/storage/schema/main/delta/41/device_outbound_index.sql +35 -0
  635. synapse/storage/schema/main/delta/41/event_search_event_id_idx.sql +36 -0
  636. synapse/storage/schema/main/delta/41/ratelimit.sql +41 -0
  637. synapse/storage/schema/main/delta/42/current_state_delta.sql +48 -0
  638. synapse/storage/schema/main/delta/42/device_list_last_id.sql +52 -0
  639. synapse/storage/schema/main/delta/42/event_auth_state_only.sql +36 -0
  640. synapse/storage/schema/main/delta/42/user_dir.py +88 -0
  641. synapse/storage/schema/main/delta/43/blocked_rooms.sql +40 -0
  642. synapse/storage/schema/main/delta/43/quarantine_media.sql +36 -0
  643. synapse/storage/schema/main/delta/43/url_cache.sql +35 -0
  644. synapse/storage/schema/main/delta/43/user_share.sql +52 -0
  645. synapse/storage/schema/main/delta/44/expire_url_cache.sql +60 -0
  646. synapse/storage/schema/main/delta/45/group_server.sql +186 -0
  647. synapse/storage/schema/main/delta/45/profile_cache.sql +47 -0
  648. synapse/storage/schema/main/delta/46/drop_refresh_tokens.sql +36 -0
  649. synapse/storage/schema/main/delta/46/drop_unique_deleted_pushers.sql +54 -0
  650. synapse/storage/schema/main/delta/46/group_server.sql +51 -0
  651. synapse/storage/schema/main/delta/46/local_media_repository_url_idx.sql +43 -0
  652. synapse/storage/schema/main/delta/46/user_dir_null_room_ids.sql +54 -0
  653. synapse/storage/schema/main/delta/46/user_dir_typos.sql +43 -0
  654. synapse/storage/schema/main/delta/47/last_access_media.sql +35 -0
  655. synapse/storage/schema/main/delta/47/postgres_fts_gin.sql +36 -0
  656. synapse/storage/schema/main/delta/47/push_actions_staging.sql +47 -0
  657. synapse/storage/schema/main/delta/48/add_user_consent.sql +37 -0
  658. synapse/storage/schema/main/delta/48/add_user_ips_last_seen_index.sql +36 -0
  659. synapse/storage/schema/main/delta/48/deactivated_users.sql +44 -0
  660. synapse/storage/schema/main/delta/48/group_unique_indexes.py +67 -0
  661. synapse/storage/schema/main/delta/48/groups_joinable.sql +41 -0
  662. synapse/storage/schema/main/delta/49/add_user_consent_server_notice_sent.sql +39 -0
  663. synapse/storage/schema/main/delta/49/add_user_daily_visits.sql +40 -0
  664. synapse/storage/schema/main/delta/49/add_user_ips_last_seen_only_index.sql +36 -0
  665. synapse/storage/schema/main/delta/50/add_creation_ts_users_index.sql +38 -0
  666. synapse/storage/schema/main/delta/50/erasure_store.sql +40 -0
  667. synapse/storage/schema/main/delta/50/make_event_content_nullable.py +102 -0
  668. synapse/storage/schema/main/delta/51/e2e_room_keys.sql +58 -0
  669. synapse/storage/schema/main/delta/51/monthly_active_users.sql +46 -0
  670. synapse/storage/schema/main/delta/52/add_event_to_state_group_index.sql +38 -0
  671. synapse/storage/schema/main/delta/52/device_list_streams_unique_idx.sql +55 -0
  672. synapse/storage/schema/main/delta/52/e2e_room_keys.sql +72 -0
  673. synapse/storage/schema/main/delta/53/add_user_type_to_users.sql +38 -0
  674. synapse/storage/schema/main/delta/53/drop_sent_transactions.sql +35 -0
  675. synapse/storage/schema/main/delta/53/event_format_version.sql +35 -0
  676. synapse/storage/schema/main/delta/53/user_dir_populate.sql +49 -0
  677. synapse/storage/schema/main/delta/53/user_ips_index.sql +49 -0
  678. synapse/storage/schema/main/delta/53/user_share.sql +63 -0
  679. synapse/storage/schema/main/delta/53/user_threepid_id.sql +48 -0
  680. synapse/storage/schema/main/delta/53/users_in_public_rooms.sql +47 -0
  681. synapse/storage/schema/main/delta/54/account_validity_with_renewal.sql +49 -0
  682. synapse/storage/schema/main/delta/54/add_validity_to_server_keys.sql +42 -0
  683. synapse/storage/schema/main/delta/54/delete_forward_extremities.sql +42 -0
  684. synapse/storage/schema/main/delta/54/drop_legacy_tables.sql +49 -0
  685. synapse/storage/schema/main/delta/54/drop_presence_list.sql +35 -0
  686. synapse/storage/schema/main/delta/54/relations.sql +46 -0
  687. synapse/storage/schema/main/delta/54/stats.sql +99 -0
  688. synapse/storage/schema/main/delta/54/stats2.sql +47 -0
  689. synapse/storage/schema/main/delta/55/access_token_expiry.sql +37 -0
  690. synapse/storage/schema/main/delta/55/track_threepid_validations.sql +50 -0
  691. synapse/storage/schema/main/delta/55/users_alter_deactivated.sql +38 -0
  692. synapse/storage/schema/main/delta/56/add_spans_to_device_lists.sql +39 -0
  693. synapse/storage/schema/main/delta/56/current_state_events_membership.sql +41 -0
  694. synapse/storage/schema/main/delta/56/current_state_events_membership_mk2.sql +43 -0
  695. synapse/storage/schema/main/delta/56/delete_keys_from_deleted_backups.sql +44 -0
  696. synapse/storage/schema/main/delta/56/destinations_failure_ts.sql +44 -0
  697. synapse/storage/schema/main/delta/56/destinations_retry_interval_type.sql.postgres +18 -0
  698. synapse/storage/schema/main/delta/56/device_stream_id_insert.sql +39 -0
  699. synapse/storage/schema/main/delta/56/devices_last_seen.sql +43 -0
  700. synapse/storage/schema/main/delta/56/drop_unused_event_tables.sql +39 -0
  701. synapse/storage/schema/main/delta/56/event_expiry.sql +40 -0
  702. synapse/storage/schema/main/delta/56/event_labels.sql +49 -0
  703. synapse/storage/schema/main/delta/56/event_labels_background_update.sql +36 -0
  704. synapse/storage/schema/main/delta/56/fix_room_keys_index.sql +37 -0
  705. synapse/storage/schema/main/delta/56/hidden_devices.sql +37 -0
  706. synapse/storage/schema/main/delta/56/hidden_devices_fix.sql.sqlite +42 -0
  707. synapse/storage/schema/main/delta/56/nuke_empty_communities_from_db.sql +48 -0
  708. synapse/storage/schema/main/delta/56/public_room_list_idx.sql +35 -0
  709. synapse/storage/schema/main/delta/56/redaction_censor.sql +35 -0
  710. synapse/storage/schema/main/delta/56/redaction_censor2.sql +41 -0
  711. synapse/storage/schema/main/delta/56/redaction_censor3_fix_update.sql.postgres +25 -0
  712. synapse/storage/schema/main/delta/56/redaction_censor4.sql +35 -0
  713. synapse/storage/schema/main/delta/56/remove_tombstoned_rooms_from_directory.sql +38 -0
  714. synapse/storage/schema/main/delta/56/room_key_etag.sql +36 -0
  715. synapse/storage/schema/main/delta/56/room_membership_idx.sql +37 -0
  716. synapse/storage/schema/main/delta/56/room_retention.sql +52 -0
  717. synapse/storage/schema/main/delta/56/signing_keys.sql +75 -0
  718. synapse/storage/schema/main/delta/56/signing_keys_nonunique_signatures.sql +41 -0
  719. synapse/storage/schema/main/delta/56/stats_separated.sql +175 -0
  720. synapse/storage/schema/main/delta/56/unique_user_filter_index.py +46 -0
  721. synapse/storage/schema/main/delta/56/user_external_ids.sql +43 -0
  722. synapse/storage/schema/main/delta/56/users_in_public_rooms_idx.sql +36 -0
  723. synapse/storage/schema/main/delta/57/delete_old_current_state_events.sql +41 -0
  724. synapse/storage/schema/main/delta/57/device_list_remote_cache_stale.sql +44 -0
  725. synapse/storage/schema/main/delta/57/local_current_membership.py +111 -0
  726. synapse/storage/schema/main/delta/57/remove_sent_outbound_pokes.sql +40 -0
  727. synapse/storage/schema/main/delta/57/rooms_version_column.sql +43 -0
  728. synapse/storage/schema/main/delta/57/rooms_version_column_2.sql.postgres +35 -0
  729. synapse/storage/schema/main/delta/57/rooms_version_column_2.sql.sqlite +22 -0
  730. synapse/storage/schema/main/delta/57/rooms_version_column_3.sql.postgres +39 -0
  731. synapse/storage/schema/main/delta/57/rooms_version_column_3.sql.sqlite +23 -0
  732. synapse/storage/schema/main/delta/58/02remove_dup_outbound_pokes.sql +41 -0
  733. synapse/storage/schema/main/delta/58/03persist_ui_auth.sql +55 -0
  734. synapse/storage/schema/main/delta/58/05cache_instance.sql.postgres +30 -0
  735. synapse/storage/schema/main/delta/58/06dlols_unique_idx.py +83 -0
  736. synapse/storage/schema/main/delta/58/07add_method_to_thumbnail_constraint.sql.postgres +33 -0
  737. synapse/storage/schema/main/delta/58/07add_method_to_thumbnail_constraint.sql.sqlite +44 -0
  738. synapse/storage/schema/main/delta/58/07persist_ui_auth_ips.sql +44 -0
  739. synapse/storage/schema/main/delta/58/08_media_safe_from_quarantine.sql.postgres +18 -0
  740. synapse/storage/schema/main/delta/58/08_media_safe_from_quarantine.sql.sqlite +18 -0
  741. synapse/storage/schema/main/delta/58/09shadow_ban.sql +37 -0
  742. synapse/storage/schema/main/delta/58/10_pushrules_enabled_delete_obsolete.sql +47 -0
  743. synapse/storage/schema/main/delta/58/10drop_local_rejections_stream.sql +41 -0
  744. synapse/storage/schema/main/delta/58/10federation_pos_instance_name.sql +41 -0
  745. synapse/storage/schema/main/delta/58/11dehydration.sql +39 -0
  746. synapse/storage/schema/main/delta/58/11fallback.sql +43 -0
  747. synapse/storage/schema/main/delta/58/11user_id_seq.py +38 -0
  748. synapse/storage/schema/main/delta/58/12room_stats.sql +51 -0
  749. synapse/storage/schema/main/delta/58/13remove_presence_allow_inbound.sql +36 -0
  750. synapse/storage/schema/main/delta/58/14events_instance_name.sql +35 -0
  751. synapse/storage/schema/main/delta/58/14events_instance_name.sql.postgres +28 -0
  752. synapse/storage/schema/main/delta/58/15_catchup_destination_rooms.sql +61 -0
  753. synapse/storage/schema/main/delta/58/15unread_count.sql +45 -0
  754. synapse/storage/schema/main/delta/58/16populate_stats_process_rooms_fix.sql +41 -0
  755. synapse/storage/schema/main/delta/58/17_catchup_last_successful.sql +40 -0
  756. synapse/storage/schema/main/delta/58/18stream_positions.sql +41 -0
  757. synapse/storage/schema/main/delta/58/19instance_map.sql.postgres +25 -0
  758. synapse/storage/schema/main/delta/58/19txn_id.sql +59 -0
  759. synapse/storage/schema/main/delta/58/20instance_name_event_tables.sql +36 -0
  760. synapse/storage/schema/main/delta/58/20user_daily_visits.sql +37 -0
  761. synapse/storage/schema/main/delta/58/21as_device_stream.sql +36 -0
  762. synapse/storage/schema/main/delta/58/21drop_device_max_stream_id.sql +1 -0
  763. synapse/storage/schema/main/delta/58/22puppet_token.sql +36 -0
  764. synapse/storage/schema/main/delta/58/22users_have_local_media.sql +2 -0
  765. synapse/storage/schema/main/delta/58/23e2e_cross_signing_keys_idx.sql +36 -0
  766. synapse/storage/schema/main/delta/58/24drop_event_json_index.sql +38 -0
  767. synapse/storage/schema/main/delta/58/25user_external_ids_user_id_idx.sql +36 -0
  768. synapse/storage/schema/main/delta/58/26access_token_last_validated.sql +37 -0
  769. synapse/storage/schema/main/delta/58/27local_invites.sql +37 -0
  770. synapse/storage/schema/main/delta/58/28drop_last_used_column.sql.postgres +16 -0
  771. synapse/storage/schema/main/delta/58/28drop_last_used_column.sql.sqlite +62 -0
  772. synapse/storage/schema/main/delta/59/01ignored_user.py +85 -0
  773. synapse/storage/schema/main/delta/59/02shard_send_to_device.sql +37 -0
  774. synapse/storage/schema/main/delta/59/03shard_send_to_device_sequence.sql.postgres +25 -0
  775. synapse/storage/schema/main/delta/59/04_event_auth_chains.sql +71 -0
  776. synapse/storage/schema/main/delta/59/04_event_auth_chains.sql.postgres +16 -0
  777. synapse/storage/schema/main/delta/59/04drop_account_data.sql +36 -0
  778. synapse/storage/schema/main/delta/59/05cache_invalidation.sql +36 -0
  779. synapse/storage/schema/main/delta/59/06chain_cover_index.sql +36 -0
  780. synapse/storage/schema/main/delta/59/06shard_account_data.sql +39 -0
  781. synapse/storage/schema/main/delta/59/06shard_account_data.sql.postgres +32 -0
  782. synapse/storage/schema/main/delta/59/07shard_account_data_fix.sql +37 -0
  783. synapse/storage/schema/main/delta/59/08delete_pushers_for_deactivated_accounts.sql +39 -0
  784. synapse/storage/schema/main/delta/59/08delete_stale_pushers.sql +39 -0
  785. synapse/storage/schema/main/delta/59/09rejected_events_metadata.sql +45 -0
  786. synapse/storage/schema/main/delta/59/10delete_purged_chain_cover.sql +36 -0
  787. synapse/storage/schema/main/delta/59/11add_knock_members_to_stats.sql +39 -0
  788. synapse/storage/schema/main/delta/59/11drop_thumbnail_constraint.sql.postgres +22 -0
  789. synapse/storage/schema/main/delta/59/12account_validity_token_used_ts_ms.sql +37 -0
  790. synapse/storage/schema/main/delta/59/12presence_stream_instance.sql +37 -0
  791. synapse/storage/schema/main/delta/59/12presence_stream_instance_seq.sql.postgres +20 -0
  792. synapse/storage/schema/main/delta/59/13users_to_send_full_presence_to.sql +53 -0
  793. synapse/storage/schema/main/delta/59/14refresh_tokens.sql +53 -0
  794. synapse/storage/schema/main/delta/59/15locks.sql +56 -0
  795. synapse/storage/schema/main/delta/59/16federation_inbound_staging.sql +51 -0
  796. synapse/storage/schema/main/delta/60/01recreate_stream_ordering.sql.postgres +45 -0
  797. synapse/storage/schema/main/delta/60/02change_stream_ordering_columns.sql.postgres +30 -0
  798. synapse/storage/schema/main/delta/61/01change_appservices_txns.sql.postgres +23 -0
  799. synapse/storage/schema/main/delta/61/01insertion_event_lookups.sql +68 -0
  800. synapse/storage/schema/main/delta/61/02drop_redundant_room_depth_index.sql +37 -0
  801. synapse/storage/schema/main/delta/61/03recreate_min_depth.py +74 -0
  802. synapse/storage/schema/main/delta/62/01insertion_event_extremities.sql +43 -0
  803. synapse/storage/schema/main/delta/63/01create_registration_tokens.sql +42 -0
  804. synapse/storage/schema/main/delta/63/02delete_unlinked_email_pushers.sql +39 -0
  805. synapse/storage/schema/main/delta/63/02populate-rooms-creator.sql +36 -0
  806. synapse/storage/schema/main/delta/63/03session_store.sql +42 -0
  807. synapse/storage/schema/main/delta/63/04add_presence_stream_not_offline_index.sql +37 -0
  808. synapse/storage/schema/main/delta/64/01msc2716_chunk_to_batch_rename.sql.postgres +23 -0
  809. synapse/storage/schema/main/delta/64/01msc2716_chunk_to_batch_rename.sql.sqlite +37 -0
  810. synapse/storage/schema/main/delta/65/01msc2716_insertion_event_edges.sql +38 -0
  811. synapse/storage/schema/main/delta/65/03remove_hidden_devices_from_device_inbox.sql +41 -0
  812. synapse/storage/schema/main/delta/65/04_local_group_updates.sql +37 -0
  813. synapse/storage/schema/main/delta/65/05_remove_room_stats_historical_and_user_stats_historical.sql +38 -0
  814. synapse/storage/schema/main/delta/65/06remove_deleted_devices_from_device_inbox.sql +53 -0
  815. synapse/storage/schema/main/delta/65/07_arbitrary_relations.sql +37 -0
  816. synapse/storage/schema/main/delta/65/08_device_inbox_background_updates.sql +37 -0
  817. synapse/storage/schema/main/delta/65/10_expirable_refresh_tokens.sql +47 -0
  818. synapse/storage/schema/main/delta/65/11_devices_auth_provider_session.sql +46 -0
  819. synapse/storage/schema/main/delta/67/01drop_public_room_list_stream.sql +37 -0
  820. synapse/storage/schema/main/delta/68/01event_columns.sql +45 -0
  821. synapse/storage/schema/main/delta/68/02_msc2409_add_device_id_appservice_stream_type.sql +40 -0
  822. synapse/storage/schema/main/delta/68/03_delete_account_data_for_deactivated_accounts.sql +39 -0
  823. synapse/storage/schema/main/delta/68/04_refresh_tokens_index_next_token_id.sql +47 -0
  824. synapse/storage/schema/main/delta/68/04partial_state_rooms.sql +60 -0
  825. synapse/storage/schema/main/delta/68/05_delete_non_strings_from_event_search.sql.sqlite +22 -0
  826. synapse/storage/schema/main/delta/68/05partial_state_rooms_triggers.py +80 -0
  827. synapse/storage/schema/main/delta/68/06_msc3202_add_device_list_appservice_stream_type.sql +42 -0
  828. synapse/storage/schema/main/delta/69/01as_txn_seq.py +54 -0
  829. synapse/storage/schema/main/delta/69/01device_list_oubound_by_room.sql +57 -0
  830. synapse/storage/schema/main/delta/69/02cache_invalidation_index.sql +37 -0
  831. synapse/storage/schema/main/delta/70/01clean_table_purged_rooms.sql +39 -0
  832. synapse/storage/schema/main/delta/71/01rebuild_event_edges.sql.postgres +43 -0
  833. synapse/storage/schema/main/delta/71/01rebuild_event_edges.sql.sqlite +47 -0
  834. synapse/storage/schema/main/delta/71/01remove_noop_background_updates.sql +80 -0
  835. synapse/storage/schema/main/delta/71/02event_push_summary_unique.sql +37 -0
  836. synapse/storage/schema/main/delta/72/01add_room_type_to_state_stats.sql +38 -0
  837. synapse/storage/schema/main/delta/72/01event_push_summary_receipt.sql +54 -0
  838. synapse/storage/schema/main/delta/72/02event_push_actions_index.sql +38 -0
  839. synapse/storage/schema/main/delta/72/03bg_populate_events_columns.py +57 -0
  840. synapse/storage/schema/main/delta/72/03drop_event_reference_hashes.sql +36 -0
  841. synapse/storage/schema/main/delta/72/03remove_groups.sql +50 -0
  842. synapse/storage/schema/main/delta/72/04drop_column_application_services_state_last_txn.sql.postgres +17 -0
  843. synapse/storage/schema/main/delta/72/04drop_column_application_services_state_last_txn.sql.sqlite +40 -0
  844. synapse/storage/schema/main/delta/72/05receipts_event_stream_ordering.sql +38 -0
  845. synapse/storage/schema/main/delta/72/05remove_unstable_private_read_receipts.sql +38 -0
  846. synapse/storage/schema/main/delta/72/06add_consent_ts_to_users.sql +35 -0
  847. synapse/storage/schema/main/delta/72/06thread_notifications.sql +49 -0
  848. synapse/storage/schema/main/delta/72/07force_update_current_state_events_membership.py +67 -0
  849. synapse/storage/schema/main/delta/72/07thread_receipts.sql.postgres +30 -0
  850. synapse/storage/schema/main/delta/72/07thread_receipts.sql.sqlite +70 -0
  851. synapse/storage/schema/main/delta/72/08begin_cache_invalidation_seq_at_2.sql.postgres +23 -0
  852. synapse/storage/schema/main/delta/72/08thread_receipts.sql +39 -0
  853. synapse/storage/schema/main/delta/72/09partial_indices.sql.sqlite +56 -0
  854. synapse/storage/schema/main/delta/73/01event_failed_pull_attempts.sql +48 -0
  855. synapse/storage/schema/main/delta/73/02add_pusher_enabled.sql +35 -0
  856. synapse/storage/schema/main/delta/73/02room_id_indexes_for_purging.sql +41 -0
  857. synapse/storage/schema/main/delta/73/03pusher_device_id.sql +39 -0
  858. synapse/storage/schema/main/delta/73/03users_approved_column.sql +39 -0
  859. synapse/storage/schema/main/delta/73/04partial_join_details.sql +42 -0
  860. synapse/storage/schema/main/delta/73/04pending_device_list_updates.sql +47 -0
  861. synapse/storage/schema/main/delta/73/05old_push_actions.sql.postgres +22 -0
  862. synapse/storage/schema/main/delta/73/05old_push_actions.sql.sqlite +24 -0
  863. synapse/storage/schema/main/delta/73/06thread_notifications_thread_id_idx.sql +42 -0
  864. synapse/storage/schema/main/delta/73/08thread_receipts_non_null.sql.postgres +23 -0
  865. synapse/storage/schema/main/delta/73/08thread_receipts_non_null.sql.sqlite +76 -0
  866. synapse/storage/schema/main/delta/73/09partial_joined_via_destination.sql +37 -0
  867. synapse/storage/schema/main/delta/73/09threads_table.sql +49 -0
  868. synapse/storage/schema/main/delta/73/10_update_sqlite_fts4_tokenizer.py +71 -0
  869. synapse/storage/schema/main/delta/73/10login_tokens.sql +54 -0
  870. synapse/storage/schema/main/delta/73/11event_search_room_id_n_distinct.sql.postgres +33 -0
  871. synapse/storage/schema/main/delta/73/12refactor_device_list_outbound_pokes.sql +72 -0
  872. synapse/storage/schema/main/delta/73/13add_device_lists_index.sql +39 -0
  873. synapse/storage/schema/main/delta/73/20_un_partial_stated_room_stream.sql +51 -0
  874. synapse/storage/schema/main/delta/73/21_un_partial_stated_room_stream_seq.sql.postgres +20 -0
  875. synapse/storage/schema/main/delta/73/22_rebuild_user_dir_stats.sql +48 -0
  876. synapse/storage/schema/main/delta/73/22_un_partial_stated_event_stream.sql +53 -0
  877. synapse/storage/schema/main/delta/73/23_fix_thread_index.sql +52 -0
  878. synapse/storage/schema/main/delta/73/23_un_partial_stated_room_stream_seq.sql.postgres +20 -0
  879. synapse/storage/schema/main/delta/73/24_events_jump_to_date_index.sql +36 -0
  880. synapse/storage/schema/main/delta/73/25drop_presence.sql +36 -0
  881. synapse/storage/schema/main/delta/74/01_user_directory_stale_remote_users.sql +58 -0
  882. synapse/storage/schema/main/delta/74/02_set_device_id_for_pushers_bg_update.sql +38 -0
  883. synapse/storage/schema/main/delta/74/03_membership_tables_event_stream_ordering.sql.postgres +29 -0
  884. synapse/storage/schema/main/delta/74/03_membership_tables_event_stream_ordering.sql.sqlite +23 -0
  885. synapse/storage/schema/main/delta/74/03_room_membership_index.sql +38 -0
  886. synapse/storage/schema/main/delta/74/04_delete_e2e_backup_keys_for_deactivated_users.sql +36 -0
  887. synapse/storage/schema/main/delta/74/04_membership_tables_event_stream_ordering_triggers.py +87 -0
  888. synapse/storage/schema/main/delta/74/05_events_txn_id_device_id.sql +72 -0
  889. synapse/storage/schema/main/delta/74/90COMMENTS_destinations.sql.postgres +52 -0
  890. synapse/storage/schema/main/delta/76/01_add_profiles_full_user_id_column.sql +39 -0
  891. synapse/storage/schema/main/delta/76/02_add_user_filters_full_user_id_column.sql +39 -0
  892. synapse/storage/schema/main/delta/76/03_per_user_experimental_features.sql +46 -0
  893. synapse/storage/schema/main/delta/76/04_add_room_forgetter.sql +43 -0
  894. synapse/storage/schema/main/delta/77/01_add_profiles_not_valid_check.sql.postgres +16 -0
  895. synapse/storage/schema/main/delta/77/02_add_user_filters_not_valid_check.sql.postgres +16 -0
  896. synapse/storage/schema/main/delta/77/03bg_populate_full_user_id_profiles.sql +35 -0
  897. synapse/storage/schema/main/delta/77/04bg_populate_full_user_id_user_filters.sql +35 -0
  898. synapse/storage/schema/main/delta/77/05thread_notifications_backfill.sql +67 -0
  899. synapse/storage/schema/main/delta/77/06thread_notifications_not_null.sql.sqlite +102 -0
  900. synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_actions.sql.postgres +27 -0
  901. synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_actions_staging.sql.postgres +27 -0
  902. synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_summary.sql.postgres +29 -0
  903. synapse/storage/schema/main/delta/77/14bg_indices_event_stream_ordering.sql +39 -0
  904. synapse/storage/schema/main/delta/78/01_validate_and_update_profiles.py +99 -0
  905. synapse/storage/schema/main/delta/78/02_validate_and_update_user_filters.py +100 -0
  906. synapse/storage/schema/main/delta/78/03_remove_unused_indexes_user_filters.py +72 -0
  907. synapse/storage/schema/main/delta/78/03event_extremities_constraints.py +65 -0
  908. synapse/storage/schema/main/delta/78/04_add_full_user_id_index_user_filters.py +32 -0
  909. synapse/storage/schema/main/delta/79/03_read_write_locks_triggers.sql.postgres +102 -0
  910. synapse/storage/schema/main/delta/79/03_read_write_locks_triggers.sql.sqlite +72 -0
  911. synapse/storage/schema/main/delta/79/04_mitigate_stream_ordering_update_race.py +70 -0
  912. synapse/storage/schema/main/delta/79/05_read_write_locks_triggers.sql.postgres +69 -0
  913. synapse/storage/schema/main/delta/79/05_read_write_locks_triggers.sql.sqlite +65 -0
  914. synapse/storage/schema/main/delta/80/01_users_alter_locked.sql +35 -0
  915. synapse/storage/schema/main/delta/80/02_read_write_locks_unlogged.sql.postgres +30 -0
  916. synapse/storage/schema/main/delta/80/02_scheduled_tasks.sql +47 -0
  917. synapse/storage/schema/main/delta/80/03_read_write_locks_triggers.sql.postgres +37 -0
  918. synapse/storage/schema/main/delta/80/04_read_write_locks_deadlock.sql.postgres +71 -0
  919. synapse/storage/schema/main/delta/82/02_scheduled_tasks_index.sql +35 -0
  920. synapse/storage/schema/main/delta/82/04_add_indices_for_purging_rooms.sql +39 -0
  921. synapse/storage/schema/main/delta/82/05gaps.sql +44 -0
  922. synapse/storage/schema/main/delta/83/01_drop_old_tables.sql +43 -0
  923. synapse/storage/schema/main/delta/83/03_instance_name_receipts.sql.sqlite +17 -0
  924. synapse/storage/schema/main/delta/83/05_cross_signing_key_update_grant.sql +34 -0
  925. synapse/storage/schema/main/delta/83/06_event_push_summary_room.sql +36 -0
  926. synapse/storage/schema/main/delta/84/01_auth_links_stats.sql.postgres +20 -0
  927. synapse/storage/schema/main/delta/84/02_auth_links_index.sql +16 -0
  928. synapse/storage/schema/main/delta/84/03_auth_links_analyze.sql.postgres +16 -0
  929. synapse/storage/schema/main/delta/84/04_access_token_index.sql +15 -0
  930. synapse/storage/schema/main/delta/85/01_add_suspended.sql +14 -0
  931. synapse/storage/schema/main/delta/85/02_add_instance_names.sql +27 -0
  932. synapse/storage/schema/main/delta/85/03_new_sequences.sql.postgres +54 -0
  933. synapse/storage/schema/main/delta/85/04_cleanup_device_federation_outbox.sql +15 -0
  934. synapse/storage/schema/main/delta/85/05_add_instance_names_converted_pos.sql +16 -0
  935. synapse/storage/schema/main/delta/85/06_add_room_reports.sql +20 -0
  936. synapse/storage/schema/main/delta/86/01_authenticate_media.sql +15 -0
  937. synapse/storage/schema/main/delta/86/02_receipts_event_id_index.sql +15 -0
  938. synapse/storage/schema/main/delta/87/01_sliding_sync_memberships.sql +169 -0
  939. synapse/storage/schema/main/delta/87/02_per_connection_state.sql +81 -0
  940. synapse/storage/schema/main/delta/87/03_current_state_index.sql +19 -0
  941. synapse/storage/schema/main/delta/88/01_add_delayed_events.sql +43 -0
  942. synapse/storage/schema/main/delta/88/01_custom_profile_fields.sql +15 -0
  943. synapse/storage/schema/main/delta/88/02_fix_sliding_sync_membership_snapshots_forgotten_column.sql +21 -0
  944. synapse/storage/schema/main/delta/88/03_add_otk_ts_added_index.sql +18 -0
  945. synapse/storage/schema/main/delta/88/04_current_state_delta_index.sql +18 -0
  946. synapse/storage/schema/main/delta/88/05_drop_old_otks.sql.postgres +19 -0
  947. synapse/storage/schema/main/delta/88/05_drop_old_otks.sql.sqlite +19 -0
  948. synapse/storage/schema/main/delta/88/05_sliding_sync_room_config_index.sql +20 -0
  949. synapse/storage/schema/main/delta/88/06_events_received_ts_index.sql +17 -0
  950. synapse/storage/schema/main/delta/89/01_sliding_sync_membership_snapshot_index.sql +15 -0
  951. synapse/storage/schema/main/delta/90/01_add_column_participant_room_memberships_table.sql +16 -0
  952. synapse/storage/schema/main/delta/91/01_media_hash.sql +28 -0
  953. synapse/storage/schema/main/delta/92/01_remove_trigger.sql.postgres +16 -0
  954. synapse/storage/schema/main/delta/92/01_remove_trigger.sql.sqlite +16 -0
  955. synapse/storage/schema/main/delta/92/02_remove_populate_participant_bg_update.sql +17 -0
  956. synapse/storage/schema/main/delta/92/04_ss_membership_snapshot_idx.sql +16 -0
  957. synapse/storage/schema/main/delta/92/04_thread_subscriptions.sql +59 -0
  958. synapse/storage/schema/main/delta/92/04_thread_subscriptions_seq.sql.postgres +19 -0
  959. synapse/storage/schema/main/delta/92/05_fixup_max_depth_cap.sql +17 -0
  960. synapse/storage/schema/main/delta/92/05_thread_subscriptions_comments.sql.postgres +18 -0
  961. synapse/storage/schema/main/delta/92/06_device_federation_inbox_index.sql +16 -0
  962. synapse/storage/schema/main/delta/92/06_threads_last_sent_stream_ordering_comments.sql.postgres +24 -0
  963. synapse/storage/schema/main/delta/92/07_add_user_reports.sql +22 -0
  964. synapse/storage/schema/main/delta/92/07_event_txn_id_device_id_txn_id2.sql +15 -0
  965. synapse/storage/schema/main/delta/92/08_room_ban_redactions.sql +21 -0
  966. synapse/storage/schema/main/delta/92/08_thread_subscriptions_seq_fixup.sql.postgres +19 -0
  967. synapse/storage/schema/main/delta/92/09_thread_subscriptions_update.sql +20 -0
  968. synapse/storage/schema/main/delta/92/09_thread_subscriptions_update.sql.postgres +18 -0
  969. synapse/storage/schema/main/full_schemas/72/full.sql.postgres +1344 -0
  970. synapse/storage/schema/main/full_schemas/72/full.sql.sqlite +646 -0
  971. synapse/storage/schema/state/delta/23/drop_state_index.sql +35 -0
  972. synapse/storage/schema/state/delta/32/remove_state_indices.sql +38 -0
  973. synapse/storage/schema/state/delta/35/add_state_index.sql +36 -0
  974. synapse/storage/schema/state/delta/35/state.sql +41 -0
  975. synapse/storage/schema/state/delta/35/state_dedupe.sql +36 -0
  976. synapse/storage/schema/state/delta/47/state_group_seq.py +38 -0
  977. synapse/storage/schema/state/delta/56/state_group_room_idx.sql +36 -0
  978. synapse/storage/schema/state/delta/61/02state_groups_state_n_distinct.sql.postgres +34 -0
  979. synapse/storage/schema/state/delta/70/08_state_group_edges_unique.sql +36 -0
  980. synapse/storage/schema/state/delta/89/01_state_groups_deletion.sql +39 -0
  981. synapse/storage/schema/state/delta/90/02_delete_unreferenced_state_groups.sql +16 -0
  982. synapse/storage/schema/state/delta/90/03_remove_old_deletion_bg_update.sql +15 -0
  983. synapse/storage/schema/state/full_schemas/72/full.sql.postgres +30 -0
  984. synapse/storage/schema/state/full_schemas/72/full.sql.sqlite +20 -0
  985. synapse/storage/types.py +185 -0
  986. synapse/storage/util/__init__.py +20 -0
  987. synapse/storage/util/id_generators.py +909 -0
  988. synapse/storage/util/partial_state_events_tracker.py +194 -0
  989. synapse/storage/util/sequence.py +315 -0
  990. synapse/streams/__init__.py +43 -0
  991. synapse/streams/config.py +92 -0
  992. synapse/streams/events.py +203 -0
  993. synapse/synapse_rust/__init__.pyi +3 -0
  994. synapse/synapse_rust/acl.pyi +20 -0
  995. synapse/synapse_rust/events.pyi +136 -0
  996. synapse/synapse_rust/http_client.pyi +32 -0
  997. synapse/synapse_rust/push.pyi +86 -0
  998. synapse/synapse_rust/rendezvous.pyi +30 -0
  999. synapse/synapse_rust/segmenter.pyi +1 -0
  1000. synapse/synapse_rust.abi3.so +0 -0
  1001. synapse/types/__init__.py +1600 -0
  1002. synapse/types/handlers/__init__.py +93 -0
  1003. synapse/types/handlers/policy_server.py +16 -0
  1004. synapse/types/handlers/sliding_sync.py +909 -0
  1005. synapse/types/rest/__init__.py +25 -0
  1006. synapse/types/rest/client/__init__.py +415 -0
  1007. synapse/types/state.py +635 -0
  1008. synapse/types/storage/__init__.py +66 -0
  1009. synapse/util/__init__.py +170 -0
  1010. synapse/util/async_helpers.py +1067 -0
  1011. synapse/util/batching_queue.py +202 -0
  1012. synapse/util/caches/__init__.py +300 -0
  1013. synapse/util/caches/cached_call.py +143 -0
  1014. synapse/util/caches/deferred_cache.py +530 -0
  1015. synapse/util/caches/descriptors.py +694 -0
  1016. synapse/util/caches/dictionary_cache.py +350 -0
  1017. synapse/util/caches/expiringcache.py +251 -0
  1018. synapse/util/caches/lrucache.py +977 -0
  1019. synapse/util/caches/response_cache.py +323 -0
  1020. synapse/util/caches/stream_change_cache.py +370 -0
  1021. synapse/util/caches/treecache.py +189 -0
  1022. synapse/util/caches/ttlcache.py +197 -0
  1023. synapse/util/cancellation.py +63 -0
  1024. synapse/util/check_dependencies.py +335 -0
  1025. synapse/util/clock.py +500 -0
  1026. synapse/util/constants.py +22 -0
  1027. synapse/util/daemonize.py +165 -0
  1028. synapse/util/distributor.py +159 -0
  1029. synapse/util/events.py +134 -0
  1030. synapse/util/file_consumer.py +164 -0
  1031. synapse/util/frozenutils.py +57 -0
  1032. synapse/util/gai_resolver.py +180 -0
  1033. synapse/util/hash.py +38 -0
  1034. synapse/util/httpresourcetree.py +108 -0
  1035. synapse/util/iterutils.py +189 -0
  1036. synapse/util/json.py +56 -0
  1037. synapse/util/linked_list.py +156 -0
  1038. synapse/util/logcontext.py +46 -0
  1039. synapse/util/logformatter.py +28 -0
  1040. synapse/util/macaroons.py +325 -0
  1041. synapse/util/manhole.py +191 -0
  1042. synapse/util/metrics.py +340 -0
  1043. synapse/util/module_loader.py +116 -0
  1044. synapse/util/msisdn.py +51 -0
  1045. synapse/util/patch_inline_callbacks.py +250 -0
  1046. synapse/util/pydantic_models.py +56 -0
  1047. synapse/util/ratelimitutils.py +420 -0
  1048. synapse/util/retryutils.py +339 -0
  1049. synapse/util/rlimit.py +42 -0
  1050. synapse/util/rust.py +134 -0
  1051. synapse/util/sentinel.py +21 -0
  1052. synapse/util/stringutils.py +293 -0
  1053. synapse/util/task_scheduler.py +493 -0
  1054. synapse/util/templates.py +126 -0
  1055. synapse/util/threepids.py +123 -0
  1056. synapse/util/wheel_timer.py +112 -0
  1057. synapse/visibility.py +836 -0
@@ -0,0 +1,1701 @@
1
+ #
2
+ # This file is licensed under the Affero General Public License (AGPL) version 3.
3
+ #
4
+ # Copyright (C) 2023 New Vector, Ltd
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as
8
+ # published by the Free Software Foundation, either version 3 of the
9
+ # License, or (at your option) any later version.
10
+ #
11
+ # See the GNU Affero General Public License for more details:
12
+ # <https://www.gnu.org/licenses/agpl-3.0.html>.
13
+ #
14
+
15
+ import itertools
16
+ import logging
17
+ from itertools import chain
18
+ from typing import TYPE_CHECKING, AbstractSet, Mapping, Optional
19
+
20
+ from prometheus_client import Histogram
21
+ from typing_extensions import assert_never
22
+
23
+ from synapse.api.constants import Direction, EventTypes, Membership
24
+ from synapse.events import EventBase
25
+ from synapse.events.utils import strip_event
26
+ from synapse.handlers.relations import BundledAggregations
27
+ from synapse.handlers.sliding_sync.extensions import SlidingSyncExtensionHandler
28
+ from synapse.handlers.sliding_sync.room_lists import (
29
+ RoomsForUserType,
30
+ SlidingSyncRoomLists,
31
+ )
32
+ from synapse.handlers.sliding_sync.store import SlidingSyncConnectionStore
33
+ from synapse.logging.opentracing import (
34
+ SynapseTags,
35
+ log_kv,
36
+ set_tag,
37
+ start_active_span,
38
+ tag_args,
39
+ trace,
40
+ )
41
+ from synapse.metrics import SERVER_NAME_LABEL
42
+ from synapse.storage.databases.main.roommember import extract_heroes_from_room_summary
43
+ from synapse.storage.databases.main.state_deltas import StateDelta
44
+ from synapse.storage.databases.main.stream import PaginateFunction
45
+ from synapse.storage.roommember import (
46
+ MemberSummary,
47
+ )
48
+ from synapse.types import (
49
+ JsonDict,
50
+ MutableStateMap,
51
+ PersistedEventPosition,
52
+ Requester,
53
+ RoomStreamToken,
54
+ SlidingSyncStreamToken,
55
+ StateMap,
56
+ StrCollection,
57
+ StreamKeyType,
58
+ StreamToken,
59
+ )
60
+ from synapse.types.handlers import SLIDING_SYNC_DEFAULT_BUMP_EVENT_TYPES
61
+ from synapse.types.handlers.sliding_sync import (
62
+ HaveSentRoomFlag,
63
+ MutablePerConnectionState,
64
+ PerConnectionState,
65
+ RoomSyncConfig,
66
+ SlidingSyncConfig,
67
+ SlidingSyncResult,
68
+ StateValues,
69
+ )
70
+ from synapse.types.state import StateFilter
71
+ from synapse.util.async_helpers import concurrently_execute
72
+ from synapse.visibility import filter_events_for_client
73
+
74
+ if TYPE_CHECKING:
75
+ from synapse.server import HomeServer
76
+
77
+ logger = logging.getLogger(__name__)
78
+
79
+
80
+ sync_processing_time = Histogram(
81
+ "synapse_sliding_sync_processing_time",
82
+ "Time taken to generate a sliding sync response, ignoring wait times.",
83
+ labelnames=["initial", SERVER_NAME_LABEL],
84
+ )
85
+
86
+ # Limit the number of state_keys we should remember sending down the connection for each
87
+ # (room_id, user_id). We don't want to store and pull out too much data in the database.
88
+ #
89
+ # 100 is an arbitrary but small-ish number. The idea is that we probably won't send down
90
+ # too many redundant member state events (that the client already knows about) for a
91
+ # given ongoing conversation if we keep 100 around. Most rooms don't have 100 members
92
+ # anyway and it takes a while to cycle through 100 members.
93
+ MAX_NUMBER_PREVIOUS_STATE_KEYS_TO_REMEMBER = 100
94
+
95
+
96
+ class SlidingSyncHandler:
97
+ def __init__(self, hs: "HomeServer"):
98
+ self.server_name = hs.hostname
99
+ self.clock = hs.get_clock()
100
+ self.store = hs.get_datastores().main
101
+ self.storage_controllers = hs.get_storage_controllers()
102
+ self.auth_blocking = hs.get_auth_blocking()
103
+ self.notifier = hs.get_notifier()
104
+ self.event_sources = hs.get_event_sources()
105
+ self.relations_handler = hs.get_relations_handler()
106
+ self.rooms_to_exclude_globally = hs.config.server.rooms_to_exclude_from_sync
107
+ self.is_mine_id = hs.is_mine_id
108
+
109
+ self.connection_store = SlidingSyncConnectionStore(self.store)
110
+ self.extensions = SlidingSyncExtensionHandler(hs)
111
+ self.room_lists = SlidingSyncRoomLists(hs)
112
+
113
+ async def wait_for_sync_for_user(
114
+ self,
115
+ requester: Requester,
116
+ sync_config: SlidingSyncConfig,
117
+ from_token: Optional[SlidingSyncStreamToken] = None,
118
+ timeout_ms: int = 0,
119
+ ) -> tuple[SlidingSyncResult, bool]:
120
+ """
121
+ Get the sync for a client if we have new data for it now. Otherwise
122
+ wait for new data to arrive on the server. If the timeout expires, then
123
+ return an empty sync result.
124
+
125
+ Args:
126
+ requester: The user making the request
127
+ sync_config: Sync configuration
128
+ from_token: The point in the stream to sync from. Token of the end of the
129
+ previous batch. May be `None` if this is the initial sync request.
130
+ timeout_ms: The time in milliseconds to wait for new data to arrive. If 0,
131
+ we will respond immediately but there might not be any new data so we just
132
+ return an empty response.
133
+
134
+ Returns:
135
+ A tuple containing the `SlidingSyncResult` and whether we waited for new
136
+ activity before responding. Knowing whether we waited is useful in traces
137
+ to filter out long-running requests where we were just waiting.
138
+ """
139
+ did_wait = False
140
+
141
+ # If the user is not part of the mau group, then check that limits have
142
+ # not been exceeded (if not part of the group by this point, almost certain
143
+ # auth_blocking will occur)
144
+ await self.auth_blocking.check_auth_blocking(requester=requester)
145
+
146
+ # If we're working with a user-provided token, we need to make sure to wait for
147
+ # this worker to catch up with the token so we don't skip past any incoming
148
+ # events or future events if the user is nefariously, manually modifying the
149
+ # token.
150
+ if from_token is not None:
151
+ # We need to make sure this worker has caught up with the token. If
152
+ # this returns false, it means we timed out waiting, and we should
153
+ # just return an empty response.
154
+ before_wait_ts = self.clock.time_msec()
155
+ if not await self.notifier.wait_for_stream_token(from_token.stream_token):
156
+ logger.warning(
157
+ "Timed out waiting for worker to catch up. Returning empty response"
158
+ )
159
+ return SlidingSyncResult.empty(from_token), did_wait
160
+
161
+ # If we've spent significant time waiting to catch up, take it off
162
+ # the timeout.
163
+ after_wait_ts = self.clock.time_msec()
164
+ if after_wait_ts - before_wait_ts > 1_000:
165
+ timeout_ms -= after_wait_ts - before_wait_ts
166
+ timeout_ms = max(timeout_ms, 0)
167
+
168
+ # We're going to respond immediately if the timeout is 0 or if this is an
169
+ # initial sync (without a `from_token`) so we can avoid calling
170
+ # `notifier.wait_for_events()`.
171
+ if timeout_ms == 0 or from_token is None:
172
+ now_token = self.event_sources.get_current_token()
173
+ result = await self.current_sync_for_user(
174
+ sync_config,
175
+ from_token=from_token,
176
+ to_token=now_token,
177
+ )
178
+ else:
179
+ # Otherwise, we wait for something to happen and report it to the user.
180
+ async def current_sync_callback(
181
+ before_token: StreamToken, after_token: StreamToken
182
+ ) -> SlidingSyncResult:
183
+ return await self.current_sync_for_user(
184
+ sync_config,
185
+ from_token=from_token,
186
+ to_token=after_token,
187
+ )
188
+
189
+ result = await self.notifier.wait_for_events(
190
+ sync_config.user.to_string(),
191
+ timeout_ms,
192
+ current_sync_callback,
193
+ from_token=from_token.stream_token,
194
+ )
195
+ did_wait = True
196
+
197
+ return result, did_wait
198
+
199
+ @trace
200
+ async def current_sync_for_user(
201
+ self,
202
+ sync_config: SlidingSyncConfig,
203
+ to_token: StreamToken,
204
+ from_token: Optional[SlidingSyncStreamToken] = None,
205
+ ) -> SlidingSyncResult:
206
+ """
207
+ Generates the response body of a Sliding Sync result, represented as a
208
+ `SlidingSyncResult`.
209
+
210
+ We fetch data according to the token range (> `from_token` and <= `to_token`).
211
+
212
+ Args:
213
+ sync_config: Sync configuration
214
+ to_token: The latest point in the stream to sync up to.
215
+ from_token: The point in the stream to sync from. Token of the end of the
216
+ previous batch. May be `None` if this is the initial sync request.
217
+ """
218
+ start_time_s = self.clock.time()
219
+
220
+ user_id = sync_config.user.to_string()
221
+ app_service = self.store.get_app_service_by_user_id(user_id)
222
+ if app_service:
223
+ # We no longer support AS users using /sync directly.
224
+ # See https://github.com/matrix-org/matrix-doc/issues/1144
225
+ raise NotImplementedError()
226
+
227
+ # Get the per-connection state (if any).
228
+ #
229
+ # Raises an exception if there is a `connection_position` that we don't
230
+ # recognize. If we don't do this and the client asks for the full range
231
+ # of rooms, we end up sending down all rooms and their state from
232
+ # scratch (which can be very slow). By expiring the connection we allow
233
+ # the client a chance to do an initial request with a smaller range of
234
+ # rooms to get them some results sooner but will end up taking the same
235
+ # amount of time (more with round-trips and re-processing) in the end to
236
+ # get everything again.
237
+ previous_connection_state = (
238
+ await self.connection_store.get_and_clear_connection_positions(
239
+ sync_config, from_token
240
+ )
241
+ )
242
+
243
+ # Get all of the room IDs that the user should be able to see in the sync
244
+ # response
245
+ has_lists = sync_config.lists is not None and len(sync_config.lists) > 0
246
+ has_room_subscriptions = (
247
+ sync_config.room_subscriptions is not None
248
+ and len(sync_config.room_subscriptions) > 0
249
+ )
250
+
251
+ interested_rooms = await self.room_lists.compute_interested_rooms(
252
+ sync_config=sync_config,
253
+ previous_connection_state=previous_connection_state,
254
+ from_token=from_token.stream_token if from_token else None,
255
+ to_token=to_token,
256
+ )
257
+
258
+ lists = interested_rooms.lists
259
+ relevant_room_map = interested_rooms.relevant_room_map
260
+ all_rooms = interested_rooms.all_rooms
261
+ room_membership_for_user_map = interested_rooms.room_membership_for_user_map
262
+ relevant_rooms_to_send_map = interested_rooms.relevant_rooms_to_send_map
263
+
264
+ # Fetch room data
265
+ rooms: dict[str, SlidingSyncResult.RoomResult] = {}
266
+
267
+ new_connection_state = previous_connection_state.get_mutable()
268
+
269
+ @trace
270
+ @tag_args
271
+ async def handle_room(room_id: str) -> None:
272
+ room_sync_result = await self.get_room_sync_data(
273
+ sync_config=sync_config,
274
+ previous_connection_state=previous_connection_state,
275
+ new_connection_state=new_connection_state,
276
+ room_id=room_id,
277
+ room_sync_config=relevant_rooms_to_send_map[room_id],
278
+ room_membership_for_user_at_to_token=room_membership_for_user_map[
279
+ room_id
280
+ ],
281
+ from_token=from_token,
282
+ to_token=to_token,
283
+ newly_joined=room_id in interested_rooms.newly_joined_rooms,
284
+ newly_left=room_id in interested_rooms.newly_left_rooms,
285
+ is_dm=room_id in interested_rooms.dm_room_ids,
286
+ )
287
+
288
+ # Filter out empty room results during incremental sync
289
+ if room_sync_result or not from_token:
290
+ rooms[room_id] = room_sync_result
291
+
292
+ if relevant_rooms_to_send_map:
293
+ with start_active_span("sliding_sync.generate_room_entries"):
294
+ await concurrently_execute(handle_room, relevant_rooms_to_send_map, 20)
295
+
296
+ extensions = await self.extensions.get_extensions_response(
297
+ sync_config=sync_config,
298
+ actual_lists=lists,
299
+ previous_connection_state=previous_connection_state,
300
+ new_connection_state=new_connection_state,
301
+ # We're purposely using `relevant_room_map` instead of
302
+ # `relevant_rooms_to_send_map` here. This needs to be all room_ids we could
303
+ # send regardless of whether they have an event update or not. The
304
+ # extensions care about more than just normal events in the rooms (like
305
+ # account data, read receipts, typing indicators, to-device messages, etc).
306
+ actual_room_ids=set(relevant_room_map.keys()),
307
+ actual_room_response_map=rooms,
308
+ from_token=from_token,
309
+ to_token=to_token,
310
+ )
311
+
312
+ if has_lists or has_room_subscriptions:
313
+ # We now calculate if any rooms outside the range have had updates,
314
+ # which we are not sending down.
315
+ #
316
+ # We *must* record rooms that have had updates, but it is also fine
317
+ # to record rooms as having updates even if there might not actually
318
+ # be anything new for the user (e.g. due to event filters, events
319
+ # having happened after the user left, etc).
320
+ if from_token:
321
+ # The set of rooms that the client (may) care about, but aren't
322
+ # in any list range (or subscribed to).
323
+ missing_rooms = all_rooms - relevant_room_map.keys()
324
+
325
+ # We now just go and try fetching any events in the above rooms
326
+ # to see if anything has happened since the `from_token`.
327
+ #
328
+ # TODO: Replace this with something faster. When we land the
329
+ # sliding sync tables that record the most recent event
330
+ # positions we can use that.
331
+ unsent_room_ids: StrCollection
332
+ if await self.store.have_finished_sliding_sync_background_jobs():
333
+ unsent_room_ids = await (
334
+ self.store.get_rooms_that_have_updates_since_sliding_sync_table(
335
+ room_ids=missing_rooms,
336
+ from_key=from_token.stream_token.room_key,
337
+ )
338
+ )
339
+ else:
340
+ missing_event_map_by_room = (
341
+ await self.store.get_room_events_stream_for_rooms(
342
+ room_ids=missing_rooms,
343
+ from_key=to_token.room_key,
344
+ to_key=from_token.stream_token.room_key,
345
+ limit=1,
346
+ )
347
+ )
348
+ unsent_room_ids = list(missing_event_map_by_room)
349
+
350
+ new_connection_state.rooms.record_unsent_rooms(
351
+ unsent_room_ids, from_token.stream_token.room_key
352
+ )
353
+
354
+ new_connection_state.rooms.record_sent_rooms(
355
+ relevant_rooms_to_send_map.keys()
356
+ )
357
+
358
+ connection_position = await self.connection_store.record_new_state(
359
+ sync_config=sync_config,
360
+ from_token=from_token,
361
+ new_connection_state=new_connection_state,
362
+ )
363
+ elif from_token:
364
+ connection_position = from_token.connection_position
365
+ else:
366
+ # Initial sync without a `from_token` starts at `0`
367
+ connection_position = 0
368
+
369
+ sliding_sync_result = SlidingSyncResult(
370
+ next_pos=SlidingSyncStreamToken(to_token, connection_position),
371
+ lists=lists,
372
+ rooms=rooms,
373
+ extensions=extensions,
374
+ )
375
+
376
+ # Make it easy to find traces for syncs that aren't empty
377
+ set_tag(SynapseTags.RESULT_PREFIX + "result", bool(sliding_sync_result))
378
+ set_tag(SynapseTags.FUNC_ARG_PREFIX + "sync_config.user", user_id)
379
+
380
+ end_time_s = self.clock.time()
381
+ sync_processing_time.labels(
382
+ initial=from_token is not None, **{SERVER_NAME_LABEL: self.server_name}
383
+ ).observe(end_time_s - start_time_s)
384
+
385
+ return sliding_sync_result
386
+
387
+ @trace
388
+ async def get_current_state_ids_at(
389
+ self,
390
+ room_id: str,
391
+ room_membership_for_user_at_to_token: RoomsForUserType,
392
+ state_filter: StateFilter,
393
+ to_token: StreamToken,
394
+ ) -> StateMap[str]:
395
+ """
396
+ Get current state IDs for the user in the room according to their membership. This
397
+ will be the current state at the time of their LEAVE/BAN, otherwise will be the
398
+ current state <= to_token.
399
+
400
+ Args:
401
+ room_id: The room ID to fetch data for
402
+ room_membership_for_user_at_token: Membership information for the user
403
+ in the room at the time of `to_token`.
404
+ to_token: The point in the stream to sync up to.
405
+ """
406
+ state_ids: StateMap[str]
407
+ # People shouldn't see past their leave/ban event
408
+ if room_membership_for_user_at_to_token.membership in (
409
+ Membership.LEAVE,
410
+ Membership.BAN,
411
+ ):
412
+ # TODO: `get_state_ids_at(...)` doesn't take into account the "current
413
+ # state". Maybe we need to use
414
+ # `get_forward_extremities_for_room_at_stream_ordering(...)` to "Fetch the
415
+ # current state at the time."
416
+ state_ids = await self.storage_controllers.state.get_state_ids_at(
417
+ room_id,
418
+ stream_position=to_token.copy_and_replace(
419
+ StreamKeyType.ROOM,
420
+ room_membership_for_user_at_to_token.event_pos.to_room_stream_token(),
421
+ ),
422
+ state_filter=state_filter,
423
+ # Partially-stated rooms should have all state events except for
424
+ # remote membership events. Since we've already excluded
425
+ # partially-stated rooms unless `required_state` only has
426
+ # `["m.room.member", "$LAZY"]` for membership, we should be able to
427
+ # retrieve everything requested. When we're lazy-loading, if there
428
+ # are some remote senders in the timeline, we should also have their
429
+ # membership event because we had to auth that timeline event. Plus
430
+ # we don't want to block the whole sync waiting for this one room.
431
+ await_full_state=False,
432
+ )
433
+ # Otherwise, we can get the latest current state in the room
434
+ else:
435
+ state_ids = await self.storage_controllers.state.get_current_state_ids(
436
+ room_id,
437
+ state_filter,
438
+ # Partially-stated rooms should have all state events except for
439
+ # remote membership events. Since we've already excluded
440
+ # partially-stated rooms unless `required_state` only has
441
+ # `["m.room.member", "$LAZY"]` for membership, we should be able to
442
+ # retrieve everything requested. When we're lazy-loading, if there
443
+ # are some remote senders in the timeline, we should also have their
444
+ # membership event because we had to auth that timeline event. Plus
445
+ # we don't want to block the whole sync waiting for this one room.
446
+ await_full_state=False,
447
+ )
448
+ # TODO: Query `current_state_delta_stream` and reverse/rewind back to the `to_token`
449
+
450
+ return state_ids
451
+
452
+ @trace
453
+ async def get_current_state_at(
454
+ self,
455
+ room_id: str,
456
+ room_membership_for_user_at_to_token: RoomsForUserType,
457
+ state_filter: StateFilter,
458
+ to_token: StreamToken,
459
+ ) -> StateMap[EventBase]:
460
+ """
461
+ Get current state for the user in the room according to their membership. This
462
+ will be the current state at the time of their LEAVE/BAN, otherwise will be the
463
+ current state <= to_token.
464
+
465
+ Args:
466
+ room_id: The room ID to fetch data for
467
+ room_membership_for_user_at_token: Membership information for the user
468
+ in the room at the time of `to_token`.
469
+ to_token: The point in the stream to sync up to.
470
+ """
471
+ state_ids = await self.get_current_state_ids_at(
472
+ room_id=room_id,
473
+ room_membership_for_user_at_to_token=room_membership_for_user_at_to_token,
474
+ state_filter=state_filter,
475
+ to_token=to_token,
476
+ )
477
+
478
+ events = await self.store.get_events_as_list(list(state_ids.values()))
479
+
480
+ state_map = {}
481
+ for event in events:
482
+ state_map[(event.type, event.state_key)] = event
483
+
484
+ return state_map
485
+
486
+ @trace
487
+ async def get_current_state_deltas_for_room(
488
+ self,
489
+ room_id: str,
490
+ room_membership_for_user_at_to_token: RoomsForUserType,
491
+ from_token: RoomStreamToken,
492
+ to_token: RoomStreamToken,
493
+ ) -> list[StateDelta]:
494
+ """
495
+ Get the state deltas between two tokens taking into account the user's
496
+ membership. If the user is LEAVE/BAN, we will only get the state deltas up to
497
+ their LEAVE/BAN event (inclusive).
498
+
499
+ (> `from_token` and <= `to_token`)
500
+ """
501
+ membership = room_membership_for_user_at_to_token.membership
502
+ # We don't know how to handle `membership` values other than these. The
503
+ # code below would need to be updated.
504
+ assert membership in (
505
+ Membership.JOIN,
506
+ Membership.INVITE,
507
+ Membership.KNOCK,
508
+ Membership.LEAVE,
509
+ Membership.BAN,
510
+ )
511
+
512
+ # People shouldn't see past their leave/ban event
513
+ if membership in (
514
+ Membership.LEAVE,
515
+ Membership.BAN,
516
+ ):
517
+ to_bound = (
518
+ room_membership_for_user_at_to_token.event_pos.to_room_stream_token()
519
+ )
520
+ # If we are participating in the room, we can get the latest current state in
521
+ # the room
522
+ elif membership == Membership.JOIN:
523
+ to_bound = to_token
524
+ # We can only rely on the stripped state included in the invite/knock event
525
+ # itself so there will never be any state deltas to send down.
526
+ elif membership in (Membership.INVITE, Membership.KNOCK):
527
+ return []
528
+ else:
529
+ # We don't know how to handle this type of membership yet
530
+ #
531
+ # FIXME: We should use `assert_never` here but for some reason
532
+ # the exhaustive matching doesn't recognize the `Never` here.
533
+ # assert_never(membership)
534
+ raise AssertionError(
535
+ f"Unexpected membership {membership} that we don't know how to handle yet"
536
+ )
537
+
538
+ return await self.store.get_current_state_deltas_for_room(
539
+ room_id=room_id,
540
+ from_token=from_token,
541
+ to_token=to_bound,
542
+ )
543
+
544
+ @trace
545
+ async def get_room_sync_data(
546
+ self,
547
+ sync_config: SlidingSyncConfig,
548
+ previous_connection_state: "PerConnectionState",
549
+ new_connection_state: "MutablePerConnectionState",
550
+ room_id: str,
551
+ room_sync_config: RoomSyncConfig,
552
+ room_membership_for_user_at_to_token: RoomsForUserType,
553
+ from_token: Optional[SlidingSyncStreamToken],
554
+ to_token: StreamToken,
555
+ newly_joined: bool,
556
+ newly_left: bool,
557
+ is_dm: bool,
558
+ ) -> SlidingSyncResult.RoomResult:
559
+ """
560
+ Fetch room data for the sync response.
561
+
562
+ We fetch data according to the token range (> `from_token` and <= `to_token`).
563
+
564
+ Args:
565
+ user: User to fetch data for
566
+ room_id: The room ID to fetch data for
567
+ room_sync_config: Config for what data we should fetch for a room in the
568
+ sync response.
569
+ room_membership_for_user_at_to_token: Membership information for the user
570
+ in the room at the time of `to_token`.
571
+ from_token: The point in the stream to sync from.
572
+ to_token: The point in the stream to sync up to.
573
+ newly_joined: If the user has newly joined the room
574
+ newly_left: If the user has newly left the room
575
+ is_dm: Whether the room is a DM room
576
+ """
577
+ user = sync_config.user
578
+
579
+ set_tag(
580
+ SynapseTags.FUNC_ARG_PREFIX + "membership",
581
+ room_membership_for_user_at_to_token.membership,
582
+ )
583
+ set_tag(
584
+ SynapseTags.FUNC_ARG_PREFIX + "timeline_limit",
585
+ room_sync_config.timeline_limit,
586
+ )
587
+
588
+ # Handle state resets. For example, if we see
589
+ # `room_membership_for_user_at_to_token.event_id=None and
590
+ # room_membership_for_user_at_to_token.membership is not None`, we should
591
+ # indicate to the client that a state reset happened. Perhaps we should indicate
592
+ # this by setting `initial: True` and empty `required_state: []`.
593
+ state_reset_out_of_room = False
594
+ if (
595
+ room_membership_for_user_at_to_token.event_id is None
596
+ and room_membership_for_user_at_to_token.membership is not None
597
+ ):
598
+ # We only expect the `event_id` to be `None` if you've been state reset out
599
+ # of the room (meaning you're no longer in the room). We could put this as
600
+ # part of the if-statement above but we want to handle every case where
601
+ # `event_id` is `None`.
602
+ assert room_membership_for_user_at_to_token.membership is Membership.LEAVE
603
+
604
+ state_reset_out_of_room = True
605
+
606
+ prev_room_sync_config = previous_connection_state.room_configs.get(room_id)
607
+
608
+ # Determine whether we should limit the timeline to the token range.
609
+ #
610
+ # We should return historical messages (before token range) in the
611
+ # following cases because we want clients to be able to show a basic
612
+ # screen of information:
613
+ #
614
+ # - Initial sync (because no `from_token` to limit us anyway)
615
+ # - When users `newly_joined`
616
+ # - For an incremental sync where we haven't sent it down this
617
+ # connection before
618
+ #
619
+ # Relevant spec issue:
620
+ # https://github.com/matrix-org/matrix-spec/issues/1917
621
+ #
622
+ # XXX: Odd behavior - We also check if the `timeline_limit` has increased, if so
623
+ # we ignore the from bound for the timeline to send down a larger chunk of
624
+ # history and set `unstable_expanded_timeline` to true. This is only being added
625
+ # to match the behavior of the Sliding Sync proxy as we expect the ElementX
626
+ # client to feel a certain way and be able to trickle in a full page of timeline
627
+ # messages to fill up the screen. This is a bit different to the behavior of the
628
+ # Sliding Sync proxy (which sets initial=true, but then doesn't send down the
629
+ # full state again), but existing apps, e.g. ElementX, just need `limited` set.
630
+ # We don't explicitly set `limited` but this will be the case for any room that
631
+ # has more history than we're trying to pull out. Using
632
+ # `unstable_expanded_timeline` allows us to avoid contaminating what `initial`
633
+ # or `limited` mean for clients that interpret them correctly. In future this
634
+ # behavior is almost certainly going to change.
635
+ #
636
+ from_bound = None
637
+ initial = True
638
+ ignore_timeline_bound = False
639
+ if from_token and not newly_joined and not state_reset_out_of_room:
640
+ room_status = previous_connection_state.rooms.have_sent_room(room_id)
641
+ if room_status.status == HaveSentRoomFlag.LIVE:
642
+ from_bound = from_token.stream_token.room_key
643
+ initial = False
644
+ elif room_status.status == HaveSentRoomFlag.PREVIOUSLY:
645
+ assert room_status.last_token is not None
646
+ from_bound = room_status.last_token
647
+ initial = False
648
+ elif room_status.status == HaveSentRoomFlag.NEVER:
649
+ from_bound = None
650
+ initial = True
651
+ else:
652
+ assert_never(room_status.status)
653
+
654
+ log_kv({"sliding_sync.room_status": room_status})
655
+
656
+ if prev_room_sync_config is not None:
657
+ # Check if the timeline limit has increased, if so ignore the
658
+ # timeline bound and record the change (see "XXX: Odd behavior"
659
+ # above).
660
+ if (
661
+ prev_room_sync_config.timeline_limit
662
+ < room_sync_config.timeline_limit
663
+ ):
664
+ ignore_timeline_bound = True
665
+
666
+ log_kv(
667
+ {
668
+ "sliding_sync.from_bound": from_bound,
669
+ "sliding_sync.initial": initial,
670
+ "sliding_sync.ignore_timeline_bound": ignore_timeline_bound,
671
+ }
672
+ )
673
+
674
+ # Assemble the list of timeline events
675
+ #
676
+ # FIXME: It would be nice to make the `rooms` response more uniform regardless of
677
+ # membership. Currently, we have to make all of these optional because
678
+ # `invite`/`knock` rooms only have `stripped_state`. See
679
+ # https://github.com/matrix-org/matrix-spec-proposals/pull/3575#discussion_r1653045932
680
+ timeline_events: list[EventBase] = []
681
+ bundled_aggregations: Optional[dict[str, BundledAggregations]] = None
682
+ limited: Optional[bool] = None
683
+ prev_batch_token: Optional[StreamToken] = None
684
+ num_live: Optional[int] = None
685
+ if (
686
+ room_sync_config.timeline_limit > 0
687
+ # No timeline for invite/knock rooms (just `stripped_state`)
688
+ and room_membership_for_user_at_to_token.membership
689
+ not in (Membership.INVITE, Membership.KNOCK)
690
+ ):
691
+ limited = False
692
+ # We want to start off using the `to_token` (vs `from_token`) because we look
693
+ # backwards from the `to_token` up to the `timeline_limit` and we might not
694
+ # reach the `from_token` before we hit the limit. We will update the room stream
695
+ # position once we've fetched the events to point to the earliest event fetched.
696
+ prev_batch_token = to_token
697
+
698
+ # We're going to paginate backwards from the `to_token`
699
+ to_bound = to_token.room_key
700
+ # People shouldn't see past their leave/ban event
701
+ if room_membership_for_user_at_to_token.membership in (
702
+ Membership.LEAVE,
703
+ Membership.BAN,
704
+ ):
705
+ to_bound = room_membership_for_user_at_to_token.event_pos.to_room_stream_token()
706
+
707
+ timeline_from_bound = from_bound
708
+ if ignore_timeline_bound:
709
+ timeline_from_bound = None
710
+
711
+ # For initial `/sync` (and other historical scenarios mentioned above), we
712
+ # want to view a historical section of the timeline; to fetch events by
713
+ # `topological_ordering` (best representation of the room DAG as others were
714
+ # seeing it at the time). This also aligns with the order that `/messages`
715
+ # returns events in.
716
+ #
717
+ # For incremental `/sync`, we want to get all updates for rooms since
718
+ # the last `/sync` (regardless if those updates arrived late or happened
719
+ # a while ago in the past); to fetch events by `stream_ordering` (in the
720
+ # order they were received by the server).
721
+ #
722
+ # Relevant spec issue: https://github.com/matrix-org/matrix-spec/issues/1917
723
+ #
724
+ # FIXME: Using workaround for mypy,
725
+ # https://github.com/python/mypy/issues/10740#issuecomment-1997047277 and
726
+ # https://github.com/python/mypy/issues/17479
727
+ paginate_room_events_by_topological_ordering: PaginateFunction = (
728
+ self.store.paginate_room_events_by_topological_ordering
729
+ )
730
+ paginate_room_events_by_stream_ordering: PaginateFunction = (
731
+ self.store.paginate_room_events_by_stream_ordering
732
+ )
733
+ pagination_method: PaginateFunction = (
734
+ # Use `topographical_ordering` for historical events
735
+ paginate_room_events_by_topological_ordering
736
+ if timeline_from_bound is None
737
+ # Use `stream_ordering` for updates
738
+ else paginate_room_events_by_stream_ordering
739
+ )
740
+ timeline_events, new_room_key, limited = await pagination_method(
741
+ room_id=room_id,
742
+ # The bounds are reversed so we can paginate backwards
743
+ # (from newer to older events) starting at to_bound.
744
+ # This ensures we fill the `limit` with the newest events first,
745
+ from_key=to_bound,
746
+ to_key=timeline_from_bound,
747
+ direction=Direction.BACKWARDS,
748
+ limit=room_sync_config.timeline_limit,
749
+ )
750
+
751
+ # We want to return the events in ascending order (the last event is the
752
+ # most recent).
753
+ timeline_events.reverse()
754
+
755
+ # Make sure we don't expose any events that the client shouldn't see
756
+ timeline_events = await filter_events_for_client(
757
+ self.storage_controllers,
758
+ user.to_string(),
759
+ timeline_events,
760
+ is_peeking=room_membership_for_user_at_to_token.membership
761
+ != Membership.JOIN,
762
+ filter_send_to_client=True,
763
+ )
764
+ # TODO: Filter out `EventTypes.CallInvite` in public rooms,
765
+ # see https://github.com/element-hq/synapse/issues/17359
766
+
767
+ # TODO: Handle timeline gaps (`get_timeline_gaps()`)
768
+
769
+ # Determine how many "live" events we have (events within the given token range).
770
+ #
771
+ # This is mostly useful to determine whether a given @mention event should
772
+ # make a noise or not. Clients cannot rely solely on the absence of
773
+ # `initial: true` to determine live events because if a room not in the
774
+ # sliding window bumps into the window because of an @mention it will have
775
+ # `initial: true` yet contain a single live event (with potentially other
776
+ # old events in the timeline)
777
+ num_live = 0
778
+ if from_token is not None:
779
+ for timeline_event in reversed(timeline_events):
780
+ # This fields should be present for all persisted events
781
+ assert timeline_event.internal_metadata.stream_ordering is not None
782
+ assert timeline_event.internal_metadata.instance_name is not None
783
+
784
+ persisted_position = PersistedEventPosition(
785
+ instance_name=timeline_event.internal_metadata.instance_name,
786
+ stream=timeline_event.internal_metadata.stream_ordering,
787
+ )
788
+ if persisted_position.persisted_after(
789
+ from_token.stream_token.room_key
790
+ ):
791
+ num_live += 1
792
+ else:
793
+ # Since we're iterating over the timeline events in
794
+ # reverse-chronological order, we can break once we hit an event
795
+ # that's not live. In the future, we could potentially optimize
796
+ # this more with a binary search (bisect).
797
+ break
798
+
799
+ # If the timeline is `limited=True`, the client does not have all events
800
+ # necessary to calculate aggregations themselves.
801
+ if limited:
802
+ bundled_aggregations = (
803
+ await self.relations_handler.get_bundled_aggregations(
804
+ timeline_events, user.to_string()
805
+ )
806
+ )
807
+
808
+ # Update the `prev_batch_token` to point to the position that allows us to
809
+ # keep paginating backwards from the oldest event we return in the timeline.
810
+ prev_batch_token = prev_batch_token.copy_and_replace(
811
+ StreamKeyType.ROOM, new_room_key
812
+ )
813
+
814
+ # Figure out any stripped state events for invite/knocks. This allows the
815
+ # potential joiner to identify the room.
816
+ stripped_state: list[JsonDict] = []
817
+ if room_membership_for_user_at_to_token.membership in (
818
+ Membership.INVITE,
819
+ Membership.KNOCK,
820
+ ):
821
+ # This should never happen. If someone is invited/knocked on room, then
822
+ # there should be an event for it.
823
+ assert room_membership_for_user_at_to_token.event_id is not None
824
+
825
+ invite_or_knock_event = await self.store.get_event(
826
+ room_membership_for_user_at_to_token.event_id
827
+ )
828
+
829
+ stripped_state = []
830
+ if invite_or_knock_event.membership == Membership.INVITE:
831
+ invite_state = invite_or_knock_event.unsigned.get(
832
+ "invite_room_state", []
833
+ )
834
+ if not isinstance(invite_state, list):
835
+ invite_state = []
836
+
837
+ stripped_state.extend(invite_state)
838
+ elif invite_or_knock_event.membership == Membership.KNOCK:
839
+ knock_state = invite_or_knock_event.unsigned.get("knock_room_state", [])
840
+ if not isinstance(knock_state, list):
841
+ knock_state = []
842
+
843
+ stripped_state.extend(knock_state)
844
+
845
+ stripped_state.append(strip_event(invite_or_knock_event))
846
+
847
+ # Get the changes to current state in the token range from the
848
+ # `current_state_delta_stream` table.
849
+ #
850
+ # For incremental syncs, we can do this first to determine if something relevant
851
+ # has changed and strategically avoid fetching other costly things.
852
+ room_state_delta_id_map: MutableStateMap[str] = {}
853
+ name_event_id: Optional[str] = None
854
+ membership_changed = False
855
+ name_changed = False
856
+ avatar_changed = False
857
+ if initial:
858
+ # Check whether the room has a name set
859
+ name_state_ids = await self.get_current_state_ids_at(
860
+ room_id=room_id,
861
+ room_membership_for_user_at_to_token=room_membership_for_user_at_to_token,
862
+ state_filter=StateFilter.from_types([(EventTypes.Name, "")]),
863
+ to_token=to_token,
864
+ )
865
+ name_event_id = name_state_ids.get((EventTypes.Name, ""))
866
+ else:
867
+ assert from_bound is not None
868
+
869
+ # TODO: Limit the number of state events we're about to send down
870
+ # the room, if its too many we should change this to an
871
+ # `initial=True`?
872
+
873
+ # For the case of rejecting remote invites, the leave event won't be
874
+ # returned by `get_current_state_deltas_for_room`. This is due to the current
875
+ # state only being filled out for rooms the server is in, and so doesn't pick
876
+ # up out-of-band leaves (including locally rejected invites) as these events
877
+ # are outliers and not added to the `current_state_delta_stream`.
878
+ #
879
+ # We rely on being explicitly told that the room has been `newly_left` to
880
+ # ensure we extract the out-of-band leave.
881
+ if newly_left and room_membership_for_user_at_to_token.event_id is not None:
882
+ membership_changed = True
883
+ leave_event = await self.store.get_event(
884
+ room_membership_for_user_at_to_token.event_id
885
+ )
886
+ state_key = leave_event.get_state_key()
887
+ if state_key is not None:
888
+ room_state_delta_id_map[(leave_event.type, state_key)] = (
889
+ room_membership_for_user_at_to_token.event_id
890
+ )
891
+
892
+ deltas = await self.get_current_state_deltas_for_room(
893
+ room_id=room_id,
894
+ room_membership_for_user_at_to_token=room_membership_for_user_at_to_token,
895
+ from_token=from_bound,
896
+ to_token=to_token.room_key,
897
+ )
898
+ for delta in deltas:
899
+ # TODO: Handle state resets where event_id is None
900
+ if delta.event_id is not None:
901
+ room_state_delta_id_map[(delta.event_type, delta.state_key)] = (
902
+ delta.event_id
903
+ )
904
+
905
+ if delta.event_type == EventTypes.Member:
906
+ membership_changed = True
907
+ elif delta.event_type == EventTypes.Name and delta.state_key == "":
908
+ name_changed = True
909
+ elif (
910
+ delta.event_type == EventTypes.RoomAvatar and delta.state_key == ""
911
+ ):
912
+ avatar_changed = True
913
+
914
+ # We only need the room summary for calculating heroes, however if we do
915
+ # fetch it then we can use it to calculate `joined_count` and
916
+ # `invited_count`.
917
+ room_membership_summary: Optional[Mapping[str, MemberSummary]] = None
918
+
919
+ # `heroes` are required if the room name is not set.
920
+ #
921
+ # Note: When you're the first one on your server to be invited to a new room
922
+ # over federation, we only have access to some stripped state in
923
+ # `event.unsigned.invite_room_state` which currently doesn't include `heroes`,
924
+ # see https://github.com/matrix-org/matrix-spec/issues/380. This means that
925
+ # clients won't be able to calculate the room name when necessary and just a
926
+ # pitfall we have to deal with until that spec issue is resolved.
927
+ hero_user_ids: list[str] = []
928
+ # TODO: Should we also check for `EventTypes.CanonicalAlias`
929
+ # (`m.room.canonical_alias`) as a fallback for the room name? see
930
+ # https://github.com/matrix-org/matrix-spec-proposals/pull/3575#discussion_r1671260153
931
+ #
932
+ # We need to fetch the `heroes` if the room name is not set. But we only need to
933
+ # get them on initial syncs (or the first time we send down the room) or if the
934
+ # membership has changed which may change the heroes.
935
+ if name_event_id is None and (initial or (not initial and membership_changed)):
936
+ # We need the room summary to extract the heroes from
937
+ if room_membership_for_user_at_to_token.membership != Membership.JOIN:
938
+ # TODO: Figure out how to get the membership summary for left/banned rooms
939
+ # For invite/knock rooms we don't include the information.
940
+ room_membership_summary = {}
941
+ else:
942
+ room_membership_summary = await self.store.get_room_summary(room_id)
943
+ # TODO: Reverse/rewind back to the `to_token`
944
+
945
+ hero_user_ids = extract_heroes_from_room_summary(
946
+ room_membership_summary, me=user.to_string()
947
+ )
948
+
949
+ # Fetch the membership counts for rooms we're joined to.
950
+ #
951
+ # Similarly to other metadata, we only need to calculate the member
952
+ # counts if this is an initial sync or the memberships have changed.
953
+ joined_count: Optional[int] = None
954
+ invited_count: Optional[int] = None
955
+ if (
956
+ initial or membership_changed
957
+ ) and room_membership_for_user_at_to_token.membership == Membership.JOIN:
958
+ # If we have the room summary (because we calculated heroes above)
959
+ # then we can simply pull the counts from there.
960
+ if room_membership_summary is not None:
961
+ empty_membership_summary = MemberSummary([], 0)
962
+
963
+ joined_count = room_membership_summary.get(
964
+ Membership.JOIN, empty_membership_summary
965
+ ).count
966
+
967
+ invited_count = room_membership_summary.get(
968
+ Membership.INVITE, empty_membership_summary
969
+ ).count
970
+ else:
971
+ member_counts = await self.store.get_member_counts(room_id)
972
+ joined_count = member_counts.get(Membership.JOIN, 0)
973
+ invited_count = member_counts.get(Membership.INVITE, 0)
974
+
975
+ # Fetch the `required_state` for the room
976
+ #
977
+ # No `required_state` for invite/knock rooms (just `stripped_state`)
978
+ #
979
+ # FIXME: It would be nice to make the `rooms` response more uniform regardless
980
+ # of membership. Currently, we have to make this optional because
981
+ # `invite`/`knock` rooms only have `stripped_state`. See
982
+ # https://github.com/matrix-org/matrix-spec-proposals/pull/3575#discussion_r1653045932
983
+ #
984
+ # Calculate the `StateFilter` based on the `required_state` for the room
985
+ required_state_filter = StateFilter.none()
986
+ # The requested `required_state_map` with the lazy membership expanded and
987
+ # `$ME` replaced with the user's ID. This allows us to see what membership we've
988
+ # sent down to the client in the next request.
989
+ #
990
+ # Make a copy so we can modify it. Still need to be careful to make a copy of
991
+ # the state key sets if we want to add/remove from them. We could make a deep
992
+ # copy but this saves us some work.
993
+ expanded_required_state_map = dict(room_sync_config.required_state_map)
994
+ if room_membership_for_user_at_to_token.membership not in (
995
+ Membership.INVITE,
996
+ Membership.KNOCK,
997
+ ):
998
+ # If we have a double wildcard ("*", "*") in the `required_state`, we need
999
+ # to fetch all state for the room
1000
+ #
1001
+ # Note: MSC3575 describes different behavior to how we're handling things
1002
+ # here but since it's not wrong to return more state than requested
1003
+ # (`required_state` is just the minimum requested), it doesn't matter if we
1004
+ # include more than client wanted. This complexity is also under scrutiny,
1005
+ # see
1006
+ # https://github.com/matrix-org/matrix-spec-proposals/pull/3575#discussion_r1185109050
1007
+ #
1008
+ # > One unique exception is when you request all state events via ["*", "*"]. When used,
1009
+ # > all state events are returned by default, and additional entries FILTER OUT the returned set
1010
+ # > of state events. These additional entries cannot use '*' themselves.
1011
+ # > For example, ["*", "*"], ["m.room.member", "@alice:example.com"] will _exclude_ every m.room.member
1012
+ # > event _except_ for @alice:example.com, and include every other state event.
1013
+ # > In addition, ["*", "*"], ["m.space.child", "*"] is an error, the m.space.child filter is not
1014
+ # > required as it would have been returned anyway.
1015
+ # >
1016
+ # > -- MSC3575 (https://github.com/matrix-org/matrix-spec-proposals/pull/3575)
1017
+ if StateValues.WILDCARD in room_sync_config.required_state_map.get(
1018
+ StateValues.WILDCARD, set()
1019
+ ):
1020
+ set_tag(
1021
+ SynapseTags.FUNC_ARG_PREFIX + "required_state_wildcard",
1022
+ True,
1023
+ )
1024
+ required_state_filter = StateFilter.all()
1025
+ # TODO: `StateFilter` currently doesn't support wildcard event types. We're
1026
+ # currently working around this by returning all state to the client but it
1027
+ # would be nice to fetch less from the database and return just what the
1028
+ # client wanted.
1029
+ elif (
1030
+ room_sync_config.required_state_map.get(StateValues.WILDCARD)
1031
+ is not None
1032
+ ):
1033
+ set_tag(
1034
+ SynapseTags.FUNC_ARG_PREFIX + "required_state_wildcard_event_type",
1035
+ True,
1036
+ )
1037
+ required_state_filter = StateFilter.all()
1038
+ else:
1039
+ required_state_types: list[tuple[str, Optional[str]]] = []
1040
+ num_wild_state_keys = 0
1041
+ lazy_load_room_members = False
1042
+ num_others = 0
1043
+ for (
1044
+ state_type,
1045
+ state_key_set,
1046
+ ) in room_sync_config.required_state_map.items():
1047
+ for state_key in state_key_set:
1048
+ if state_key == StateValues.WILDCARD:
1049
+ num_wild_state_keys += 1
1050
+ # `None` is a wildcard in the `StateFilter`
1051
+ required_state_types.append((state_type, None))
1052
+ # We need to fetch all relevant people when we're lazy-loading membership
1053
+ elif (
1054
+ state_type == EventTypes.Member
1055
+ and state_key == StateValues.LAZY
1056
+ ):
1057
+ lazy_load_room_members = True
1058
+
1059
+ # Everyone in the timeline is relevant
1060
+ timeline_membership: set[str] = set()
1061
+ if timeline_events is not None:
1062
+ for timeline_event in timeline_events:
1063
+ # Anyone who sent a message is relevant
1064
+ timeline_membership.add(timeline_event.sender)
1065
+
1066
+ # We also care about invite, ban, kick, targets,
1067
+ # etc.
1068
+ if timeline_event.type == EventTypes.Member:
1069
+ timeline_membership.add(
1070
+ timeline_event.state_key
1071
+ )
1072
+
1073
+ # Update the required state filter so we pick up the new
1074
+ # membership
1075
+ for user_id in timeline_membership:
1076
+ required_state_types.append(
1077
+ (EventTypes.Member, user_id)
1078
+ )
1079
+
1080
+ # Add an explicit entry for each user in the timeline
1081
+ #
1082
+ # Make a new set or copy of the state key set so we can
1083
+ # modify it without affecting the original
1084
+ # `required_state_map`
1085
+ expanded_required_state_map[EventTypes.Member] = (
1086
+ expanded_required_state_map.get(
1087
+ EventTypes.Member, set()
1088
+ )
1089
+ | timeline_membership
1090
+ )
1091
+ elif state_key == StateValues.ME:
1092
+ num_others += 1
1093
+ required_state_types.append((state_type, user.to_string()))
1094
+ # Replace `$ME` with the user's ID so we can deduplicate
1095
+ # when someone requests the same state with `$ME` or with
1096
+ # their user ID.
1097
+ #
1098
+ # Make a new set or copy of the state key set so we can
1099
+ # modify it without affecting the original
1100
+ # `required_state_map`
1101
+ expanded_required_state_map[EventTypes.Member] = (
1102
+ expanded_required_state_map.get(
1103
+ EventTypes.Member, set()
1104
+ )
1105
+ | {user.to_string()}
1106
+ )
1107
+ else:
1108
+ num_others += 1
1109
+ required_state_types.append((state_type, state_key))
1110
+
1111
+ set_tag(
1112
+ SynapseTags.FUNC_ARG_PREFIX
1113
+ + "required_state_wildcard_state_key_count",
1114
+ num_wild_state_keys,
1115
+ )
1116
+ set_tag(
1117
+ SynapseTags.FUNC_ARG_PREFIX + "required_state_lazy",
1118
+ lazy_load_room_members,
1119
+ )
1120
+ set_tag(
1121
+ SynapseTags.FUNC_ARG_PREFIX + "required_state_other_count",
1122
+ num_others,
1123
+ )
1124
+
1125
+ required_state_filter = StateFilter.from_types(required_state_types)
1126
+
1127
+ # We need this base set of info for the response so let's just fetch it along
1128
+ # with the `required_state` for the room
1129
+ hero_room_state = [
1130
+ (EventTypes.Member, hero_user_id) for hero_user_id in hero_user_ids
1131
+ ]
1132
+ meta_room_state = list(hero_room_state)
1133
+ if initial or name_changed:
1134
+ meta_room_state.append((EventTypes.Name, ""))
1135
+ if initial or avatar_changed:
1136
+ meta_room_state.append((EventTypes.RoomAvatar, ""))
1137
+
1138
+ state_filter = StateFilter.all()
1139
+ if required_state_filter != StateFilter.all():
1140
+ state_filter = StateFilter(
1141
+ types=StateFilter.from_types(
1142
+ chain(meta_room_state, required_state_filter.to_types())
1143
+ ).types,
1144
+ include_others=required_state_filter.include_others,
1145
+ )
1146
+
1147
+ # The required state map to store in the room sync config, if it has
1148
+ # changed.
1149
+ changed_required_state_map: Optional[Mapping[str, AbstractSet[str]]] = None
1150
+
1151
+ # We can return all of the state that was requested if this was the first
1152
+ # time we've sent the room down this connection.
1153
+ room_state: StateMap[EventBase] = {}
1154
+ if initial:
1155
+ room_state = await self.get_current_state_at(
1156
+ room_id=room_id,
1157
+ room_membership_for_user_at_to_token=room_membership_for_user_at_to_token,
1158
+ state_filter=state_filter,
1159
+ to_token=to_token,
1160
+ )
1161
+ else:
1162
+ assert from_bound is not None
1163
+
1164
+ if prev_room_sync_config is not None:
1165
+ # Check if there are any changes to the required state config
1166
+ # that we need to handle.
1167
+ changed_required_state_map, added_state_filter = (
1168
+ _required_state_changes(
1169
+ user.to_string(),
1170
+ prev_required_state_map=prev_room_sync_config.required_state_map,
1171
+ request_required_state_map=expanded_required_state_map,
1172
+ state_deltas=room_state_delta_id_map,
1173
+ )
1174
+ )
1175
+
1176
+ if added_state_filter:
1177
+ # Some state entries got added, so we pull out the current
1178
+ # state for them. If we don't do this we'd only send down new deltas.
1179
+ state_ids = await self.get_current_state_ids_at(
1180
+ room_id=room_id,
1181
+ room_membership_for_user_at_to_token=room_membership_for_user_at_to_token,
1182
+ state_filter=added_state_filter,
1183
+ to_token=to_token,
1184
+ )
1185
+ room_state_delta_id_map.update(state_ids)
1186
+
1187
+ events = await self.store.get_events(
1188
+ state_filter.filter_state(room_state_delta_id_map).values()
1189
+ )
1190
+ room_state = {(s.type, s.state_key): s for s in events.values()}
1191
+
1192
+ # If the membership changed and we have to get heroes, get the remaining
1193
+ # heroes from the state
1194
+ if hero_user_ids:
1195
+ hero_membership_state = await self.get_current_state_at(
1196
+ room_id=room_id,
1197
+ room_membership_for_user_at_to_token=room_membership_for_user_at_to_token,
1198
+ state_filter=StateFilter.from_types(hero_room_state),
1199
+ to_token=to_token,
1200
+ )
1201
+ room_state.update(hero_membership_state)
1202
+
1203
+ required_room_state: StateMap[EventBase] = {}
1204
+ if required_state_filter != StateFilter.none():
1205
+ required_room_state = required_state_filter.filter_state(room_state)
1206
+
1207
+ # Find the room name and avatar from the state
1208
+ room_name: Optional[str] = None
1209
+ # TODO: Should we also check for `EventTypes.CanonicalAlias`
1210
+ # (`m.room.canonical_alias`) as a fallback for the room name? see
1211
+ # https://github.com/matrix-org/matrix-spec-proposals/pull/3575#discussion_r1671260153
1212
+ name_event = room_state.get((EventTypes.Name, ""))
1213
+ if name_event is not None:
1214
+ room_name = name_event.content.get("name")
1215
+
1216
+ room_avatar: Optional[str] = None
1217
+ avatar_event = room_state.get((EventTypes.RoomAvatar, ""))
1218
+ if avatar_event is not None:
1219
+ room_avatar = avatar_event.content.get("url")
1220
+
1221
+ # Assemble heroes: extract the info from the state we just fetched
1222
+ heroes: list[SlidingSyncResult.RoomResult.StrippedHero] = []
1223
+ for hero_user_id in hero_user_ids:
1224
+ member_event = room_state.get((EventTypes.Member, hero_user_id))
1225
+ if member_event is not None:
1226
+ heroes.append(
1227
+ SlidingSyncResult.RoomResult.StrippedHero(
1228
+ user_id=hero_user_id,
1229
+ display_name=member_event.content.get("displayname"),
1230
+ avatar_url=member_event.content.get("avatar_url"),
1231
+ )
1232
+ )
1233
+
1234
+ # Figure out the last bump event in the room. If the bump stamp hasn't
1235
+ # changed we omit it from the response.
1236
+ bump_stamp = None
1237
+
1238
+ always_return_bump_stamp = (
1239
+ # We use the membership event position for any non-join
1240
+ room_membership_for_user_at_to_token.membership != Membership.JOIN
1241
+ # We didn't fetch any timeline events but we should still check for
1242
+ # a bump_stamp that might be somewhere
1243
+ or limited is None
1244
+ # There might be a bump event somewhere before the timeline events
1245
+ # that we fetched, that we didn't previously send down
1246
+ or limited is True
1247
+ # Always give the client some frame of reference if this is the
1248
+ # first time they are seeing the room down the connection
1249
+ or initial
1250
+ )
1251
+
1252
+ # If we're joined to the room, we need to find the last bump event before the
1253
+ # `to_token`
1254
+ if room_membership_for_user_at_to_token.membership == Membership.JOIN:
1255
+ # Try and get a bump stamp
1256
+ new_bump_stamp = await self._get_bump_stamp(
1257
+ room_id,
1258
+ to_token,
1259
+ timeline_events,
1260
+ check_outside_timeline=always_return_bump_stamp,
1261
+ )
1262
+ if new_bump_stamp is not None:
1263
+ bump_stamp = new_bump_stamp
1264
+
1265
+ if bump_stamp is None and always_return_bump_stamp:
1266
+ # By default, just choose the membership event position for any non-join membership
1267
+ bump_stamp = room_membership_for_user_at_to_token.event_pos.stream
1268
+
1269
+ if bump_stamp is not None and bump_stamp < 0:
1270
+ # We never want to send down negative stream orderings, as you can't
1271
+ # sensibly compare positive and negative stream orderings (they have
1272
+ # different meanings).
1273
+ #
1274
+ # A negative bump stamp here can only happen if the stream ordering
1275
+ # of the membership event is negative (and there are no further bump
1276
+ # stamps), which can happen if the server leaves and deletes a room,
1277
+ # and then rejoins it.
1278
+ #
1279
+ # To deal with this, we just set the bump stamp to zero, which will
1280
+ # shove this room to the bottom of the list. This is OK as the
1281
+ # moment a new message happens in the room it will get put into a
1282
+ # sensible order again.
1283
+ bump_stamp = 0
1284
+
1285
+ room_sync_required_state_map_to_persist: Mapping[str, AbstractSet[str]] = (
1286
+ expanded_required_state_map
1287
+ )
1288
+ if changed_required_state_map:
1289
+ room_sync_required_state_map_to_persist = changed_required_state_map
1290
+
1291
+ # Record the `room_sync_config` if we're `ignore_timeline_bound` (which means
1292
+ # that the `timeline_limit` has increased)
1293
+ unstable_expanded_timeline = False
1294
+ if ignore_timeline_bound:
1295
+ # FIXME: We signal the fact that we're sending down more events to
1296
+ # the client by setting `unstable_expanded_timeline` to true (see
1297
+ # "XXX: Odd behavior" above).
1298
+ unstable_expanded_timeline = True
1299
+
1300
+ new_connection_state.room_configs[room_id] = RoomSyncConfig(
1301
+ timeline_limit=room_sync_config.timeline_limit,
1302
+ required_state_map=room_sync_required_state_map_to_persist,
1303
+ )
1304
+ elif prev_room_sync_config is not None:
1305
+ # If the result is `limited` then we need to record that the
1306
+ # `timeline_limit` has been reduced, as when/if the client later requests
1307
+ # more timeline then we have more data to send.
1308
+ #
1309
+ # Otherwise (when not `limited`) we don't need to record that the
1310
+ # `timeline_limit` has been reduced, as the *effective* `timeline_limit`
1311
+ # (i.e. the amount of timeline we have previously sent to the client) is at
1312
+ # least the previous `timeline_limit`.
1313
+ #
1314
+ # This is to handle the case where the `timeline_limit` e.g. goes from 10 to
1315
+ # 5 to 10 again (without any timeline gaps), where there's no point sending
1316
+ # down the initial historical chunk events when the `timeline_limit` is
1317
+ # increased as the client already has the 10 previous events. However, if
1318
+ # client has a gap in the timeline (i.e. `limited` is True), then we *do*
1319
+ # need to record the reduced timeline.
1320
+ #
1321
+ # TODO: Handle timeline gaps (`get_timeline_gaps()`) - This is separate from
1322
+ # the gaps we might see on the client because a response was `limited` we're
1323
+ # talking about above.
1324
+ if (
1325
+ limited
1326
+ and prev_room_sync_config.timeline_limit
1327
+ > room_sync_config.timeline_limit
1328
+ ):
1329
+ new_connection_state.room_configs[room_id] = RoomSyncConfig(
1330
+ timeline_limit=room_sync_config.timeline_limit,
1331
+ required_state_map=room_sync_required_state_map_to_persist,
1332
+ )
1333
+
1334
+ elif changed_required_state_map is not None:
1335
+ new_connection_state.room_configs[room_id] = RoomSyncConfig(
1336
+ timeline_limit=room_sync_config.timeline_limit,
1337
+ required_state_map=room_sync_required_state_map_to_persist,
1338
+ )
1339
+
1340
+ else:
1341
+ new_connection_state.room_configs[room_id] = RoomSyncConfig(
1342
+ timeline_limit=room_sync_config.timeline_limit,
1343
+ required_state_map=room_sync_required_state_map_to_persist,
1344
+ )
1345
+
1346
+ set_tag(SynapseTags.RESULT_PREFIX + "initial", initial)
1347
+
1348
+ return SlidingSyncResult.RoomResult(
1349
+ name=room_name,
1350
+ avatar=room_avatar,
1351
+ heroes=heroes,
1352
+ is_dm=is_dm,
1353
+ initial=initial,
1354
+ required_state=list(required_room_state.values()),
1355
+ timeline_events=timeline_events,
1356
+ bundled_aggregations=bundled_aggregations,
1357
+ stripped_state=stripped_state,
1358
+ prev_batch=prev_batch_token,
1359
+ limited=limited,
1360
+ unstable_expanded_timeline=unstable_expanded_timeline,
1361
+ num_live=num_live,
1362
+ bump_stamp=bump_stamp,
1363
+ joined_count=joined_count,
1364
+ invited_count=invited_count,
1365
+ # TODO: These are just dummy values. We could potentially just remove these
1366
+ # since notifications can only really be done correctly on the client anyway
1367
+ # (encrypted rooms).
1368
+ notification_count=0,
1369
+ highlight_count=0,
1370
+ )
1371
+
1372
+ @trace
1373
+ async def _get_bump_stamp(
1374
+ self,
1375
+ room_id: str,
1376
+ to_token: StreamToken,
1377
+ timeline: list[EventBase],
1378
+ check_outside_timeline: bool,
1379
+ ) -> Optional[int]:
1380
+ """Get a bump stamp for the room, if we have a bump event and it has
1381
+ changed.
1382
+
1383
+ Args:
1384
+ room_id
1385
+ to_token: The upper bound of token to return
1386
+ timeline: The list of events we have fetched.
1387
+ limited: If the timeline was limited.
1388
+ check_outside_timeline: Whether we need to check for bump stamp for
1389
+ events before the timeline if we didn't find a bump stamp in
1390
+ the timeline events.
1391
+ """
1392
+
1393
+ # First check the timeline events we're returning to see if one of
1394
+ # those matches. We iterate backwards and take the stream ordering
1395
+ # of the first event that matches the bump event types.
1396
+ for timeline_event in reversed(timeline):
1397
+ if timeline_event.type in SLIDING_SYNC_DEFAULT_BUMP_EVENT_TYPES:
1398
+ new_bump_stamp = timeline_event.internal_metadata.stream_ordering
1399
+
1400
+ # All persisted events have a stream ordering
1401
+ assert new_bump_stamp is not None
1402
+
1403
+ # If we've just joined a remote room, then the last bump event may
1404
+ # have been backfilled (and so have a negative stream ordering).
1405
+ # These negative stream orderings can't sensibly be compared, so
1406
+ # instead we use the membership event position.
1407
+ if new_bump_stamp > 0:
1408
+ return new_bump_stamp
1409
+
1410
+ if not check_outside_timeline:
1411
+ # If we are not a limited sync, then we know the bump stamp can't
1412
+ # have changed.
1413
+ return None
1414
+
1415
+ # We can quickly query for the latest bump event in the room using the
1416
+ # sliding sync tables.
1417
+ latest_room_bump_stamp = await self.store.get_latest_bump_stamp_for_room(
1418
+ room_id
1419
+ )
1420
+
1421
+ min_to_token_position = to_token.room_key.stream
1422
+
1423
+ # If we can rely on the new sliding sync tables and the `bump_stamp` is
1424
+ # `None`, just fallback to the membership event position. This can happen
1425
+ # when we've just joined a remote room and all the events are backfilled.
1426
+ if (
1427
+ # FIXME: The background job check can be removed once we bump
1428
+ # `SCHEMA_COMPAT_VERSION` and run the foreground update for
1429
+ # `sliding_sync_joined_rooms`/`sliding_sync_membership_snapshots`
1430
+ # (tracked by https://github.com/element-hq/synapse/issues/17623)
1431
+ latest_room_bump_stamp is None
1432
+ and await self.store.have_finished_sliding_sync_background_jobs()
1433
+ ):
1434
+ return None
1435
+
1436
+ # The `bump_stamp` stored in the database might be ahead of our token. Since
1437
+ # `bump_stamp` is only a `stream_ordering` position, we can't be 100% sure
1438
+ # that's before the `to_token` in all scenarios. The only scenario we can be
1439
+ # sure of is if the `bump_stamp` is totally before the minimum position from
1440
+ # the token.
1441
+ #
1442
+ # We don't need to check if the background update has finished, as if the
1443
+ # returned bump stamp is not None then it must be up to date.
1444
+ elif (
1445
+ latest_room_bump_stamp is not None
1446
+ and latest_room_bump_stamp < min_to_token_position
1447
+ ):
1448
+ if latest_room_bump_stamp > 0:
1449
+ return latest_room_bump_stamp
1450
+ else:
1451
+ return None
1452
+
1453
+ # Otherwise, if it's within or after the `to_token`, we need to find the
1454
+ # last bump event before the `to_token`.
1455
+ else:
1456
+ last_bump_event_result = (
1457
+ await self.store.get_last_event_pos_in_room_before_stream_ordering(
1458
+ room_id,
1459
+ to_token.room_key,
1460
+ event_types=SLIDING_SYNC_DEFAULT_BUMP_EVENT_TYPES,
1461
+ )
1462
+ )
1463
+ if last_bump_event_result is not None:
1464
+ _, new_bump_event_pos = last_bump_event_result
1465
+
1466
+ # If we've just joined a remote room, then the last bump event may
1467
+ # have been backfilled (and so have a negative stream ordering).
1468
+ # These negative stream orderings can't sensibly be compared, so
1469
+ # instead we use the membership event position.
1470
+ if new_bump_event_pos.stream > 0:
1471
+ return new_bump_event_pos.stream
1472
+
1473
+ return None
1474
+
1475
+
1476
+ def _required_state_changes(
1477
+ user_id: str,
1478
+ *,
1479
+ prev_required_state_map: Mapping[str, AbstractSet[str]],
1480
+ request_required_state_map: Mapping[str, AbstractSet[str]],
1481
+ state_deltas: StateMap[str],
1482
+ ) -> tuple[Optional[Mapping[str, AbstractSet[str]]], StateFilter]:
1483
+ """Calculates the changes between the required state room config from the
1484
+ previous requests compared with the current request.
1485
+
1486
+ This does two things. First, it calculates if we need to update the room
1487
+ config due to changes to required state. Secondly, it works out which state
1488
+ entries we need to pull from current state and return due to the state entry
1489
+ now appearing in the required state when it previously wasn't (on top of the
1490
+ state deltas).
1491
+
1492
+ This function tries to ensure to handle the case where a state entry is
1493
+ added, removed and then added again to the required state. In that case we
1494
+ only want to re-send that entry down sync if it has changed.
1495
+
1496
+ Returns:
1497
+ A 2-tuple of updated required state config (or None if there is no update)
1498
+ and the state filter to use to fetch extra current state that we need to
1499
+ return.
1500
+ """
1501
+ if prev_required_state_map == request_required_state_map:
1502
+ # There has been no change. Return immediately.
1503
+ return None, StateFilter.none()
1504
+
1505
+ prev_wildcard = prev_required_state_map.get(StateValues.WILDCARD, set())
1506
+ request_wildcard = request_required_state_map.get(StateValues.WILDCARD, set())
1507
+
1508
+ # If we were previously fetching everything ("*", "*"), always update the effective
1509
+ # room required state config to match the request. And since we we're previously
1510
+ # already fetching everything, we don't have to fetch anything now that they've
1511
+ # narrowed.
1512
+ if StateValues.WILDCARD in prev_wildcard:
1513
+ return request_required_state_map, StateFilter.none()
1514
+
1515
+ # If a event type wildcard has been added or removed we don't try and do
1516
+ # anything fancy, and instead always update the effective room required
1517
+ # state config to match the request.
1518
+ if request_wildcard - prev_wildcard:
1519
+ # Some keys were added, so we need to fetch everything
1520
+ return request_required_state_map, StateFilter.all()
1521
+ if prev_wildcard - request_wildcard:
1522
+ # Keys were only removed, so we don't have to fetch everything.
1523
+ return request_required_state_map, StateFilter.none()
1524
+
1525
+ # Contains updates to the required state map compared with the previous room
1526
+ # config. This has the same format as `RoomSyncConfig.required_state`
1527
+ changes: dict[str, AbstractSet[str]] = {}
1528
+
1529
+ # The set of types/state keys that we need to fetch and return to the
1530
+ # client. Passed to `StateFilter.from_types(...)`
1531
+ added: list[tuple[str, Optional[str]]] = []
1532
+
1533
+ # Convert the list of state deltas to map from type to state_keys that have
1534
+ # changed.
1535
+ changed_types_to_state_keys: dict[str, set[str]] = {}
1536
+ for event_type, state_key in state_deltas:
1537
+ changed_types_to_state_keys.setdefault(event_type, set()).add(state_key)
1538
+
1539
+ # First we calculate what, if anything, has been *added*.
1540
+ for event_type in (
1541
+ prev_required_state_map.keys() | request_required_state_map.keys()
1542
+ ):
1543
+ old_state_keys = prev_required_state_map.get(event_type, set())
1544
+ request_state_keys = request_required_state_map.get(event_type, set())
1545
+ changed_state_keys = changed_types_to_state_keys.get(event_type, set())
1546
+
1547
+ if old_state_keys == request_state_keys:
1548
+ # No change to this type
1549
+ continue
1550
+
1551
+ if not request_state_keys - old_state_keys:
1552
+ # Nothing *added*, so we skip. Removals happen below.
1553
+ continue
1554
+
1555
+ # We only remove state keys from the effective state if they've been
1556
+ # removed from the request *and* the state has changed. This ensures
1557
+ # that if a client removes and then re-adds a state key, we only send
1558
+ # down the associated current state event if its changed (rather than
1559
+ # sending down the same event twice).
1560
+ invalidated_state_keys = (
1561
+ old_state_keys - request_state_keys
1562
+ ) & changed_state_keys
1563
+
1564
+ # Figure out which state keys we should remember sending down the connection
1565
+ inheritable_previous_state_keys = (
1566
+ # Retain the previous state_keys that we've sent down before.
1567
+ # Wildcard and lazy state keys are not sticky from previous requests.
1568
+ (old_state_keys - {StateValues.WILDCARD, StateValues.LAZY})
1569
+ - invalidated_state_keys
1570
+ )
1571
+
1572
+ # Always update changes to include the newly added keys (we've expanded the set
1573
+ # of state keys), use the new requested set with whatever hasn't been
1574
+ # invalidated from the previous set.
1575
+ changes[event_type] = request_state_keys | inheritable_previous_state_keys
1576
+ # Limit the number of state_keys we should remember sending down the connection
1577
+ # for each (room_id, user_id). We don't want to store and pull out too much data
1578
+ # in the database. This is a happy-medium between remembering nothing and
1579
+ # everything. We can avoid sending redundant state down the connection most of
1580
+ # the time given that most rooms don't have 100 members anyway and it takes a
1581
+ # while to cycle through 100 members.
1582
+ #
1583
+ # Only remember up to (MAX_NUMBER_PREVIOUS_STATE_KEYS_TO_REMEMBER)
1584
+ if len(changes[event_type]) > MAX_NUMBER_PREVIOUS_STATE_KEYS_TO_REMEMBER:
1585
+ # Reset back to only the requested state keys
1586
+ changes[event_type] = request_state_keys
1587
+
1588
+ # Skip if there isn't any room to fill in the rest with previous state keys
1589
+ if len(request_state_keys) < MAX_NUMBER_PREVIOUS_STATE_KEYS_TO_REMEMBER:
1590
+ # Fill the rest with previous state_keys. Ideally, we could sort
1591
+ # these by recency but it's just a set so just pick an arbitrary
1592
+ # subset (good enough).
1593
+ changes[event_type] = changes[event_type] | set(
1594
+ itertools.islice(
1595
+ inheritable_previous_state_keys,
1596
+ # Just taking the difference isn't perfect as there could be
1597
+ # overlap in the keys between the requested and previous but we
1598
+ # will decide to just take the easy route for now and avoid
1599
+ # additional set operations to figure it out.
1600
+ MAX_NUMBER_PREVIOUS_STATE_KEYS_TO_REMEMBER
1601
+ - len(request_state_keys),
1602
+ )
1603
+ )
1604
+
1605
+ if StateValues.WILDCARD in old_state_keys:
1606
+ # We were previously fetching everything for this type, so we don't need to
1607
+ # fetch anything new.
1608
+ continue
1609
+
1610
+ # Record the new state keys to fetch for this type.
1611
+ if StateValues.WILDCARD in request_state_keys:
1612
+ # If we have added a wildcard then we always just fetch everything.
1613
+ added.append((event_type, None))
1614
+ else:
1615
+ for state_key in request_state_keys - old_state_keys:
1616
+ if state_key == StateValues.ME:
1617
+ added.append((event_type, user_id))
1618
+ elif state_key == StateValues.LAZY:
1619
+ # We handle lazy loading separately (outside this function),
1620
+ # so don't need to explicitly add anything here.
1621
+ #
1622
+ # LAZY values should also be ignore for event types that are
1623
+ # not membership.
1624
+ pass
1625
+ else:
1626
+ added.append((event_type, state_key))
1627
+
1628
+ added_state_filter = StateFilter.from_types(added)
1629
+
1630
+ # Figure out what changes we need to apply to the effective required state
1631
+ # config.
1632
+ for event_type, changed_state_keys in changed_types_to_state_keys.items():
1633
+ old_state_keys = prev_required_state_map.get(event_type, set())
1634
+ request_state_keys = request_required_state_map.get(event_type, set())
1635
+
1636
+ if old_state_keys == request_state_keys:
1637
+ # No change.
1638
+ continue
1639
+
1640
+ # If we see the `user_id` as a state_key, also add "$ME" to the list of state
1641
+ # that has changed to account for people requesting `required_state` with `$ME`
1642
+ # or their user ID.
1643
+ if user_id in changed_state_keys:
1644
+ changed_state_keys.add(StateValues.ME)
1645
+
1646
+ # We only remove state keys from the effective state if they've been
1647
+ # removed from the request *and* the state has changed. This ensures
1648
+ # that if a client removes and then re-adds a state key, we only send
1649
+ # down the associated current state event if its changed (rather than
1650
+ # sending down the same event twice).
1651
+ invalidated_state_keys = (
1652
+ old_state_keys - request_state_keys
1653
+ ) & changed_state_keys
1654
+
1655
+ # We've expanded the set of state keys, ... (already handled above)
1656
+ if request_state_keys - old_state_keys:
1657
+ continue
1658
+
1659
+ old_state_key_wildcard = StateValues.WILDCARD in old_state_keys
1660
+ request_state_key_wildcard = StateValues.WILDCARD in request_state_keys
1661
+
1662
+ if old_state_key_wildcard != request_state_key_wildcard:
1663
+ # If a state_key wildcard has been added or removed, we always update the
1664
+ # effective room required state config to match the request.
1665
+ changes[event_type] = request_state_keys
1666
+ continue
1667
+
1668
+ if event_type == EventTypes.Member:
1669
+ old_state_key_lazy = StateValues.LAZY in old_state_keys
1670
+ request_state_key_lazy = StateValues.LAZY in request_state_keys
1671
+
1672
+ if old_state_key_lazy != request_state_key_lazy:
1673
+ # If a "$LAZY" has been added or removed we always update the effective room
1674
+ # required state config to match the request.
1675
+ changes[event_type] = request_state_keys
1676
+ continue
1677
+
1678
+ # At this point there are no wildcards and no additions to the set of
1679
+ # state keys requested, only deletions.
1680
+ #
1681
+ # We only remove state keys from the effective state if they've been
1682
+ # removed from the request *and* the state has changed. This ensures
1683
+ # that if a client removes and then re-adds a state key, we only send
1684
+ # down the associated current state event if its changed (rather than
1685
+ # sending down the same event twice).
1686
+ if invalidated_state_keys:
1687
+ changes[event_type] = old_state_keys - invalidated_state_keys
1688
+
1689
+ if changes:
1690
+ # Update the required state config based on the changes.
1691
+ new_required_state_map = dict(prev_required_state_map)
1692
+ for event_type, state_keys in changes.items():
1693
+ if state_keys:
1694
+ new_required_state_map[event_type] = state_keys
1695
+ else:
1696
+ # Remove entries with empty state keys.
1697
+ new_required_state_map.pop(event_type, None)
1698
+
1699
+ return new_required_state_map, added_state_filter
1700
+ else:
1701
+ return None, added_state_filter