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,1342 @@
1
+ #
2
+ # This file is licensed under the Affero General Public License (AGPL) version 3.
3
+ #
4
+ # Copyright 2014-2016 OpenMarket Ltd
5
+ # Copyright (C) 2023 New Vector, Ltd
6
+ #
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Affero General Public License as
9
+ # published by the Free Software Foundation, either version 3 of the
10
+ # License, or (at your option) any later version.
11
+ #
12
+ # See the GNU Affero General Public License for more details:
13
+ # <https://www.gnu.org/licenses/agpl-3.0.html>.
14
+ #
15
+ # Originally licensed under the Apache License, Version 2.0:
16
+ # <http://www.apache.org/licenses/LICENSE-2.0>.
17
+ #
18
+ # [This file includes modifications made by New Vector Limited]
19
+ #
20
+ #
21
+
22
+ import logging
23
+ from typing import (
24
+ TYPE_CHECKING,
25
+ Any,
26
+ Collection,
27
+ Iterable,
28
+ Mapping,
29
+ Optional,
30
+ Sequence,
31
+ cast,
32
+ )
33
+
34
+ import attr
35
+
36
+ from synapse.api.constants import EduTypes
37
+ from synapse.replication.tcp.streams import ReceiptsStream
38
+ from synapse.storage._base import SQLBaseStore, db_to_json, make_in_list_sql_clause
39
+ from synapse.storage.database import (
40
+ DatabasePool,
41
+ LoggingDatabaseConnection,
42
+ LoggingTransaction,
43
+ make_tuple_in_list_sql_clause,
44
+ )
45
+ from synapse.storage.engines._base import IsolationLevel
46
+ from synapse.storage.util.id_generators import MultiWriterIdGenerator
47
+ from synapse.types import (
48
+ JsonDict,
49
+ JsonMapping,
50
+ MultiWriterStreamToken,
51
+ PersistedPosition,
52
+ StrCollection,
53
+ )
54
+ from synapse.util.caches.descriptors import cached, cachedList
55
+ from synapse.util.caches.stream_change_cache import StreamChangeCache
56
+ from synapse.util.iterutils import batch_iter
57
+ from synapse.util.json import json_encoder
58
+
59
+ if TYPE_CHECKING:
60
+ from synapse.server import HomeServer
61
+
62
+ logger = logging.getLogger(__name__)
63
+
64
+
65
+ @attr.s(auto_attribs=True, slots=True, frozen=True)
66
+ class ReceiptInRoom:
67
+ receipt_type: str
68
+ user_id: str
69
+ event_id: str
70
+ thread_id: Optional[str]
71
+ data: JsonMapping
72
+
73
+ @staticmethod
74
+ def merge_to_content(receipts: Collection["ReceiptInRoom"]) -> JsonMapping:
75
+ """Merge the given set of receipts (in a room) into the receipt
76
+ content format.
77
+
78
+ Returns:
79
+ A mapping of the combined receipts: event ID -> receipt type -> user
80
+ ID -> receipt data.
81
+ """
82
+ # MSC4102: always replace threaded receipts with unthreaded ones if
83
+ # there is a clash. This means we will drop some receipts, but MSC4102
84
+ # is designed to drop semantically meaningless receipts, so this is
85
+ # okay. Previously, we would drop meaningful data!
86
+ #
87
+ # We do this by finding the unthreaded receipts, and then filtering out
88
+ # matching threaded receipts.
89
+
90
+ # Set of (user_id, event_id)
91
+ unthreaded_receipts: set[tuple[str, str]] = {
92
+ (receipt.user_id, receipt.event_id)
93
+ for receipt in receipts
94
+ if receipt.thread_id is None
95
+ }
96
+
97
+ # event_id -> receipt_type -> user_id -> receipt data
98
+ content: dict[str, dict[str, dict[str, JsonMapping]]] = {}
99
+ for receipt in receipts:
100
+ data = receipt.data
101
+ if receipt.thread_id is not None:
102
+ if (receipt.user_id, receipt.event_id) in unthreaded_receipts:
103
+ # Ignore threaded receipts if we have an unthreaded one.
104
+ continue
105
+
106
+ data = dict(data)
107
+ data["thread_id"] = receipt.thread_id
108
+
109
+ content.setdefault(receipt.event_id, {}).setdefault(
110
+ receipt.receipt_type, {}
111
+ )[receipt.user_id] = data
112
+
113
+ return content
114
+
115
+
116
+ class ReceiptsWorkerStore(SQLBaseStore):
117
+ def __init__(
118
+ self,
119
+ database: DatabasePool,
120
+ db_conn: LoggingDatabaseConnection,
121
+ hs: "HomeServer",
122
+ ):
123
+ super().__init__(database, db_conn, hs)
124
+ self._instance_name = hs.get_instance_name()
125
+
126
+ # In the worker store this is an ID tracker which we overwrite in the non-worker
127
+ # class below that is used on the main process.
128
+ self._receipts_id_gen: MultiWriterIdGenerator
129
+
130
+ self._can_write_to_receipts = (
131
+ self._instance_name in hs.config.worker.writers.receipts
132
+ )
133
+
134
+ self._receipts_id_gen = MultiWriterIdGenerator(
135
+ db_conn=db_conn,
136
+ db=database,
137
+ notifier=hs.get_replication_notifier(),
138
+ server_name=self.server_name,
139
+ stream_name="receipts",
140
+ instance_name=self._instance_name,
141
+ tables=[("receipts_linearized", "instance_name", "stream_id")],
142
+ sequence_name="receipts_sequence",
143
+ writers=hs.config.worker.writers.receipts,
144
+ )
145
+
146
+ max_receipts_stream_id = self.get_max_receipt_stream_id()
147
+ receipts_stream_prefill, min_receipts_stream_id = self.db_pool.get_cache_dict(
148
+ db_conn,
149
+ "receipts_linearized",
150
+ entity_column="room_id",
151
+ stream_column="stream_id",
152
+ max_value=max_receipts_stream_id.stream,
153
+ limit=10000,
154
+ )
155
+ self._receipts_stream_cache = StreamChangeCache(
156
+ name="ReceiptsRoomChangeCache",
157
+ server_name=self.server_name,
158
+ current_stream_pos=min_receipts_stream_id,
159
+ prefilled_cache=receipts_stream_prefill,
160
+ )
161
+
162
+ def get_max_receipt_stream_id(self) -> MultiWriterStreamToken:
163
+ """Get the current max stream ID for receipts stream"""
164
+
165
+ return MultiWriterStreamToken.from_generator(self._receipts_id_gen)
166
+
167
+ def get_receipt_stream_id_for_instance(self, instance_name: str) -> int:
168
+ return self._receipts_id_gen.get_current_token_for_writer(instance_name)
169
+
170
+ def get_receipts_stream_id_gen(self) -> MultiWriterIdGenerator:
171
+ return self._receipts_id_gen
172
+
173
+ def get_last_unthreaded_receipt_for_user_txn(
174
+ self,
175
+ txn: LoggingTransaction,
176
+ user_id: str,
177
+ room_id: str,
178
+ receipt_types: Collection[str],
179
+ ) -> Optional[tuple[str, int]]:
180
+ """
181
+ Fetch the event ID and stream_ordering for the latest unthreaded receipt
182
+ in a room with one of the given receipt types.
183
+
184
+ Args:
185
+ user_id: The user to fetch receipts for.
186
+ room_id: The room ID to fetch the receipt for.
187
+ receipt_types: The receipt types to fetch.
188
+
189
+ Returns:
190
+ The event ID and stream ordering of the latest receipt, if one exists.
191
+ """
192
+
193
+ clause, args = make_in_list_sql_clause(
194
+ self.database_engine, "receipt_type", receipt_types
195
+ )
196
+
197
+ sql = f"""
198
+ SELECT event_id, event_stream_ordering
199
+ FROM receipts_linearized
200
+ WHERE {clause}
201
+ AND user_id = ?
202
+ AND room_id = ?
203
+ AND thread_id IS NULL
204
+ ORDER BY event_stream_ordering DESC
205
+ LIMIT 1
206
+ """
207
+
208
+ args.extend((user_id, room_id))
209
+ txn.execute(sql, args)
210
+
211
+ return cast(Optional[tuple[str, int]], txn.fetchone())
212
+
213
+ async def get_receipts_for_user(
214
+ self, user_id: str, receipt_types: Iterable[str]
215
+ ) -> dict[str, str]:
216
+ """
217
+ Fetch the event IDs for the latest receipts sent by the given user.
218
+
219
+ Args:
220
+ user_id: The user to fetch receipts for.
221
+ receipt_types: The receipt types to check.
222
+
223
+ Returns:
224
+ A map of room ID to the event ID of the latest receipt for that room.
225
+
226
+ If the user has not sent a receipt to a room then it will not appear
227
+ in the returned dictionary.
228
+ """
229
+ results = await self.get_receipts_for_user_with_orderings(
230
+ user_id, receipt_types
231
+ )
232
+
233
+ # Reduce the result to room ID -> event ID.
234
+ return {
235
+ room_id: room_result["event_id"] for room_id, room_result in results.items()
236
+ }
237
+
238
+ async def get_receipts_for_user_with_orderings(
239
+ self, user_id: str, receipt_types: Iterable[str]
240
+ ) -> JsonDict:
241
+ """
242
+ Fetch receipts for all rooms that the given user is joined to.
243
+
244
+ Args:
245
+ user_id: The user to fetch receipts for.
246
+ receipt_types: The receipt types to fetch. Earlier receipt types
247
+ are given priority if multiple receipts point to the same event.
248
+
249
+ Returns:
250
+ A map of room ID to the latest receipt (for the given types).
251
+ """
252
+ results: JsonDict = {}
253
+ for receipt_type in receipt_types:
254
+ partial_result = await self._get_receipts_for_user_with_orderings(
255
+ user_id, receipt_type
256
+ )
257
+ for room_id, room_result in partial_result.items():
258
+ # If the room has not yet been seen, or the receipt is newer,
259
+ # use it.
260
+ if (
261
+ room_id not in results
262
+ or results[room_id]["stream_ordering"]
263
+ < room_result["stream_ordering"]
264
+ ):
265
+ results[room_id] = room_result
266
+
267
+ return results
268
+
269
+ @cached()
270
+ async def _get_receipts_for_user_with_orderings(
271
+ self, user_id: str, receipt_type: str
272
+ ) -> JsonMapping:
273
+ """
274
+ Fetch receipts for all rooms that the given user is joined to.
275
+
276
+ Args:
277
+ user_id: The user to fetch receipts for.
278
+ receipt_type: The receipt type to fetch.
279
+
280
+ Returns:
281
+ A map of room ID to the latest receipt information.
282
+ """
283
+
284
+ def f(txn: LoggingTransaction) -> list[tuple[str, str, int, int]]:
285
+ sql = (
286
+ "SELECT rl.room_id, rl.event_id,"
287
+ " e.topological_ordering, e.stream_ordering"
288
+ " FROM receipts_linearized AS rl"
289
+ " INNER JOIN events AS e USING (room_id, event_id)"
290
+ " WHERE rl.room_id = e.room_id"
291
+ " AND rl.event_id = e.event_id"
292
+ " AND user_id = ?"
293
+ " AND receipt_type = ?"
294
+ )
295
+ txn.execute(sql, (user_id, receipt_type))
296
+ return cast(list[tuple[str, str, int, int]], txn.fetchall())
297
+
298
+ rows = await self.db_pool.runInteraction(
299
+ "get_receipts_for_user_with_orderings", f
300
+ )
301
+ return {
302
+ row[0]: {
303
+ "event_id": row[1],
304
+ "topological_ordering": row[2],
305
+ "stream_ordering": row[3],
306
+ }
307
+ for row in rows
308
+ }
309
+
310
+ async def get_linearized_receipts_for_rooms(
311
+ self,
312
+ room_ids: Iterable[str],
313
+ to_key: MultiWriterStreamToken,
314
+ from_key: Optional[MultiWriterStreamToken] = None,
315
+ ) -> list[JsonMapping]:
316
+ """Get receipts for multiple rooms for sending to clients.
317
+
318
+ Args:
319
+ room_id: The room IDs to fetch receipts of.
320
+ to_key: Max stream id to fetch receipts up to.
321
+ from_key: Min stream id to fetch receipts from. None fetches
322
+ from the start.
323
+
324
+ Returns:
325
+ A list of receipts.
326
+ """
327
+ room_ids = set(room_ids)
328
+
329
+ if from_key is not None:
330
+ # Only ask the database about rooms where there have been new
331
+ # receipts added since `from_key`
332
+ room_ids = self._receipts_stream_cache.get_entities_changed(
333
+ room_ids, from_key.stream
334
+ )
335
+
336
+ results = await self._get_linearized_receipts_for_rooms(
337
+ room_ids, to_key, from_key=from_key
338
+ )
339
+
340
+ return [ev for res in results.values() for ev in res]
341
+
342
+ async def get_linearized_receipts_for_room(
343
+ self,
344
+ room_id: str,
345
+ to_key: MultiWriterStreamToken,
346
+ from_key: Optional[MultiWriterStreamToken] = None,
347
+ ) -> Sequence[JsonMapping]:
348
+ """Get receipts for a single room for sending to clients.
349
+
350
+ Args:
351
+ room_ids: The room id.
352
+ to_key: Max stream id to fetch receipts up to.
353
+ from_key: Min stream id to fetch receipts from. None fetches
354
+ from the start.
355
+
356
+ Returns:
357
+ A list of receipts.
358
+ """
359
+ if from_key is not None:
360
+ # Check the cache first to see if any new receipts have been added
361
+ # since`from_key`. If not we can no-op.
362
+ if not self._receipts_stream_cache.has_entity_changed(
363
+ room_id, from_key.stream
364
+ ):
365
+ return []
366
+
367
+ return await self._get_linearized_receipts_for_room(room_id, to_key, from_key)
368
+
369
+ @cached(tree=True)
370
+ async def _get_linearized_receipts_for_room(
371
+ self,
372
+ room_id: str,
373
+ to_key: MultiWriterStreamToken,
374
+ from_key: Optional[MultiWriterStreamToken] = None,
375
+ ) -> Sequence[JsonMapping]:
376
+ """See get_linearized_receipts_for_room"""
377
+
378
+ def f(txn: LoggingTransaction) -> list[tuple[str, str, str, str]]:
379
+ if from_key:
380
+ sql = """
381
+ SELECT stream_id, instance_name, receipt_type, user_id, event_id, data
382
+ FROM receipts_linearized
383
+ WHERE room_id = ? AND stream_id > ? AND stream_id <= ?
384
+ """
385
+
386
+ txn.execute(
387
+ sql, (room_id, from_key.stream, to_key.get_max_stream_pos())
388
+ )
389
+ else:
390
+ sql = """
391
+ SELECT stream_id, instance_name, receipt_type, user_id, event_id, data
392
+ FROM receipts_linearized WHERE
393
+ room_id = ? AND stream_id <= ?
394
+ """
395
+
396
+ txn.execute(sql, (room_id, to_key.get_max_stream_pos()))
397
+
398
+ return [
399
+ (receipt_type, user_id, event_id, data)
400
+ for stream_id, instance_name, receipt_type, user_id, event_id, data in txn
401
+ if MultiWriterStreamToken.is_stream_position_in_range(
402
+ from_key, to_key, instance_name, stream_id
403
+ )
404
+ ]
405
+
406
+ rows = await self.db_pool.runInteraction("get_linearized_receipts_for_room", f)
407
+
408
+ if not rows:
409
+ return []
410
+
411
+ content: JsonDict = {}
412
+ for receipt_type, user_id, event_id, data in rows:
413
+ content.setdefault(event_id, {}).setdefault(receipt_type, {})[user_id] = (
414
+ db_to_json(data)
415
+ )
416
+
417
+ return [{"type": EduTypes.RECEIPT, "room_id": room_id, "content": content}]
418
+
419
+ @cachedList(
420
+ cached_method_name="_get_linearized_receipts_for_room",
421
+ list_name="room_ids",
422
+ num_args=3,
423
+ )
424
+ async def _get_linearized_receipts_for_rooms(
425
+ self,
426
+ room_ids: Collection[str],
427
+ to_key: MultiWriterStreamToken,
428
+ from_key: Optional[MultiWriterStreamToken] = None,
429
+ ) -> Mapping[str, Sequence[JsonMapping]]:
430
+ if not room_ids:
431
+ return {}
432
+
433
+ def f(
434
+ txn: LoggingTransaction,
435
+ ) -> Mapping[str, Sequence[ReceiptInRoom]]:
436
+ if from_key:
437
+ sql = """
438
+ SELECT stream_id, instance_name, room_id, receipt_type,
439
+ user_id, event_id, thread_id, data
440
+ FROM receipts_linearized WHERE
441
+ stream_id > ? AND stream_id <= ? AND
442
+ """
443
+ clause, args = make_in_list_sql_clause(
444
+ self.database_engine, "room_id", room_ids
445
+ )
446
+
447
+ txn.execute(
448
+ sql + clause,
449
+ [from_key.stream, to_key.get_max_stream_pos()] + list(args),
450
+ )
451
+ else:
452
+ sql = """
453
+ SELECT stream_id, instance_name, room_id, receipt_type,
454
+ user_id, event_id, thread_id, data
455
+ FROM receipts_linearized WHERE
456
+ stream_id <= ? AND
457
+ """
458
+
459
+ clause, args = make_in_list_sql_clause(
460
+ self.database_engine, "room_id", room_ids
461
+ )
462
+
463
+ txn.execute(sql + clause, [to_key.get_max_stream_pos()] + list(args))
464
+
465
+ results: dict[str, list[ReceiptInRoom]] = {}
466
+ for (
467
+ stream_id,
468
+ instance_name,
469
+ room_id,
470
+ receipt_type,
471
+ user_id,
472
+ event_id,
473
+ thread_id,
474
+ data,
475
+ ) in txn:
476
+ if not MultiWriterStreamToken.is_stream_position_in_range(
477
+ from_key, to_key, instance_name, stream_id
478
+ ):
479
+ continue
480
+
481
+ results.setdefault(room_id, []).append(
482
+ ReceiptInRoom(
483
+ receipt_type=receipt_type,
484
+ user_id=user_id,
485
+ event_id=event_id,
486
+ thread_id=thread_id,
487
+ data=db_to_json(data),
488
+ )
489
+ )
490
+
491
+ return results
492
+
493
+ txn_results = await self.db_pool.runInteraction(
494
+ "_get_linearized_receipts_for_rooms", f
495
+ )
496
+
497
+ results: JsonDict = {
498
+ room_id: {
499
+ "room_id": room_id,
500
+ "type": EduTypes.RECEIPT,
501
+ "content": ReceiptInRoom.merge_to_content(receipts),
502
+ }
503
+ for room_id, receipts in txn_results.items()
504
+ }
505
+
506
+ results = {
507
+ room_id: [results[room_id]] if room_id in results else []
508
+ for room_id in room_ids
509
+ }
510
+ return results
511
+
512
+ async def get_linearized_receipts_for_events(
513
+ self,
514
+ room_and_event_ids: Collection[tuple[str, str]],
515
+ ) -> Mapping[str, Sequence[ReceiptInRoom]]:
516
+ """Get all receipts for the given set of events.
517
+
518
+ Arguments:
519
+ room_and_event_ids: A collection of 2-tuples of room ID and
520
+ event IDs to fetch receipts for
521
+
522
+ Returns:
523
+ A list of receipts, one per room.
524
+ """
525
+ if not room_and_event_ids:
526
+ return {}
527
+
528
+ def get_linearized_receipts_for_events_txn(
529
+ txn: LoggingTransaction,
530
+ room_id_event_id_tuples: Collection[tuple[str, str]],
531
+ ) -> list[tuple[str, str, str, str, Optional[str], str]]:
532
+ clause, args = make_tuple_in_list_sql_clause(
533
+ self.database_engine, ("room_id", "event_id"), room_id_event_id_tuples
534
+ )
535
+
536
+ sql = f"""
537
+ SELECT room_id, receipt_type, user_id, event_id, thread_id, data
538
+ FROM receipts_linearized
539
+ WHERE {clause}
540
+ """
541
+
542
+ txn.execute(sql, args)
543
+
544
+ return txn.fetchall()
545
+
546
+ # room_id -> receipts
547
+ room_to_receipts: dict[str, list[ReceiptInRoom]] = {}
548
+ for batch in batch_iter(room_and_event_ids, 1000):
549
+ batch_results = await self.db_pool.runInteraction(
550
+ "get_linearized_receipts_for_events",
551
+ get_linearized_receipts_for_events_txn,
552
+ batch,
553
+ )
554
+
555
+ for (
556
+ room_id,
557
+ receipt_type,
558
+ user_id,
559
+ event_id,
560
+ thread_id,
561
+ data,
562
+ ) in batch_results:
563
+ room_to_receipts.setdefault(room_id, []).append(
564
+ ReceiptInRoom(
565
+ receipt_type=receipt_type,
566
+ user_id=user_id,
567
+ event_id=event_id,
568
+ thread_id=thread_id,
569
+ data=db_to_json(data),
570
+ )
571
+ )
572
+
573
+ return room_to_receipts
574
+
575
+ @cached(
576
+ num_args=2,
577
+ )
578
+ async def get_linearized_receipts_for_all_rooms(
579
+ self,
580
+ to_key: MultiWriterStreamToken,
581
+ from_key: Optional[MultiWriterStreamToken] = None,
582
+ ) -> Mapping[str, JsonMapping]:
583
+ """Get receipts for all rooms between two stream_ids, up
584
+ to a limit of the latest 100 read receipts.
585
+
586
+ Args:
587
+ to_key: Max stream id to fetch receipts up to.
588
+ from_key: Min stream id to fetch receipts from. None fetches
589
+ from the start.
590
+
591
+ Returns:
592
+ A dictionary of roomids to a list of receipts.
593
+ """
594
+
595
+ def f(txn: LoggingTransaction) -> list[tuple[str, str, str, str, str]]:
596
+ if from_key:
597
+ sql = """
598
+ SELECT stream_id, instance_name, room_id, receipt_type, user_id, event_id, data
599
+ FROM receipts_linearized WHERE
600
+ stream_id > ? AND stream_id <= ?
601
+ ORDER BY stream_id DESC
602
+ LIMIT 100
603
+ """
604
+ txn.execute(sql, [from_key.stream, to_key.get_max_stream_pos()])
605
+ else:
606
+ sql = """
607
+ SELECT stream_id, instance_name, room_id, receipt_type, user_id, event_id, data
608
+ FROM receipts_linearized WHERE
609
+ stream_id <= ?
610
+ ORDER BY stream_id DESC
611
+ LIMIT 100
612
+ """
613
+
614
+ txn.execute(sql, [to_key.get_max_stream_pos()])
615
+
616
+ return [
617
+ (room_id, receipt_type, user_id, event_id, data)
618
+ for stream_id, instance_name, room_id, receipt_type, user_id, event_id, data in txn
619
+ if MultiWriterStreamToken.is_stream_position_in_range(
620
+ from_key, to_key, instance_name, stream_id
621
+ )
622
+ ]
623
+
624
+ txn_results = await self.db_pool.runInteraction(
625
+ "get_linearized_receipts_for_all_rooms", f
626
+ )
627
+
628
+ results: JsonDict = {}
629
+ for room_id, receipt_type, user_id, event_id, data in txn_results:
630
+ # We want a single event per room, since we want to batch the
631
+ # receipts by room, event and type.
632
+ room_event = results.setdefault(
633
+ room_id,
634
+ {"type": EduTypes.RECEIPT, "room_id": room_id, "content": {}},
635
+ )
636
+
637
+ # The content is of the form:
638
+ # {"$foo:bar": { "read": { "@user:host": <receipt> }, .. }, .. }
639
+ event_entry = room_event["content"].setdefault(event_id, {})
640
+ receipt_type_dict = event_entry.setdefault(receipt_type, {})
641
+
642
+ receipt_type_dict[user_id] = db_to_json(data)
643
+
644
+ return results
645
+
646
+ async def get_linearized_receipts_for_user_in_rooms(
647
+ self, user_id: str, room_ids: StrCollection, to_key: MultiWriterStreamToken
648
+ ) -> Mapping[str, Sequence[ReceiptInRoom]]:
649
+ """Fetch all receipts for the user in the given room.
650
+
651
+ Returns:
652
+ A dict from room ID to receipts in the room.
653
+ """
654
+
655
+ def get_linearized_receipts_for_user_in_rooms_txn(
656
+ txn: LoggingTransaction,
657
+ batch_room_ids: StrCollection,
658
+ ) -> list[tuple[str, str, str, str, Optional[str], str]]:
659
+ clause, args = make_in_list_sql_clause(
660
+ self.database_engine, "room_id", batch_room_ids
661
+ )
662
+
663
+ sql = f"""
664
+ SELECT instance_name, stream_id, room_id, receipt_type, user_id, event_id, thread_id, data
665
+ FROM receipts_linearized
666
+ WHERE {clause} AND user_id = ? AND stream_id <= ?
667
+ """
668
+
669
+ args.append(user_id)
670
+ args.append(to_key.get_max_stream_pos())
671
+
672
+ txn.execute(sql, args)
673
+
674
+ return [
675
+ (room_id, receipt_type, user_id, event_id, thread_id, data)
676
+ for instance_name, stream_id, room_id, receipt_type, user_id, event_id, thread_id, data in txn
677
+ if MultiWriterStreamToken.is_stream_position_in_range(
678
+ low=None,
679
+ high=to_key,
680
+ instance_name=instance_name,
681
+ pos=stream_id,
682
+ )
683
+ ]
684
+
685
+ # room_id -> receipts
686
+ room_to_receipts: dict[str, list[ReceiptInRoom]] = {}
687
+ for batch in batch_iter(room_ids, 1000):
688
+ batch_results = await self.db_pool.runInteraction(
689
+ "get_linearized_receipts_for_events",
690
+ get_linearized_receipts_for_user_in_rooms_txn,
691
+ batch,
692
+ )
693
+
694
+ for (
695
+ room_id,
696
+ receipt_type,
697
+ user_id,
698
+ event_id,
699
+ thread_id,
700
+ data,
701
+ ) in batch_results:
702
+ room_to_receipts.setdefault(room_id, []).append(
703
+ ReceiptInRoom(
704
+ receipt_type=receipt_type,
705
+ user_id=user_id,
706
+ event_id=event_id,
707
+ thread_id=thread_id,
708
+ data=db_to_json(data),
709
+ )
710
+ )
711
+
712
+ return room_to_receipts
713
+
714
+ async def get_rooms_with_receipts_between(
715
+ self,
716
+ room_ids: StrCollection,
717
+ from_key: MultiWriterStreamToken,
718
+ to_key: MultiWriterStreamToken,
719
+ ) -> StrCollection:
720
+ """Given a set of room_ids, find out which ones (may) have receipts
721
+ between the two tokens (> `from_token` and <= `to_token`)."""
722
+
723
+ room_ids = self._receipts_stream_cache.get_entities_changed(
724
+ room_ids, from_key.stream
725
+ )
726
+ if not room_ids:
727
+ return []
728
+
729
+ def f(txn: LoggingTransaction, room_ids: StrCollection) -> StrCollection:
730
+ clause, args = make_in_list_sql_clause(
731
+ self.database_engine, "room_id", room_ids
732
+ )
733
+
734
+ sql = f"""
735
+ SELECT DISTINCT room_id FROM receipts_linearized
736
+ WHERE {clause} AND ? < stream_id AND stream_id <= ?
737
+ """
738
+ args.append(from_key.stream)
739
+ args.append(to_key.get_max_stream_pos())
740
+
741
+ txn.execute(sql, args)
742
+
743
+ return [room_id for (room_id,) in txn]
744
+
745
+ results: list[str] = []
746
+ for batch in batch_iter(room_ids, 1000):
747
+ batch_result = await self.db_pool.runInteraction(
748
+ "get_rooms_with_receipts_between", f, batch
749
+ )
750
+ results.extend(batch_result)
751
+
752
+ return results
753
+
754
+ async def get_users_sent_receipts_between(
755
+ self, last_id: int, current_id: int
756
+ ) -> list[str]:
757
+ """Get all users who sent receipts between `last_id` exclusive and
758
+ `current_id` inclusive.
759
+
760
+ Returns:
761
+ The list of users.
762
+ """
763
+
764
+ if last_id == current_id:
765
+ return []
766
+
767
+ def _get_users_sent_receipts_between_txn(txn: LoggingTransaction) -> list[str]:
768
+ sql = """
769
+ SELECT DISTINCT user_id FROM receipts_linearized
770
+ WHERE ? < stream_id AND stream_id <= ?
771
+ """
772
+ txn.execute(sql, (last_id, current_id))
773
+
774
+ return [r[0] for r in txn]
775
+
776
+ return await self.db_pool.runInteraction(
777
+ "get_users_sent_receipts_between", _get_users_sent_receipts_between_txn
778
+ )
779
+
780
+ async def get_all_updated_receipts(
781
+ self, instance_name: str, last_id: int, current_id: int, limit: int
782
+ ) -> tuple[
783
+ list[tuple[int, tuple[str, str, str, str, Optional[str], JsonDict]]], int, bool
784
+ ]:
785
+ """Get updates for receipts replication stream.
786
+
787
+ Args:
788
+ instance_name: The writer we want to fetch updates from. Unused
789
+ here since there is only ever one writer.
790
+ last_id: The token to fetch updates from. Exclusive.
791
+ current_id: The token to fetch updates up to. Inclusive.
792
+ limit: The requested limit for the number of rows to return. The
793
+ function may return more or fewer rows.
794
+
795
+ Returns:
796
+ A tuple consisting of: the updates, a token to use to fetch
797
+ subsequent updates, and whether we returned fewer rows than exists
798
+ between the requested tokens due to the limit.
799
+
800
+ The token returned can be used in a subsequent call to this
801
+ function to get further updatees.
802
+
803
+ The updates are a list of 2-tuples of stream ID and the row data
804
+ """
805
+
806
+ if last_id == current_id:
807
+ return [], current_id, False
808
+
809
+ def get_all_updated_receipts_txn(
810
+ txn: LoggingTransaction,
811
+ ) -> tuple[
812
+ list[tuple[int, tuple[str, str, str, str, Optional[str], JsonDict]]],
813
+ int,
814
+ bool,
815
+ ]:
816
+ sql = """
817
+ SELECT stream_id, room_id, receipt_type, user_id, event_id, thread_id, data
818
+ FROM receipts_linearized
819
+ WHERE ? < stream_id AND stream_id <= ?
820
+ AND instance_name = ?
821
+ ORDER BY stream_id ASC
822
+ LIMIT ?
823
+ """
824
+ txn.execute(sql, (last_id, current_id, instance_name, limit))
825
+
826
+ updates = cast(
827
+ list[tuple[int, tuple[str, str, str, str, Optional[str], JsonDict]]],
828
+ [(r[0], r[1:6] + (db_to_json(r[6]),)) for r in txn],
829
+ )
830
+
831
+ limited = False
832
+ upper_bound = current_id
833
+
834
+ if len(updates) == limit:
835
+ limited = True
836
+ upper_bound = updates[-1][0]
837
+
838
+ return updates, upper_bound, limited
839
+
840
+ return await self.db_pool.runInteraction(
841
+ "get_all_updated_receipts", get_all_updated_receipts_txn
842
+ )
843
+
844
+ def invalidate_caches_for_receipt(
845
+ self, room_id: str, receipt_type: str, user_id: str
846
+ ) -> None:
847
+ self._get_receipts_for_user_with_orderings.invalidate((user_id, receipt_type))
848
+ self._get_linearized_receipts_for_room.invalidate((room_id,))
849
+
850
+ # We use this method to invalidate so that we don't end up with circular
851
+ # dependencies between the receipts and push action stores.
852
+ self._attempt_to_invalidate_cache(
853
+ "get_unread_event_push_actions_by_room_for_user", (room_id,)
854
+ )
855
+
856
+ def process_replication_rows(
857
+ self,
858
+ stream_name: str,
859
+ instance_name: str,
860
+ token: int,
861
+ rows: Iterable[Any],
862
+ ) -> None:
863
+ if stream_name == ReceiptsStream.NAME:
864
+ self._receipts_id_gen.advance(instance_name, token)
865
+ for row in rows:
866
+ self.invalidate_caches_for_receipt(
867
+ row.room_id, row.receipt_type, row.user_id
868
+ )
869
+ self._receipts_stream_cache.entity_has_changed(row.room_id, token)
870
+
871
+ return super().process_replication_rows(stream_name, instance_name, token, rows)
872
+
873
+ def process_replication_position(
874
+ self, stream_name: str, instance_name: str, token: int
875
+ ) -> None:
876
+ if stream_name == ReceiptsStream.NAME:
877
+ self._receipts_id_gen.advance(instance_name, token)
878
+ super().process_replication_position(stream_name, instance_name, token)
879
+
880
+ def _insert_linearized_receipt_txn(
881
+ self,
882
+ txn: LoggingTransaction,
883
+ room_id: str,
884
+ receipt_type: str,
885
+ user_id: str,
886
+ event_id: str,
887
+ thread_id: Optional[str],
888
+ data: JsonDict,
889
+ stream_id: int,
890
+ ) -> Optional[int]:
891
+ """Inserts a receipt into the database if it's newer than the current one.
892
+
893
+ Returns:
894
+ None if the receipt is older than the current receipt
895
+ otherwise, the rx timestamp of the event that the receipt corresponds to
896
+ (or 0 if the event is unknown)
897
+ """
898
+ assert self._can_write_to_receipts
899
+
900
+ res = self.db_pool.simple_select_one_txn(
901
+ txn,
902
+ table="events",
903
+ retcols=["stream_ordering", "received_ts"],
904
+ keyvalues={"event_id": event_id},
905
+ allow_none=True,
906
+ )
907
+
908
+ stream_ordering = int(res[0]) if res else None
909
+ rx_ts = res[1] if res else 0
910
+
911
+ # We don't want to clobber receipts for more recent events, so we
912
+ # have to compare orderings of existing receipts
913
+ if stream_ordering is not None:
914
+ if thread_id is None:
915
+ thread_clause = "r.thread_id IS NULL"
916
+ thread_args: tuple[str, ...] = ()
917
+ else:
918
+ thread_clause = "r.thread_id = ?"
919
+ thread_args = (thread_id,)
920
+
921
+ # If the receipt doesn't have a stream ordering it is because we
922
+ # don't have the associated event, and so must be a remote receipt.
923
+ # Hence it's safe to just allow new receipts to clobber it.
924
+ sql = f"""
925
+ SELECT r.event_stream_ordering, r.event_id FROM receipts_linearized AS r
926
+ WHERE r.room_id = ? AND r.receipt_type = ? AND r.user_id = ?
927
+ AND r.event_stream_ordering IS NOT NULL AND {thread_clause}
928
+ """
929
+ txn.execute(
930
+ sql,
931
+ (
932
+ room_id,
933
+ receipt_type,
934
+ user_id,
935
+ )
936
+ + thread_args,
937
+ )
938
+
939
+ for so, eid in txn:
940
+ if int(so) >= stream_ordering:
941
+ logger.debug(
942
+ "Ignoring new receipt for %s in favour of existing "
943
+ "one for later event %s",
944
+ event_id,
945
+ eid,
946
+ )
947
+ return None
948
+
949
+ txn.call_after(
950
+ self.invalidate_caches_for_receipt, room_id, receipt_type, user_id
951
+ )
952
+
953
+ txn.call_after(
954
+ self._receipts_stream_cache.entity_has_changed, room_id, stream_id
955
+ )
956
+
957
+ keyvalues = {
958
+ "room_id": room_id,
959
+ "receipt_type": receipt_type,
960
+ "user_id": user_id,
961
+ }
962
+ where_clause = ""
963
+ if thread_id is None:
964
+ where_clause = "thread_id IS NULL"
965
+ else:
966
+ keyvalues["thread_id"] = thread_id
967
+
968
+ self.db_pool.simple_upsert_txn(
969
+ txn,
970
+ table="receipts_linearized",
971
+ keyvalues=keyvalues,
972
+ values={
973
+ "stream_id": stream_id,
974
+ "instance_name": self._instance_name,
975
+ "event_id": event_id,
976
+ "event_stream_ordering": stream_ordering,
977
+ "data": json_encoder.encode(data),
978
+ },
979
+ where_clause=where_clause,
980
+ )
981
+
982
+ return rx_ts
983
+
984
+ def _graph_to_linear(
985
+ self, txn: LoggingTransaction, room_id: str, event_ids: list[str]
986
+ ) -> str:
987
+ """
988
+ Generate a linearized event from a list of events (i.e. a list of forward
989
+ extremities in the room).
990
+
991
+ This should allow for calculation of the correct read receipt even if
992
+ servers have different event ordering.
993
+
994
+ Args:
995
+ txn: The transaction
996
+ room_id: The room ID the events are in.
997
+ event_ids: The list of event IDs to linearize.
998
+
999
+ Returns:
1000
+ The linearized event ID.
1001
+ """
1002
+ # TODO: Make this better.
1003
+ clause, args = make_in_list_sql_clause(
1004
+ self.database_engine, "event_id", event_ids
1005
+ )
1006
+
1007
+ sql = """
1008
+ SELECT event_id WHERE room_id = ? AND stream_ordering IN (
1009
+ SELECT max(stream_ordering) WHERE %s
1010
+ )
1011
+ """ % (clause,)
1012
+
1013
+ txn.execute(sql, [room_id] + list(args))
1014
+ rows = txn.fetchall()
1015
+ if rows:
1016
+ return rows[0][0]
1017
+ else:
1018
+ raise RuntimeError("Unrecognized event_ids: %r" % (event_ids,))
1019
+
1020
+ async def insert_receipt(
1021
+ self,
1022
+ room_id: str,
1023
+ receipt_type: str,
1024
+ user_id: str,
1025
+ event_ids: list[str],
1026
+ thread_id: Optional[str],
1027
+ data: dict,
1028
+ ) -> Optional[PersistedPosition]:
1029
+ """Insert a receipt, either from local client or remote server.
1030
+
1031
+ Automatically does conversion between linearized and graph
1032
+ representations.
1033
+
1034
+ Returns:
1035
+ The new receipts stream ID and token, if the receipt is newer than
1036
+ what was previously persisted. None, otherwise.
1037
+ """
1038
+ assert self._can_write_to_receipts
1039
+
1040
+ if not event_ids:
1041
+ return None
1042
+
1043
+ if len(event_ids) == 1:
1044
+ linearized_event_id = event_ids[0]
1045
+ else:
1046
+ # we need to points in graph -> linearized form.
1047
+ linearized_event_id = await self.db_pool.runInteraction(
1048
+ "insert_receipt_conv", self._graph_to_linear, room_id, event_ids
1049
+ )
1050
+
1051
+ async with self._receipts_id_gen.get_next() as stream_id:
1052
+ event_ts = await self.db_pool.runInteraction(
1053
+ "insert_linearized_receipt",
1054
+ self._insert_linearized_receipt_txn,
1055
+ room_id,
1056
+ receipt_type,
1057
+ user_id,
1058
+ linearized_event_id,
1059
+ thread_id,
1060
+ data,
1061
+ stream_id=stream_id,
1062
+ # Read committed is actually beneficial here because we check for a receipt with
1063
+ # greater stream order, and checking the very latest data at select time is better
1064
+ # than the data at transaction start time.
1065
+ isolation_level=IsolationLevel.READ_COMMITTED,
1066
+ )
1067
+
1068
+ # If the receipt was older than the currently persisted one, nothing to do.
1069
+ if event_ts is None:
1070
+ return None
1071
+
1072
+ now = self.clock.time_msec()
1073
+ logger.debug(
1074
+ "Receipt %s for event %s in %s (%i ms old)",
1075
+ receipt_type,
1076
+ linearized_event_id,
1077
+ room_id,
1078
+ now - event_ts,
1079
+ )
1080
+
1081
+ await self._insert_graph_receipt(
1082
+ room_id,
1083
+ receipt_type,
1084
+ user_id,
1085
+ event_ids,
1086
+ thread_id,
1087
+ data,
1088
+ )
1089
+
1090
+ return PersistedPosition(self._instance_name, stream_id)
1091
+
1092
+ async def _insert_graph_receipt(
1093
+ self,
1094
+ room_id: str,
1095
+ receipt_type: str,
1096
+ user_id: str,
1097
+ event_ids: list[str],
1098
+ thread_id: Optional[str],
1099
+ data: JsonDict,
1100
+ ) -> None:
1101
+ assert self._can_write_to_receipts
1102
+
1103
+ keyvalues = {
1104
+ "room_id": room_id,
1105
+ "receipt_type": receipt_type,
1106
+ "user_id": user_id,
1107
+ }
1108
+ where_clause = ""
1109
+ if thread_id is None:
1110
+ where_clause = "thread_id IS NULL"
1111
+ else:
1112
+ keyvalues["thread_id"] = thread_id
1113
+
1114
+ await self.db_pool.simple_upsert(
1115
+ desc="insert_graph_receipt",
1116
+ table="receipts_graph",
1117
+ keyvalues=keyvalues,
1118
+ values={
1119
+ "event_ids": json_encoder.encode(event_ids),
1120
+ "data": json_encoder.encode(data),
1121
+ },
1122
+ where_clause=where_clause,
1123
+ )
1124
+
1125
+ self._get_receipts_for_user_with_orderings.invalidate((user_id, receipt_type))
1126
+
1127
+ # FIXME: This shouldn't invalidate the whole cache
1128
+ self._get_linearized_receipts_for_room.invalidate((room_id,))
1129
+
1130
+
1131
+ class ReceiptsBackgroundUpdateStore(SQLBaseStore):
1132
+ POPULATE_RECEIPT_EVENT_STREAM_ORDERING = "populate_event_stream_ordering"
1133
+ RECEIPTS_LINEARIZED_UNIQUE_INDEX_UPDATE_NAME = "receipts_linearized_unique_index"
1134
+ RECEIPTS_GRAPH_UNIQUE_INDEX_UPDATE_NAME = "receipts_graph_unique_index"
1135
+
1136
+ def __init__(
1137
+ self,
1138
+ database: DatabasePool,
1139
+ db_conn: LoggingDatabaseConnection,
1140
+ hs: "HomeServer",
1141
+ ):
1142
+ super().__init__(database, db_conn, hs)
1143
+
1144
+ self.db_pool.updates.register_background_update_handler(
1145
+ self.POPULATE_RECEIPT_EVENT_STREAM_ORDERING,
1146
+ self._populate_receipt_event_stream_ordering,
1147
+ )
1148
+ self.db_pool.updates.register_background_update_handler(
1149
+ self.RECEIPTS_LINEARIZED_UNIQUE_INDEX_UPDATE_NAME,
1150
+ self._background_receipts_linearized_unique_index,
1151
+ )
1152
+ self.db_pool.updates.register_background_update_handler(
1153
+ self.RECEIPTS_GRAPH_UNIQUE_INDEX_UPDATE_NAME,
1154
+ self._background_receipts_graph_unique_index,
1155
+ )
1156
+ self.db_pool.updates.register_background_index_update(
1157
+ update_name="receipts_room_id_event_id_index",
1158
+ index_name="receipts_linearized_event_id",
1159
+ table="receipts_linearized",
1160
+ columns=("room_id", "event_id"),
1161
+ )
1162
+
1163
+ async def _populate_receipt_event_stream_ordering(
1164
+ self, progress: JsonDict, batch_size: int
1165
+ ) -> int:
1166
+ def _populate_receipt_event_stream_ordering_txn(
1167
+ txn: LoggingTransaction,
1168
+ ) -> bool:
1169
+ if "max_stream_id" in progress:
1170
+ max_stream_id = progress["max_stream_id"]
1171
+ else:
1172
+ txn.execute("SELECT max(stream_id) FROM receipts_linearized")
1173
+ res = txn.fetchone()
1174
+ if res is None or res[0] is None:
1175
+ return True
1176
+ else:
1177
+ max_stream_id = res[0]
1178
+
1179
+ start = progress.get("stream_id", 0)
1180
+ stop = start + batch_size
1181
+
1182
+ sql = """
1183
+ UPDATE receipts_linearized
1184
+ SET event_stream_ordering = (
1185
+ SELECT stream_ordering
1186
+ FROM events
1187
+ WHERE event_id = receipts_linearized.event_id
1188
+ )
1189
+ WHERE stream_id >= ? AND stream_id < ?
1190
+ """
1191
+ txn.execute(sql, (start, stop))
1192
+
1193
+ self.db_pool.updates._background_update_progress_txn(
1194
+ txn,
1195
+ self.POPULATE_RECEIPT_EVENT_STREAM_ORDERING,
1196
+ {
1197
+ "stream_id": stop,
1198
+ "max_stream_id": max_stream_id,
1199
+ },
1200
+ )
1201
+
1202
+ return stop > max_stream_id
1203
+
1204
+ finished = await self.db_pool.runInteraction(
1205
+ "_remove_devices_from_device_inbox_txn",
1206
+ _populate_receipt_event_stream_ordering_txn,
1207
+ )
1208
+
1209
+ if finished:
1210
+ await self.db_pool.updates._end_background_update(
1211
+ self.POPULATE_RECEIPT_EVENT_STREAM_ORDERING
1212
+ )
1213
+
1214
+ return batch_size
1215
+
1216
+ async def _background_receipts_linearized_unique_index(
1217
+ self, progress: dict, batch_size: int
1218
+ ) -> int:
1219
+ """Removes duplicate receipts and adds a unique index on
1220
+ `(room_id, receipt_type, user_id)` to `receipts_linearized`, for non-thread
1221
+ receipts."""
1222
+
1223
+ def _remote_duplicate_receipts_txn(txn: LoggingTransaction) -> None:
1224
+ ROW_ID_NAME = self.database_engine.row_id_name
1225
+ # Identify any duplicate receipts arising from
1226
+ # https://github.com/matrix-org/synapse/issues/14406.
1227
+ # The following query takes less than a minute on matrix.org.
1228
+ sql = """
1229
+ SELECT MAX(stream_id), room_id, receipt_type, user_id
1230
+ FROM receipts_linearized
1231
+ WHERE thread_id IS NULL
1232
+ GROUP BY room_id, receipt_type, user_id
1233
+ HAVING COUNT(*) > 1
1234
+ """
1235
+ txn.execute(sql)
1236
+ duplicate_keys = cast(list[tuple[int, str, str, str]], list(txn))
1237
+
1238
+ # Then remove duplicate receipts, keeping the one with the highest
1239
+ # `stream_id`. Since there might be duplicate rows with the same
1240
+ # `stream_id`, we delete by the ctid instead.
1241
+ for stream_id, room_id, receipt_type, user_id in duplicate_keys:
1242
+ sql = f"""
1243
+ SELECT {ROW_ID_NAME}
1244
+ FROM receipts_linearized
1245
+ WHERE
1246
+ room_id = ? AND
1247
+ receipt_type = ? AND
1248
+ user_id = ? AND
1249
+ thread_id IS NULL AND
1250
+ stream_id = ?
1251
+ LIMIT 1
1252
+ """
1253
+ txn.execute(sql, (room_id, receipt_type, user_id, stream_id))
1254
+ row_id = cast(tuple[str], txn.fetchone())[0]
1255
+
1256
+ sql = f"""
1257
+ DELETE FROM receipts_linearized
1258
+ WHERE
1259
+ room_id = ? AND
1260
+ receipt_type = ? AND
1261
+ user_id = ? AND
1262
+ thread_id IS NULL AND
1263
+ {ROW_ID_NAME} != ?
1264
+ """
1265
+ txn.execute(sql, (room_id, receipt_type, user_id, row_id))
1266
+
1267
+ await self.db_pool.runInteraction(
1268
+ self.RECEIPTS_LINEARIZED_UNIQUE_INDEX_UPDATE_NAME,
1269
+ _remote_duplicate_receipts_txn,
1270
+ )
1271
+
1272
+ await self.db_pool.updates.create_index_in_background(
1273
+ index_name="receipts_linearized_unique_index",
1274
+ table="receipts_linearized",
1275
+ columns=["room_id", "receipt_type", "user_id"],
1276
+ where_clause="thread_id IS NULL",
1277
+ unique=True,
1278
+ )
1279
+
1280
+ await self.db_pool.updates._end_background_update(
1281
+ self.RECEIPTS_LINEARIZED_UNIQUE_INDEX_UPDATE_NAME
1282
+ )
1283
+
1284
+ return 1
1285
+
1286
+ async def _background_receipts_graph_unique_index(
1287
+ self, progress: dict, batch_size: int
1288
+ ) -> int:
1289
+ """Removes duplicate receipts and adds a unique index on
1290
+ `(room_id, receipt_type, user_id)` to `receipts_graph`, for non-thread
1291
+ receipts."""
1292
+
1293
+ def _remote_duplicate_receipts_txn(txn: LoggingTransaction) -> None:
1294
+ # Identify any duplicate receipts arising from
1295
+ # https://github.com/matrix-org/synapse/issues/14406.
1296
+ # We expect the following query to use the per-thread receipt index and take
1297
+ # less than a minute.
1298
+ sql = """
1299
+ SELECT room_id, receipt_type, user_id FROM receipts_graph
1300
+ WHERE thread_id IS NULL
1301
+ GROUP BY room_id, receipt_type, user_id
1302
+ HAVING COUNT(*) > 1
1303
+ """
1304
+ txn.execute(sql)
1305
+ duplicate_keys = cast(list[tuple[str, str, str]], list(txn))
1306
+
1307
+ # Then remove all duplicate receipts.
1308
+ # We could be clever and try to keep the latest receipt out of every set of
1309
+ # duplicates, but it's far simpler to remove them all.
1310
+ for room_id, receipt_type, user_id in duplicate_keys:
1311
+ sql = """
1312
+ DELETE FROM receipts_graph
1313
+ WHERE
1314
+ room_id = ? AND
1315
+ receipt_type = ? AND
1316
+ user_id = ? AND
1317
+ thread_id IS NULL
1318
+ """
1319
+ txn.execute(sql, (room_id, receipt_type, user_id))
1320
+
1321
+ await self.db_pool.runInteraction(
1322
+ self.RECEIPTS_GRAPH_UNIQUE_INDEX_UPDATE_NAME,
1323
+ _remote_duplicate_receipts_txn,
1324
+ )
1325
+
1326
+ await self.db_pool.updates.create_index_in_background(
1327
+ index_name="receipts_graph_unique_index",
1328
+ table="receipts_graph",
1329
+ columns=["room_id", "receipt_type", "user_id"],
1330
+ where_clause="thread_id IS NULL",
1331
+ unique=True,
1332
+ )
1333
+
1334
+ await self.db_pool.updates._end_background_update(
1335
+ self.RECEIPTS_GRAPH_UNIQUE_INDEX_UPDATE_NAME
1336
+ )
1337
+
1338
+ return 1
1339
+
1340
+
1341
+ class ReceiptsStore(ReceiptsWorkerStore, ReceiptsBackgroundUpdateStore):
1342
+ pass