matrix-synapse 1.143.0__cp310-abi3-manylinux_2_28_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 (1058) hide show
  1. matrix_synapse-1.143.0.dist-info/AUTHORS.rst +51 -0
  2. matrix_synapse-1.143.0.dist-info/LICENSE-AGPL-3.0 +661 -0
  3. matrix_synapse-1.143.0.dist-info/LICENSE-COMMERCIAL +6 -0
  4. matrix_synapse-1.143.0.dist-info/METADATA +385 -0
  5. matrix_synapse-1.143.0.dist-info/RECORD +1058 -0
  6. matrix_synapse-1.143.0.dist-info/WHEEL +4 -0
  7. matrix_synapse-1.143.0.dist-info/entry_points.txt +14 -0
  8. synapse/__init__.py +97 -0
  9. synapse/_scripts/__init__.py +0 -0
  10. synapse/_scripts/export_signing_key.py +109 -0
  11. synapse/_scripts/generate_config.py +83 -0
  12. synapse/_scripts/generate_log_config.py +56 -0
  13. synapse/_scripts/generate_signing_key.py +55 -0
  14. synapse/_scripts/generate_workers_map.py +318 -0
  15. synapse/_scripts/hash_password.py +95 -0
  16. synapse/_scripts/move_remote_media_to_new_store.py +128 -0
  17. synapse/_scripts/register_new_matrix_user.py +402 -0
  18. synapse/_scripts/review_recent_signups.py +212 -0
  19. synapse/_scripts/synapse_port_db.py +1604 -0
  20. synapse/_scripts/synctl.py +365 -0
  21. synapse/_scripts/update_synapse_database.py +130 -0
  22. synapse/api/__init__.py +20 -0
  23. synapse/api/auth/__init__.py +207 -0
  24. synapse/api/auth/base.py +406 -0
  25. synapse/api/auth/internal.py +299 -0
  26. synapse/api/auth/mas.py +436 -0
  27. synapse/api/auth/msc3861_delegated.py +617 -0
  28. synapse/api/auth_blocking.py +144 -0
  29. synapse/api/constants.py +362 -0
  30. synapse/api/errors.py +907 -0
  31. synapse/api/filtering.py +537 -0
  32. synapse/api/presence.py +102 -0
  33. synapse/api/ratelimiting.py +480 -0
  34. synapse/api/room_versions.py +535 -0
  35. synapse/api/urls.py +118 -0
  36. synapse/app/__init__.py +60 -0
  37. synapse/app/_base.py +862 -0
  38. synapse/app/admin_cmd.py +388 -0
  39. synapse/app/appservice.py +30 -0
  40. synapse/app/client_reader.py +30 -0
  41. synapse/app/complement_fork_starter.py +206 -0
  42. synapse/app/event_creator.py +29 -0
  43. synapse/app/federation_reader.py +30 -0
  44. synapse/app/federation_sender.py +30 -0
  45. synapse/app/frontend_proxy.py +30 -0
  46. synapse/app/generic_worker.py +474 -0
  47. synapse/app/homeserver.py +505 -0
  48. synapse/app/media_repository.py +30 -0
  49. synapse/app/phone_stats_home.py +296 -0
  50. synapse/app/pusher.py +30 -0
  51. synapse/app/synchrotron.py +30 -0
  52. synapse/app/user_dir.py +31 -0
  53. synapse/appservice/__init__.py +458 -0
  54. synapse/appservice/api.py +567 -0
  55. synapse/appservice/scheduler.py +564 -0
  56. synapse/config/__init__.py +27 -0
  57. synapse/config/__main__.py +62 -0
  58. synapse/config/_base.py +1106 -0
  59. synapse/config/_base.pyi +215 -0
  60. synapse/config/_util.py +99 -0
  61. synapse/config/account_validity.py +116 -0
  62. synapse/config/api.py +141 -0
  63. synapse/config/appservice.py +210 -0
  64. synapse/config/auth.py +80 -0
  65. synapse/config/auto_accept_invites.py +43 -0
  66. synapse/config/background_updates.py +44 -0
  67. synapse/config/cache.py +231 -0
  68. synapse/config/captcha.py +90 -0
  69. synapse/config/cas.py +116 -0
  70. synapse/config/consent.py +73 -0
  71. synapse/config/database.py +184 -0
  72. synapse/config/emailconfig.py +367 -0
  73. synapse/config/experimental.py +595 -0
  74. synapse/config/federation.py +114 -0
  75. synapse/config/homeserver.py +141 -0
  76. synapse/config/jwt.py +55 -0
  77. synapse/config/key.py +447 -0
  78. synapse/config/logger.py +390 -0
  79. synapse/config/mas.py +192 -0
  80. synapse/config/matrixrtc.py +66 -0
  81. synapse/config/metrics.py +84 -0
  82. synapse/config/modules.py +40 -0
  83. synapse/config/oembed.py +185 -0
  84. synapse/config/oidc.py +509 -0
  85. synapse/config/password_auth_providers.py +82 -0
  86. synapse/config/push.py +64 -0
  87. synapse/config/ratelimiting.py +254 -0
  88. synapse/config/redis.py +74 -0
  89. synapse/config/registration.py +296 -0
  90. synapse/config/repository.py +311 -0
  91. synapse/config/retention.py +162 -0
  92. synapse/config/room.py +88 -0
  93. synapse/config/room_directory.py +165 -0
  94. synapse/config/saml2.py +251 -0
  95. synapse/config/server.py +1170 -0
  96. synapse/config/server_notices.py +84 -0
  97. synapse/config/spam_checker.py +66 -0
  98. synapse/config/sso.py +121 -0
  99. synapse/config/stats.py +54 -0
  100. synapse/config/third_party_event_rules.py +40 -0
  101. synapse/config/tls.py +192 -0
  102. synapse/config/tracer.py +71 -0
  103. synapse/config/user_directory.py +47 -0
  104. synapse/config/user_types.py +42 -0
  105. synapse/config/voip.py +59 -0
  106. synapse/config/workers.py +642 -0
  107. synapse/crypto/__init__.py +20 -0
  108. synapse/crypto/context_factory.py +278 -0
  109. synapse/crypto/event_signing.py +194 -0
  110. synapse/crypto/keyring.py +931 -0
  111. synapse/event_auth.py +1266 -0
  112. synapse/events/__init__.py +667 -0
  113. synapse/events/auto_accept_invites.py +216 -0
  114. synapse/events/builder.py +387 -0
  115. synapse/events/presence_router.py +243 -0
  116. synapse/events/snapshot.py +559 -0
  117. synapse/events/utils.py +924 -0
  118. synapse/events/validator.py +305 -0
  119. synapse/federation/__init__.py +22 -0
  120. synapse/federation/federation_base.py +382 -0
  121. synapse/federation/federation_client.py +2132 -0
  122. synapse/federation/federation_server.py +1540 -0
  123. synapse/federation/persistence.py +70 -0
  124. synapse/federation/send_queue.py +531 -0
  125. synapse/federation/sender/__init__.py +1164 -0
  126. synapse/federation/sender/per_destination_queue.py +886 -0
  127. synapse/federation/sender/transaction_manager.py +210 -0
  128. synapse/federation/transport/__init__.py +28 -0
  129. synapse/federation/transport/client.py +1199 -0
  130. synapse/federation/transport/server/__init__.py +334 -0
  131. synapse/federation/transport/server/_base.py +429 -0
  132. synapse/federation/transport/server/federation.py +910 -0
  133. synapse/federation/units.py +133 -0
  134. synapse/handlers/__init__.py +20 -0
  135. synapse/handlers/account.py +162 -0
  136. synapse/handlers/account_data.py +360 -0
  137. synapse/handlers/account_validity.py +361 -0
  138. synapse/handlers/admin.py +615 -0
  139. synapse/handlers/appservice.py +989 -0
  140. synapse/handlers/auth.py +2481 -0
  141. synapse/handlers/cas.py +413 -0
  142. synapse/handlers/deactivate_account.py +363 -0
  143. synapse/handlers/delayed_events.py +599 -0
  144. synapse/handlers/device.py +1870 -0
  145. synapse/handlers/devicemessage.py +399 -0
  146. synapse/handlers/directory.py +545 -0
  147. synapse/handlers/e2e_keys.py +1834 -0
  148. synapse/handlers/e2e_room_keys.py +455 -0
  149. synapse/handlers/event_auth.py +390 -0
  150. synapse/handlers/events.py +201 -0
  151. synapse/handlers/federation.py +2039 -0
  152. synapse/handlers/federation_event.py +2419 -0
  153. synapse/handlers/identity.py +812 -0
  154. synapse/handlers/initial_sync.py +528 -0
  155. synapse/handlers/jwt.py +120 -0
  156. synapse/handlers/message.py +2347 -0
  157. synapse/handlers/oidc.py +1801 -0
  158. synapse/handlers/pagination.py +768 -0
  159. synapse/handlers/password_policy.py +102 -0
  160. synapse/handlers/presence.py +2633 -0
  161. synapse/handlers/profile.py +655 -0
  162. synapse/handlers/push_rules.py +164 -0
  163. synapse/handlers/read_marker.py +79 -0
  164. synapse/handlers/receipts.py +351 -0
  165. synapse/handlers/register.py +1059 -0
  166. synapse/handlers/relations.py +623 -0
  167. synapse/handlers/reports.py +98 -0
  168. synapse/handlers/room.py +2448 -0
  169. synapse/handlers/room_list.py +632 -0
  170. synapse/handlers/room_member.py +2365 -0
  171. synapse/handlers/room_member_worker.py +146 -0
  172. synapse/handlers/room_policy.py +186 -0
  173. synapse/handlers/room_summary.py +1057 -0
  174. synapse/handlers/saml.py +524 -0
  175. synapse/handlers/search.py +723 -0
  176. synapse/handlers/send_email.py +209 -0
  177. synapse/handlers/set_password.py +71 -0
  178. synapse/handlers/sliding_sync/__init__.py +1701 -0
  179. synapse/handlers/sliding_sync/extensions.py +969 -0
  180. synapse/handlers/sliding_sync/room_lists.py +2262 -0
  181. synapse/handlers/sliding_sync/store.py +128 -0
  182. synapse/handlers/sso.py +1291 -0
  183. synapse/handlers/state_deltas.py +82 -0
  184. synapse/handlers/stats.py +321 -0
  185. synapse/handlers/sync.py +3106 -0
  186. synapse/handlers/thread_subscriptions.py +190 -0
  187. synapse/handlers/typing.py +606 -0
  188. synapse/handlers/ui_auth/__init__.py +48 -0
  189. synapse/handlers/ui_auth/checkers.py +332 -0
  190. synapse/handlers/user_directory.py +783 -0
  191. synapse/handlers/worker_lock.py +371 -0
  192. synapse/http/__init__.py +105 -0
  193. synapse/http/additional_resource.py +62 -0
  194. synapse/http/client.py +1373 -0
  195. synapse/http/connectproxyclient.py +316 -0
  196. synapse/http/federation/__init__.py +19 -0
  197. synapse/http/federation/matrix_federation_agent.py +490 -0
  198. synapse/http/federation/srv_resolver.py +196 -0
  199. synapse/http/federation/well_known_resolver.py +367 -0
  200. synapse/http/matrixfederationclient.py +1873 -0
  201. synapse/http/proxy.py +290 -0
  202. synapse/http/proxyagent.py +497 -0
  203. synapse/http/replicationagent.py +202 -0
  204. synapse/http/request_metrics.py +309 -0
  205. synapse/http/server.py +1110 -0
  206. synapse/http/servlet.py +1018 -0
  207. synapse/http/site.py +825 -0
  208. synapse/http/types.py +27 -0
  209. synapse/logging/__init__.py +31 -0
  210. synapse/logging/_remote.py +261 -0
  211. synapse/logging/_terse_json.py +95 -0
  212. synapse/logging/context.py +1209 -0
  213. synapse/logging/formatter.py +62 -0
  214. synapse/logging/handlers.py +99 -0
  215. synapse/logging/loggers.py +25 -0
  216. synapse/logging/opentracing.py +1132 -0
  217. synapse/logging/scopecontextmanager.py +160 -0
  218. synapse/media/_base.py +830 -0
  219. synapse/media/filepath.py +417 -0
  220. synapse/media/media_repository.py +1580 -0
  221. synapse/media/media_storage.py +702 -0
  222. synapse/media/oembed.py +277 -0
  223. synapse/media/preview_html.py +556 -0
  224. synapse/media/storage_provider.py +195 -0
  225. synapse/media/thumbnailer.py +833 -0
  226. synapse/media/url_previewer.py +875 -0
  227. synapse/metrics/__init__.py +748 -0
  228. synapse/metrics/_gc.py +219 -0
  229. synapse/metrics/_reactor_metrics.py +171 -0
  230. synapse/metrics/_types.py +38 -0
  231. synapse/metrics/background_process_metrics.py +555 -0
  232. synapse/metrics/common_usage_metrics.py +94 -0
  233. synapse/metrics/jemalloc.py +248 -0
  234. synapse/module_api/__init__.py +2131 -0
  235. synapse/module_api/callbacks/__init__.py +50 -0
  236. synapse/module_api/callbacks/account_validity_callbacks.py +106 -0
  237. synapse/module_api/callbacks/media_repository_callbacks.py +157 -0
  238. synapse/module_api/callbacks/ratelimit_callbacks.py +78 -0
  239. synapse/module_api/callbacks/spamchecker_callbacks.py +991 -0
  240. synapse/module_api/callbacks/third_party_event_rules_callbacks.py +592 -0
  241. synapse/module_api/errors.py +42 -0
  242. synapse/notifier.py +970 -0
  243. synapse/push/__init__.py +212 -0
  244. synapse/push/bulk_push_rule_evaluator.py +635 -0
  245. synapse/push/clientformat.py +126 -0
  246. synapse/push/emailpusher.py +333 -0
  247. synapse/push/httppusher.py +564 -0
  248. synapse/push/mailer.py +1010 -0
  249. synapse/push/presentable_names.py +216 -0
  250. synapse/push/push_tools.py +114 -0
  251. synapse/push/push_types.py +141 -0
  252. synapse/push/pusher.py +87 -0
  253. synapse/push/pusherpool.py +501 -0
  254. synapse/push/rulekinds.py +33 -0
  255. synapse/py.typed +0 -0
  256. synapse/replication/__init__.py +20 -0
  257. synapse/replication/http/__init__.py +68 -0
  258. synapse/replication/http/_base.py +468 -0
  259. synapse/replication/http/account_data.py +297 -0
  260. synapse/replication/http/deactivate_account.py +81 -0
  261. synapse/replication/http/delayed_events.py +62 -0
  262. synapse/replication/http/devices.py +254 -0
  263. synapse/replication/http/federation.py +334 -0
  264. synapse/replication/http/login.py +106 -0
  265. synapse/replication/http/membership.py +364 -0
  266. synapse/replication/http/presence.py +133 -0
  267. synapse/replication/http/push.py +156 -0
  268. synapse/replication/http/register.py +172 -0
  269. synapse/replication/http/send_events.py +182 -0
  270. synapse/replication/http/state.py +82 -0
  271. synapse/replication/http/streams.py +101 -0
  272. synapse/replication/tcp/__init__.py +56 -0
  273. synapse/replication/tcp/client.py +552 -0
  274. synapse/replication/tcp/commands.py +569 -0
  275. synapse/replication/tcp/context.py +41 -0
  276. synapse/replication/tcp/external_cache.py +156 -0
  277. synapse/replication/tcp/handler.py +922 -0
  278. synapse/replication/tcp/protocol.py +608 -0
  279. synapse/replication/tcp/redis.py +509 -0
  280. synapse/replication/tcp/resource.py +348 -0
  281. synapse/replication/tcp/streams/__init__.py +96 -0
  282. synapse/replication/tcp/streams/_base.py +765 -0
  283. synapse/replication/tcp/streams/events.py +287 -0
  284. synapse/replication/tcp/streams/federation.py +92 -0
  285. synapse/replication/tcp/streams/partial_state.py +80 -0
  286. synapse/res/providers.json +29 -0
  287. synapse/res/templates/_base.html +29 -0
  288. synapse/res/templates/account_previously_renewed.html +6 -0
  289. synapse/res/templates/account_renewed.html +6 -0
  290. synapse/res/templates/add_threepid.html +8 -0
  291. synapse/res/templates/add_threepid.txt +6 -0
  292. synapse/res/templates/add_threepid_failure.html +7 -0
  293. synapse/res/templates/add_threepid_success.html +6 -0
  294. synapse/res/templates/already_in_use.html +12 -0
  295. synapse/res/templates/already_in_use.txt +10 -0
  296. synapse/res/templates/auth_success.html +21 -0
  297. synapse/res/templates/invalid_token.html +6 -0
  298. synapse/res/templates/mail-Element.css +7 -0
  299. synapse/res/templates/mail-Vector.css +7 -0
  300. synapse/res/templates/mail-expiry.css +4 -0
  301. synapse/res/templates/mail.css +156 -0
  302. synapse/res/templates/notice_expiry.html +46 -0
  303. synapse/res/templates/notice_expiry.txt +7 -0
  304. synapse/res/templates/notif.html +51 -0
  305. synapse/res/templates/notif.txt +22 -0
  306. synapse/res/templates/notif_mail.html +59 -0
  307. synapse/res/templates/notif_mail.txt +10 -0
  308. synapse/res/templates/password_reset.html +10 -0
  309. synapse/res/templates/password_reset.txt +7 -0
  310. synapse/res/templates/password_reset_confirmation.html +15 -0
  311. synapse/res/templates/password_reset_failure.html +7 -0
  312. synapse/res/templates/password_reset_success.html +6 -0
  313. synapse/res/templates/recaptcha.html +42 -0
  314. synapse/res/templates/registration.html +12 -0
  315. synapse/res/templates/registration.txt +10 -0
  316. synapse/res/templates/registration_failure.html +6 -0
  317. synapse/res/templates/registration_success.html +6 -0
  318. synapse/res/templates/registration_token.html +18 -0
  319. synapse/res/templates/room.html +33 -0
  320. synapse/res/templates/room.txt +9 -0
  321. synapse/res/templates/sso.css +129 -0
  322. synapse/res/templates/sso_account_deactivated.html +25 -0
  323. synapse/res/templates/sso_auth_account_details.html +186 -0
  324. synapse/res/templates/sso_auth_account_details.js +116 -0
  325. synapse/res/templates/sso_auth_bad_user.html +26 -0
  326. synapse/res/templates/sso_auth_confirm.html +27 -0
  327. synapse/res/templates/sso_auth_success.html +26 -0
  328. synapse/res/templates/sso_error.html +71 -0
  329. synapse/res/templates/sso_footer.html +19 -0
  330. synapse/res/templates/sso_login_idp_picker.html +60 -0
  331. synapse/res/templates/sso_new_user_consent.html +30 -0
  332. synapse/res/templates/sso_partial_profile.html +19 -0
  333. synapse/res/templates/sso_redirect_confirm.html +39 -0
  334. synapse/res/templates/style.css +33 -0
  335. synapse/res/templates/terms.html +27 -0
  336. synapse/rest/__init__.py +197 -0
  337. synapse/rest/admin/__init__.py +390 -0
  338. synapse/rest/admin/_base.py +72 -0
  339. synapse/rest/admin/background_updates.py +171 -0
  340. synapse/rest/admin/devices.py +221 -0
  341. synapse/rest/admin/event_reports.py +173 -0
  342. synapse/rest/admin/events.py +69 -0
  343. synapse/rest/admin/experimental_features.py +137 -0
  344. synapse/rest/admin/federation.py +243 -0
  345. synapse/rest/admin/media.py +540 -0
  346. synapse/rest/admin/registration_tokens.py +358 -0
  347. synapse/rest/admin/rooms.py +1061 -0
  348. synapse/rest/admin/scheduled_tasks.py +70 -0
  349. synapse/rest/admin/server_notice_servlet.py +132 -0
  350. synapse/rest/admin/statistics.py +132 -0
  351. synapse/rest/admin/username_available.py +58 -0
  352. synapse/rest/admin/users.py +1606 -0
  353. synapse/rest/client/__init__.py +20 -0
  354. synapse/rest/client/_base.py +113 -0
  355. synapse/rest/client/account.py +930 -0
  356. synapse/rest/client/account_data.py +319 -0
  357. synapse/rest/client/account_validity.py +103 -0
  358. synapse/rest/client/appservice_ping.py +125 -0
  359. synapse/rest/client/auth.py +218 -0
  360. synapse/rest/client/auth_metadata.py +122 -0
  361. synapse/rest/client/capabilities.py +121 -0
  362. synapse/rest/client/delayed_events.py +165 -0
  363. synapse/rest/client/devices.py +587 -0
  364. synapse/rest/client/directory.py +211 -0
  365. synapse/rest/client/events.py +116 -0
  366. synapse/rest/client/filter.py +112 -0
  367. synapse/rest/client/initial_sync.py +65 -0
  368. synapse/rest/client/keys.py +678 -0
  369. synapse/rest/client/knock.py +104 -0
  370. synapse/rest/client/login.py +750 -0
  371. synapse/rest/client/login_token_request.py +127 -0
  372. synapse/rest/client/logout.py +93 -0
  373. synapse/rest/client/matrixrtc.py +52 -0
  374. synapse/rest/client/media.py +285 -0
  375. synapse/rest/client/mutual_rooms.py +93 -0
  376. synapse/rest/client/notifications.py +137 -0
  377. synapse/rest/client/openid.py +109 -0
  378. synapse/rest/client/password_policy.py +69 -0
  379. synapse/rest/client/presence.py +131 -0
  380. synapse/rest/client/profile.py +291 -0
  381. synapse/rest/client/push_rule.py +331 -0
  382. synapse/rest/client/pusher.py +181 -0
  383. synapse/rest/client/read_marker.py +104 -0
  384. synapse/rest/client/receipts.py +165 -0
  385. synapse/rest/client/register.py +1067 -0
  386. synapse/rest/client/relations.py +138 -0
  387. synapse/rest/client/rendezvous.py +76 -0
  388. synapse/rest/client/reporting.py +207 -0
  389. synapse/rest/client/room.py +1669 -0
  390. synapse/rest/client/room_keys.py +426 -0
  391. synapse/rest/client/room_upgrade_rest_servlet.py +112 -0
  392. synapse/rest/client/sendtodevice.py +85 -0
  393. synapse/rest/client/sync.py +1131 -0
  394. synapse/rest/client/tags.py +129 -0
  395. synapse/rest/client/thirdparty.py +130 -0
  396. synapse/rest/client/thread_subscriptions.py +247 -0
  397. synapse/rest/client/tokenrefresh.py +52 -0
  398. synapse/rest/client/transactions.py +149 -0
  399. synapse/rest/client/user_directory.py +90 -0
  400. synapse/rest/client/versions.py +191 -0
  401. synapse/rest/client/voip.py +88 -0
  402. synapse/rest/consent/__init__.py +0 -0
  403. synapse/rest/consent/consent_resource.py +210 -0
  404. synapse/rest/health.py +38 -0
  405. synapse/rest/key/__init__.py +20 -0
  406. synapse/rest/key/v2/__init__.py +40 -0
  407. synapse/rest/key/v2/local_key_resource.py +125 -0
  408. synapse/rest/key/v2/remote_key_resource.py +302 -0
  409. synapse/rest/media/__init__.py +0 -0
  410. synapse/rest/media/config_resource.py +53 -0
  411. synapse/rest/media/create_resource.py +90 -0
  412. synapse/rest/media/download_resource.py +110 -0
  413. synapse/rest/media/media_repository_resource.py +113 -0
  414. synapse/rest/media/preview_url_resource.py +77 -0
  415. synapse/rest/media/thumbnail_resource.py +142 -0
  416. synapse/rest/media/upload_resource.py +187 -0
  417. synapse/rest/media/v1/__init__.py +39 -0
  418. synapse/rest/media/v1/_base.py +23 -0
  419. synapse/rest/media/v1/media_storage.py +23 -0
  420. synapse/rest/media/v1/storage_provider.py +23 -0
  421. synapse/rest/synapse/__init__.py +20 -0
  422. synapse/rest/synapse/client/__init__.py +93 -0
  423. synapse/rest/synapse/client/federation_whitelist.py +66 -0
  424. synapse/rest/synapse/client/jwks.py +77 -0
  425. synapse/rest/synapse/client/new_user_consent.py +115 -0
  426. synapse/rest/synapse/client/oidc/__init__.py +45 -0
  427. synapse/rest/synapse/client/oidc/backchannel_logout_resource.py +42 -0
  428. synapse/rest/synapse/client/oidc/callback_resource.py +48 -0
  429. synapse/rest/synapse/client/password_reset.py +129 -0
  430. synapse/rest/synapse/client/pick_idp.py +107 -0
  431. synapse/rest/synapse/client/pick_username.py +153 -0
  432. synapse/rest/synapse/client/rendezvous.py +58 -0
  433. synapse/rest/synapse/client/saml2/__init__.py +42 -0
  434. synapse/rest/synapse/client/saml2/metadata_resource.py +46 -0
  435. synapse/rest/synapse/client/saml2/response_resource.py +52 -0
  436. synapse/rest/synapse/client/sso_register.py +56 -0
  437. synapse/rest/synapse/client/unsubscribe.py +88 -0
  438. synapse/rest/synapse/mas/__init__.py +71 -0
  439. synapse/rest/synapse/mas/_base.py +55 -0
  440. synapse/rest/synapse/mas/devices.py +239 -0
  441. synapse/rest/synapse/mas/users.py +469 -0
  442. synapse/rest/well_known.py +148 -0
  443. synapse/server.py +1257 -0
  444. synapse/server_notices/__init__.py +0 -0
  445. synapse/server_notices/consent_server_notices.py +136 -0
  446. synapse/server_notices/resource_limits_server_notices.py +215 -0
  447. synapse/server_notices/server_notices_manager.py +388 -0
  448. synapse/server_notices/server_notices_sender.py +67 -0
  449. synapse/server_notices/worker_server_notices_sender.py +46 -0
  450. synapse/spam_checker_api/__init__.py +31 -0
  451. synapse/state/__init__.py +1022 -0
  452. synapse/state/v1.py +369 -0
  453. synapse/state/v2.py +984 -0
  454. synapse/static/client/login/index.html +47 -0
  455. synapse/static/client/login/js/jquery-3.4.1.min.js +2 -0
  456. synapse/static/client/login/js/login.js +291 -0
  457. synapse/static/client/login/spinner.gif +0 -0
  458. synapse/static/client/login/style.css +79 -0
  459. synapse/static/index.html +63 -0
  460. synapse/storage/__init__.py +43 -0
  461. synapse/storage/_base.py +245 -0
  462. synapse/storage/admin_client_config.py +25 -0
  463. synapse/storage/background_updates.py +1188 -0
  464. synapse/storage/controllers/__init__.py +57 -0
  465. synapse/storage/controllers/persist_events.py +1237 -0
  466. synapse/storage/controllers/purge_events.py +455 -0
  467. synapse/storage/controllers/state.py +950 -0
  468. synapse/storage/controllers/stats.py +119 -0
  469. synapse/storage/database.py +2719 -0
  470. synapse/storage/databases/__init__.py +175 -0
  471. synapse/storage/databases/main/__init__.py +420 -0
  472. synapse/storage/databases/main/account_data.py +1059 -0
  473. synapse/storage/databases/main/appservice.py +473 -0
  474. synapse/storage/databases/main/cache.py +911 -0
  475. synapse/storage/databases/main/censor_events.py +225 -0
  476. synapse/storage/databases/main/client_ips.py +815 -0
  477. synapse/storage/databases/main/delayed_events.py +562 -0
  478. synapse/storage/databases/main/deviceinbox.py +1271 -0
  479. synapse/storage/databases/main/devices.py +2578 -0
  480. synapse/storage/databases/main/directory.py +212 -0
  481. synapse/storage/databases/main/e2e_room_keys.py +689 -0
  482. synapse/storage/databases/main/end_to_end_keys.py +1894 -0
  483. synapse/storage/databases/main/event_federation.py +2508 -0
  484. synapse/storage/databases/main/event_push_actions.py +1933 -0
  485. synapse/storage/databases/main/events.py +3765 -0
  486. synapse/storage/databases/main/events_bg_updates.py +2910 -0
  487. synapse/storage/databases/main/events_forward_extremities.py +126 -0
  488. synapse/storage/databases/main/events_worker.py +2786 -0
  489. synapse/storage/databases/main/experimental_features.py +130 -0
  490. synapse/storage/databases/main/filtering.py +231 -0
  491. synapse/storage/databases/main/keys.py +291 -0
  492. synapse/storage/databases/main/lock.py +553 -0
  493. synapse/storage/databases/main/media_repository.py +1068 -0
  494. synapse/storage/databases/main/metrics.py +460 -0
  495. synapse/storage/databases/main/monthly_active_users.py +443 -0
  496. synapse/storage/databases/main/openid.py +60 -0
  497. synapse/storage/databases/main/presence.py +509 -0
  498. synapse/storage/databases/main/profile.py +539 -0
  499. synapse/storage/databases/main/purge_events.py +521 -0
  500. synapse/storage/databases/main/push_rule.py +970 -0
  501. synapse/storage/databases/main/pusher.py +793 -0
  502. synapse/storage/databases/main/receipts.py +1341 -0
  503. synapse/storage/databases/main/registration.py +3072 -0
  504. synapse/storage/databases/main/rejections.py +37 -0
  505. synapse/storage/databases/main/relations.py +1116 -0
  506. synapse/storage/databases/main/room.py +2779 -0
  507. synapse/storage/databases/main/roommember.py +2110 -0
  508. synapse/storage/databases/main/search.py +939 -0
  509. synapse/storage/databases/main/session.py +151 -0
  510. synapse/storage/databases/main/signatures.py +94 -0
  511. synapse/storage/databases/main/sliding_sync.py +603 -0
  512. synapse/storage/databases/main/state.py +1002 -0
  513. synapse/storage/databases/main/state_deltas.py +329 -0
  514. synapse/storage/databases/main/stats.py +789 -0
  515. synapse/storage/databases/main/stream.py +2577 -0
  516. synapse/storage/databases/main/tags.py +360 -0
  517. synapse/storage/databases/main/task_scheduler.py +225 -0
  518. synapse/storage/databases/main/thread_subscriptions.py +589 -0
  519. synapse/storage/databases/main/transactions.py +675 -0
  520. synapse/storage/databases/main/ui_auth.py +420 -0
  521. synapse/storage/databases/main/user_directory.py +1330 -0
  522. synapse/storage/databases/main/user_erasure_store.py +117 -0
  523. synapse/storage/databases/state/__init__.py +22 -0
  524. synapse/storage/databases/state/bg_updates.py +497 -0
  525. synapse/storage/databases/state/deletion.py +557 -0
  526. synapse/storage/databases/state/store.py +948 -0
  527. synapse/storage/engines/__init__.py +70 -0
  528. synapse/storage/engines/_base.py +154 -0
  529. synapse/storage/engines/postgres.py +261 -0
  530. synapse/storage/engines/sqlite.py +199 -0
  531. synapse/storage/invite_rule.py +112 -0
  532. synapse/storage/keys.py +40 -0
  533. synapse/storage/prepare_database.py +730 -0
  534. synapse/storage/push_rule.py +28 -0
  535. synapse/storage/roommember.py +88 -0
  536. synapse/storage/schema/README.md +4 -0
  537. synapse/storage/schema/__init__.py +186 -0
  538. synapse/storage/schema/common/delta/25/00background_updates.sql +40 -0
  539. synapse/storage/schema/common/delta/35/00background_updates_add_col.sql +36 -0
  540. synapse/storage/schema/common/delta/58/00background_update_ordering.sql +38 -0
  541. synapse/storage/schema/common/full_schemas/72/full.sql.postgres +8 -0
  542. synapse/storage/schema/common/full_schemas/72/full.sql.sqlite +6 -0
  543. synapse/storage/schema/common/schema_version.sql +60 -0
  544. synapse/storage/schema/main/delta/12/v12.sql +82 -0
  545. synapse/storage/schema/main/delta/13/v13.sql +38 -0
  546. synapse/storage/schema/main/delta/14/v14.sql +42 -0
  547. synapse/storage/schema/main/delta/15/appservice_txns.sql +50 -0
  548. synapse/storage/schema/main/delta/15/presence_indices.sql +2 -0
  549. synapse/storage/schema/main/delta/15/v15.sql +24 -0
  550. synapse/storage/schema/main/delta/16/events_order_index.sql +4 -0
  551. synapse/storage/schema/main/delta/16/remote_media_cache_index.sql +2 -0
  552. synapse/storage/schema/main/delta/16/remove_duplicates.sql +9 -0
  553. synapse/storage/schema/main/delta/16/room_alias_index.sql +3 -0
  554. synapse/storage/schema/main/delta/16/unique_constraints.sql +72 -0
  555. synapse/storage/schema/main/delta/16/users.sql +56 -0
  556. synapse/storage/schema/main/delta/17/drop_indexes.sql +37 -0
  557. synapse/storage/schema/main/delta/17/server_keys.sql +43 -0
  558. synapse/storage/schema/main/delta/17/user_threepids.sql +9 -0
  559. synapse/storage/schema/main/delta/18/server_keys_bigger_ints.sql +51 -0
  560. synapse/storage/schema/main/delta/19/event_index.sql +38 -0
  561. synapse/storage/schema/main/delta/20/dummy.sql +1 -0
  562. synapse/storage/schema/main/delta/20/pushers.py +93 -0
  563. synapse/storage/schema/main/delta/21/end_to_end_keys.sql +53 -0
  564. synapse/storage/schema/main/delta/21/receipts.sql +57 -0
  565. synapse/storage/schema/main/delta/22/receipts_index.sql +41 -0
  566. synapse/storage/schema/main/delta/22/user_threepids_unique.sql +19 -0
  567. synapse/storage/schema/main/delta/24/stats_reporting.sql +37 -0
  568. synapse/storage/schema/main/delta/25/fts.py +81 -0
  569. synapse/storage/schema/main/delta/25/guest_access.sql +44 -0
  570. synapse/storage/schema/main/delta/25/history_visibility.sql +44 -0
  571. synapse/storage/schema/main/delta/25/tags.sql +57 -0
  572. synapse/storage/schema/main/delta/26/account_data.sql +36 -0
  573. synapse/storage/schema/main/delta/27/account_data.sql +55 -0
  574. synapse/storage/schema/main/delta/27/forgotten_memberships.sql +45 -0
  575. synapse/storage/schema/main/delta/27/ts.py +61 -0
  576. synapse/storage/schema/main/delta/28/event_push_actions.sql +46 -0
  577. synapse/storage/schema/main/delta/28/events_room_stream.sql +39 -0
  578. synapse/storage/schema/main/delta/28/public_roms_index.sql +39 -0
  579. synapse/storage/schema/main/delta/28/receipts_user_id_index.sql +41 -0
  580. synapse/storage/schema/main/delta/28/upgrade_times.sql +40 -0
  581. synapse/storage/schema/main/delta/28/users_is_guest.sql +41 -0
  582. synapse/storage/schema/main/delta/29/push_actions.sql +54 -0
  583. synapse/storage/schema/main/delta/30/alias_creator.sql +35 -0
  584. synapse/storage/schema/main/delta/30/as_users.py +82 -0
  585. synapse/storage/schema/main/delta/30/deleted_pushers.sql +44 -0
  586. synapse/storage/schema/main/delta/30/presence_stream.sql +49 -0
  587. synapse/storage/schema/main/delta/30/public_rooms.sql +42 -0
  588. synapse/storage/schema/main/delta/30/push_rule_stream.sql +57 -0
  589. synapse/storage/schema/main/delta/30/threepid_guest_access_tokens.sql +43 -0
  590. synapse/storage/schema/main/delta/31/invites.sql +61 -0
  591. synapse/storage/schema/main/delta/31/local_media_repository_url_cache.sql +46 -0
  592. synapse/storage/schema/main/delta/31/pushers_0.py +92 -0
  593. synapse/storage/schema/main/delta/31/pushers_index.sql +41 -0
  594. synapse/storage/schema/main/delta/31/search_update.py +65 -0
  595. synapse/storage/schema/main/delta/32/events.sql +35 -0
  596. synapse/storage/schema/main/delta/32/openid.sql +9 -0
  597. synapse/storage/schema/main/delta/32/pusher_throttle.sql +42 -0
  598. synapse/storage/schema/main/delta/32/remove_indices.sql +52 -0
  599. synapse/storage/schema/main/delta/32/reports.sql +44 -0
  600. synapse/storage/schema/main/delta/33/access_tokens_device_index.sql +36 -0
  601. synapse/storage/schema/main/delta/33/devices.sql +40 -0
  602. synapse/storage/schema/main/delta/33/devices_for_e2e_keys.sql +38 -0
  603. synapse/storage/schema/main/delta/33/devices_for_e2e_keys_clear_unknown_device.sql +39 -0
  604. synapse/storage/schema/main/delta/33/event_fields.py +61 -0
  605. synapse/storage/schema/main/delta/33/remote_media_ts.py +43 -0
  606. synapse/storage/schema/main/delta/33/user_ips_index.sql +36 -0
  607. synapse/storage/schema/main/delta/34/appservice_stream.sql +42 -0
  608. synapse/storage/schema/main/delta/34/cache_stream.py +50 -0
  609. synapse/storage/schema/main/delta/34/device_inbox.sql +43 -0
  610. synapse/storage/schema/main/delta/34/push_display_name_rename.sql +39 -0
  611. synapse/storage/schema/main/delta/34/received_txn_purge.py +36 -0
  612. synapse/storage/schema/main/delta/35/contains_url.sql +36 -0
  613. synapse/storage/schema/main/delta/35/device_outbox.sql +58 -0
  614. synapse/storage/schema/main/delta/35/device_stream_id.sql +40 -0
  615. synapse/storage/schema/main/delta/35/event_push_actions_index.sql +36 -0
  616. synapse/storage/schema/main/delta/35/public_room_list_change_stream.sql +52 -0
  617. synapse/storage/schema/main/delta/35/stream_order_to_extrem.sql +56 -0
  618. synapse/storage/schema/main/delta/36/readd_public_rooms.sql +45 -0
  619. synapse/storage/schema/main/delta/37/remove_auth_idx.py +89 -0
  620. synapse/storage/schema/main/delta/37/user_threepids.sql +71 -0
  621. synapse/storage/schema/main/delta/38/postgres_fts_gist.sql +38 -0
  622. synapse/storage/schema/main/delta/39/appservice_room_list.sql +48 -0
  623. synapse/storage/schema/main/delta/39/device_federation_stream_idx.sql +35 -0
  624. synapse/storage/schema/main/delta/39/event_push_index.sql +36 -0
  625. synapse/storage/schema/main/delta/39/federation_out_position.sql +41 -0
  626. synapse/storage/schema/main/delta/39/membership_profile.sql +39 -0
  627. synapse/storage/schema/main/delta/40/current_state_idx.sql +36 -0
  628. synapse/storage/schema/main/delta/40/device_inbox.sql +40 -0
  629. synapse/storage/schema/main/delta/40/device_list_streams.sql +79 -0
  630. synapse/storage/schema/main/delta/40/event_push_summary.sql +57 -0
  631. synapse/storage/schema/main/delta/40/pushers.sql +58 -0
  632. synapse/storage/schema/main/delta/41/device_list_stream_idx.sql +36 -0
  633. synapse/storage/schema/main/delta/41/device_outbound_index.sql +35 -0
  634. synapse/storage/schema/main/delta/41/event_search_event_id_idx.sql +36 -0
  635. synapse/storage/schema/main/delta/41/ratelimit.sql +41 -0
  636. synapse/storage/schema/main/delta/42/current_state_delta.sql +48 -0
  637. synapse/storage/schema/main/delta/42/device_list_last_id.sql +52 -0
  638. synapse/storage/schema/main/delta/42/event_auth_state_only.sql +36 -0
  639. synapse/storage/schema/main/delta/42/user_dir.py +88 -0
  640. synapse/storage/schema/main/delta/43/blocked_rooms.sql +40 -0
  641. synapse/storage/schema/main/delta/43/quarantine_media.sql +36 -0
  642. synapse/storage/schema/main/delta/43/url_cache.sql +35 -0
  643. synapse/storage/schema/main/delta/43/user_share.sql +52 -0
  644. synapse/storage/schema/main/delta/44/expire_url_cache.sql +60 -0
  645. synapse/storage/schema/main/delta/45/group_server.sql +186 -0
  646. synapse/storage/schema/main/delta/45/profile_cache.sql +47 -0
  647. synapse/storage/schema/main/delta/46/drop_refresh_tokens.sql +36 -0
  648. synapse/storage/schema/main/delta/46/drop_unique_deleted_pushers.sql +54 -0
  649. synapse/storage/schema/main/delta/46/group_server.sql +51 -0
  650. synapse/storage/schema/main/delta/46/local_media_repository_url_idx.sql +43 -0
  651. synapse/storage/schema/main/delta/46/user_dir_null_room_ids.sql +54 -0
  652. synapse/storage/schema/main/delta/46/user_dir_typos.sql +43 -0
  653. synapse/storage/schema/main/delta/47/last_access_media.sql +35 -0
  654. synapse/storage/schema/main/delta/47/postgres_fts_gin.sql +36 -0
  655. synapse/storage/schema/main/delta/47/push_actions_staging.sql +47 -0
  656. synapse/storage/schema/main/delta/48/add_user_consent.sql +37 -0
  657. synapse/storage/schema/main/delta/48/add_user_ips_last_seen_index.sql +36 -0
  658. synapse/storage/schema/main/delta/48/deactivated_users.sql +44 -0
  659. synapse/storage/schema/main/delta/48/group_unique_indexes.py +67 -0
  660. synapse/storage/schema/main/delta/48/groups_joinable.sql +41 -0
  661. synapse/storage/schema/main/delta/49/add_user_consent_server_notice_sent.sql +39 -0
  662. synapse/storage/schema/main/delta/49/add_user_daily_visits.sql +40 -0
  663. synapse/storage/schema/main/delta/49/add_user_ips_last_seen_only_index.sql +36 -0
  664. synapse/storage/schema/main/delta/50/add_creation_ts_users_index.sql +38 -0
  665. synapse/storage/schema/main/delta/50/erasure_store.sql +40 -0
  666. synapse/storage/schema/main/delta/50/make_event_content_nullable.py +102 -0
  667. synapse/storage/schema/main/delta/51/e2e_room_keys.sql +58 -0
  668. synapse/storage/schema/main/delta/51/monthly_active_users.sql +46 -0
  669. synapse/storage/schema/main/delta/52/add_event_to_state_group_index.sql +38 -0
  670. synapse/storage/schema/main/delta/52/device_list_streams_unique_idx.sql +55 -0
  671. synapse/storage/schema/main/delta/52/e2e_room_keys.sql +72 -0
  672. synapse/storage/schema/main/delta/53/add_user_type_to_users.sql +38 -0
  673. synapse/storage/schema/main/delta/53/drop_sent_transactions.sql +35 -0
  674. synapse/storage/schema/main/delta/53/event_format_version.sql +35 -0
  675. synapse/storage/schema/main/delta/53/user_dir_populate.sql +49 -0
  676. synapse/storage/schema/main/delta/53/user_ips_index.sql +49 -0
  677. synapse/storage/schema/main/delta/53/user_share.sql +63 -0
  678. synapse/storage/schema/main/delta/53/user_threepid_id.sql +48 -0
  679. synapse/storage/schema/main/delta/53/users_in_public_rooms.sql +47 -0
  680. synapse/storage/schema/main/delta/54/account_validity_with_renewal.sql +49 -0
  681. synapse/storage/schema/main/delta/54/add_validity_to_server_keys.sql +42 -0
  682. synapse/storage/schema/main/delta/54/delete_forward_extremities.sql +42 -0
  683. synapse/storage/schema/main/delta/54/drop_legacy_tables.sql +49 -0
  684. synapse/storage/schema/main/delta/54/drop_presence_list.sql +35 -0
  685. synapse/storage/schema/main/delta/54/relations.sql +46 -0
  686. synapse/storage/schema/main/delta/54/stats.sql +99 -0
  687. synapse/storage/schema/main/delta/54/stats2.sql +47 -0
  688. synapse/storage/schema/main/delta/55/access_token_expiry.sql +37 -0
  689. synapse/storage/schema/main/delta/55/track_threepid_validations.sql +50 -0
  690. synapse/storage/schema/main/delta/55/users_alter_deactivated.sql +38 -0
  691. synapse/storage/schema/main/delta/56/add_spans_to_device_lists.sql +39 -0
  692. synapse/storage/schema/main/delta/56/current_state_events_membership.sql +41 -0
  693. synapse/storage/schema/main/delta/56/current_state_events_membership_mk2.sql +43 -0
  694. synapse/storage/schema/main/delta/56/delete_keys_from_deleted_backups.sql +44 -0
  695. synapse/storage/schema/main/delta/56/destinations_failure_ts.sql +44 -0
  696. synapse/storage/schema/main/delta/56/destinations_retry_interval_type.sql.postgres +18 -0
  697. synapse/storage/schema/main/delta/56/device_stream_id_insert.sql +39 -0
  698. synapse/storage/schema/main/delta/56/devices_last_seen.sql +43 -0
  699. synapse/storage/schema/main/delta/56/drop_unused_event_tables.sql +39 -0
  700. synapse/storage/schema/main/delta/56/event_expiry.sql +40 -0
  701. synapse/storage/schema/main/delta/56/event_labels.sql +49 -0
  702. synapse/storage/schema/main/delta/56/event_labels_background_update.sql +36 -0
  703. synapse/storage/schema/main/delta/56/fix_room_keys_index.sql +37 -0
  704. synapse/storage/schema/main/delta/56/hidden_devices.sql +37 -0
  705. synapse/storage/schema/main/delta/56/hidden_devices_fix.sql.sqlite +42 -0
  706. synapse/storage/schema/main/delta/56/nuke_empty_communities_from_db.sql +48 -0
  707. synapse/storage/schema/main/delta/56/public_room_list_idx.sql +35 -0
  708. synapse/storage/schema/main/delta/56/redaction_censor.sql +35 -0
  709. synapse/storage/schema/main/delta/56/redaction_censor2.sql +41 -0
  710. synapse/storage/schema/main/delta/56/redaction_censor3_fix_update.sql.postgres +25 -0
  711. synapse/storage/schema/main/delta/56/redaction_censor4.sql +35 -0
  712. synapse/storage/schema/main/delta/56/remove_tombstoned_rooms_from_directory.sql +38 -0
  713. synapse/storage/schema/main/delta/56/room_key_etag.sql +36 -0
  714. synapse/storage/schema/main/delta/56/room_membership_idx.sql +37 -0
  715. synapse/storage/schema/main/delta/56/room_retention.sql +52 -0
  716. synapse/storage/schema/main/delta/56/signing_keys.sql +75 -0
  717. synapse/storage/schema/main/delta/56/signing_keys_nonunique_signatures.sql +41 -0
  718. synapse/storage/schema/main/delta/56/stats_separated.sql +175 -0
  719. synapse/storage/schema/main/delta/56/unique_user_filter_index.py +46 -0
  720. synapse/storage/schema/main/delta/56/user_external_ids.sql +43 -0
  721. synapse/storage/schema/main/delta/56/users_in_public_rooms_idx.sql +36 -0
  722. synapse/storage/schema/main/delta/57/delete_old_current_state_events.sql +41 -0
  723. synapse/storage/schema/main/delta/57/device_list_remote_cache_stale.sql +44 -0
  724. synapse/storage/schema/main/delta/57/local_current_membership.py +111 -0
  725. synapse/storage/schema/main/delta/57/remove_sent_outbound_pokes.sql +40 -0
  726. synapse/storage/schema/main/delta/57/rooms_version_column.sql +43 -0
  727. synapse/storage/schema/main/delta/57/rooms_version_column_2.sql.postgres +35 -0
  728. synapse/storage/schema/main/delta/57/rooms_version_column_2.sql.sqlite +22 -0
  729. synapse/storage/schema/main/delta/57/rooms_version_column_3.sql.postgres +39 -0
  730. synapse/storage/schema/main/delta/57/rooms_version_column_3.sql.sqlite +23 -0
  731. synapse/storage/schema/main/delta/58/02remove_dup_outbound_pokes.sql +41 -0
  732. synapse/storage/schema/main/delta/58/03persist_ui_auth.sql +55 -0
  733. synapse/storage/schema/main/delta/58/05cache_instance.sql.postgres +30 -0
  734. synapse/storage/schema/main/delta/58/06dlols_unique_idx.py +83 -0
  735. synapse/storage/schema/main/delta/58/07add_method_to_thumbnail_constraint.sql.postgres +33 -0
  736. synapse/storage/schema/main/delta/58/07add_method_to_thumbnail_constraint.sql.sqlite +44 -0
  737. synapse/storage/schema/main/delta/58/07persist_ui_auth_ips.sql +44 -0
  738. synapse/storage/schema/main/delta/58/08_media_safe_from_quarantine.sql.postgres +18 -0
  739. synapse/storage/schema/main/delta/58/08_media_safe_from_quarantine.sql.sqlite +18 -0
  740. synapse/storage/schema/main/delta/58/09shadow_ban.sql +37 -0
  741. synapse/storage/schema/main/delta/58/10_pushrules_enabled_delete_obsolete.sql +47 -0
  742. synapse/storage/schema/main/delta/58/10drop_local_rejections_stream.sql +41 -0
  743. synapse/storage/schema/main/delta/58/10federation_pos_instance_name.sql +41 -0
  744. synapse/storage/schema/main/delta/58/11dehydration.sql +39 -0
  745. synapse/storage/schema/main/delta/58/11fallback.sql +43 -0
  746. synapse/storage/schema/main/delta/58/11user_id_seq.py +38 -0
  747. synapse/storage/schema/main/delta/58/12room_stats.sql +51 -0
  748. synapse/storage/schema/main/delta/58/13remove_presence_allow_inbound.sql +36 -0
  749. synapse/storage/schema/main/delta/58/14events_instance_name.sql +35 -0
  750. synapse/storage/schema/main/delta/58/14events_instance_name.sql.postgres +28 -0
  751. synapse/storage/schema/main/delta/58/15_catchup_destination_rooms.sql +61 -0
  752. synapse/storage/schema/main/delta/58/15unread_count.sql +45 -0
  753. synapse/storage/schema/main/delta/58/16populate_stats_process_rooms_fix.sql +41 -0
  754. synapse/storage/schema/main/delta/58/17_catchup_last_successful.sql +40 -0
  755. synapse/storage/schema/main/delta/58/18stream_positions.sql +41 -0
  756. synapse/storage/schema/main/delta/58/19instance_map.sql.postgres +25 -0
  757. synapse/storage/schema/main/delta/58/19txn_id.sql +59 -0
  758. synapse/storage/schema/main/delta/58/20instance_name_event_tables.sql +36 -0
  759. synapse/storage/schema/main/delta/58/20user_daily_visits.sql +37 -0
  760. synapse/storage/schema/main/delta/58/21as_device_stream.sql +36 -0
  761. synapse/storage/schema/main/delta/58/21drop_device_max_stream_id.sql +1 -0
  762. synapse/storage/schema/main/delta/58/22puppet_token.sql +36 -0
  763. synapse/storage/schema/main/delta/58/22users_have_local_media.sql +2 -0
  764. synapse/storage/schema/main/delta/58/23e2e_cross_signing_keys_idx.sql +36 -0
  765. synapse/storage/schema/main/delta/58/24drop_event_json_index.sql +38 -0
  766. synapse/storage/schema/main/delta/58/25user_external_ids_user_id_idx.sql +36 -0
  767. synapse/storage/schema/main/delta/58/26access_token_last_validated.sql +37 -0
  768. synapse/storage/schema/main/delta/58/27local_invites.sql +37 -0
  769. synapse/storage/schema/main/delta/58/28drop_last_used_column.sql.postgres +16 -0
  770. synapse/storage/schema/main/delta/58/28drop_last_used_column.sql.sqlite +62 -0
  771. synapse/storage/schema/main/delta/59/01ignored_user.py +85 -0
  772. synapse/storage/schema/main/delta/59/02shard_send_to_device.sql +37 -0
  773. synapse/storage/schema/main/delta/59/03shard_send_to_device_sequence.sql.postgres +25 -0
  774. synapse/storage/schema/main/delta/59/04_event_auth_chains.sql +71 -0
  775. synapse/storage/schema/main/delta/59/04_event_auth_chains.sql.postgres +16 -0
  776. synapse/storage/schema/main/delta/59/04drop_account_data.sql +36 -0
  777. synapse/storage/schema/main/delta/59/05cache_invalidation.sql +36 -0
  778. synapse/storage/schema/main/delta/59/06chain_cover_index.sql +36 -0
  779. synapse/storage/schema/main/delta/59/06shard_account_data.sql +39 -0
  780. synapse/storage/schema/main/delta/59/06shard_account_data.sql.postgres +32 -0
  781. synapse/storage/schema/main/delta/59/07shard_account_data_fix.sql +37 -0
  782. synapse/storage/schema/main/delta/59/08delete_pushers_for_deactivated_accounts.sql +39 -0
  783. synapse/storage/schema/main/delta/59/08delete_stale_pushers.sql +39 -0
  784. synapse/storage/schema/main/delta/59/09rejected_events_metadata.sql +45 -0
  785. synapse/storage/schema/main/delta/59/10delete_purged_chain_cover.sql +36 -0
  786. synapse/storage/schema/main/delta/59/11add_knock_members_to_stats.sql +39 -0
  787. synapse/storage/schema/main/delta/59/11drop_thumbnail_constraint.sql.postgres +22 -0
  788. synapse/storage/schema/main/delta/59/12account_validity_token_used_ts_ms.sql +37 -0
  789. synapse/storage/schema/main/delta/59/12presence_stream_instance.sql +37 -0
  790. synapse/storage/schema/main/delta/59/12presence_stream_instance_seq.sql.postgres +20 -0
  791. synapse/storage/schema/main/delta/59/13users_to_send_full_presence_to.sql +53 -0
  792. synapse/storage/schema/main/delta/59/14refresh_tokens.sql +53 -0
  793. synapse/storage/schema/main/delta/59/15locks.sql +56 -0
  794. synapse/storage/schema/main/delta/59/16federation_inbound_staging.sql +51 -0
  795. synapse/storage/schema/main/delta/60/01recreate_stream_ordering.sql.postgres +45 -0
  796. synapse/storage/schema/main/delta/60/02change_stream_ordering_columns.sql.postgres +30 -0
  797. synapse/storage/schema/main/delta/61/01change_appservices_txns.sql.postgres +23 -0
  798. synapse/storage/schema/main/delta/61/01insertion_event_lookups.sql +68 -0
  799. synapse/storage/schema/main/delta/61/02drop_redundant_room_depth_index.sql +37 -0
  800. synapse/storage/schema/main/delta/61/03recreate_min_depth.py +74 -0
  801. synapse/storage/schema/main/delta/62/01insertion_event_extremities.sql +43 -0
  802. synapse/storage/schema/main/delta/63/01create_registration_tokens.sql +42 -0
  803. synapse/storage/schema/main/delta/63/02delete_unlinked_email_pushers.sql +39 -0
  804. synapse/storage/schema/main/delta/63/02populate-rooms-creator.sql +36 -0
  805. synapse/storage/schema/main/delta/63/03session_store.sql +42 -0
  806. synapse/storage/schema/main/delta/63/04add_presence_stream_not_offline_index.sql +37 -0
  807. synapse/storage/schema/main/delta/64/01msc2716_chunk_to_batch_rename.sql.postgres +23 -0
  808. synapse/storage/schema/main/delta/64/01msc2716_chunk_to_batch_rename.sql.sqlite +37 -0
  809. synapse/storage/schema/main/delta/65/01msc2716_insertion_event_edges.sql +38 -0
  810. synapse/storage/schema/main/delta/65/03remove_hidden_devices_from_device_inbox.sql +41 -0
  811. synapse/storage/schema/main/delta/65/04_local_group_updates.sql +37 -0
  812. synapse/storage/schema/main/delta/65/05_remove_room_stats_historical_and_user_stats_historical.sql +38 -0
  813. synapse/storage/schema/main/delta/65/06remove_deleted_devices_from_device_inbox.sql +53 -0
  814. synapse/storage/schema/main/delta/65/07_arbitrary_relations.sql +37 -0
  815. synapse/storage/schema/main/delta/65/08_device_inbox_background_updates.sql +37 -0
  816. synapse/storage/schema/main/delta/65/10_expirable_refresh_tokens.sql +47 -0
  817. synapse/storage/schema/main/delta/65/11_devices_auth_provider_session.sql +46 -0
  818. synapse/storage/schema/main/delta/67/01drop_public_room_list_stream.sql +37 -0
  819. synapse/storage/schema/main/delta/68/01event_columns.sql +45 -0
  820. synapse/storage/schema/main/delta/68/02_msc2409_add_device_id_appservice_stream_type.sql +40 -0
  821. synapse/storage/schema/main/delta/68/03_delete_account_data_for_deactivated_accounts.sql +39 -0
  822. synapse/storage/schema/main/delta/68/04_refresh_tokens_index_next_token_id.sql +47 -0
  823. synapse/storage/schema/main/delta/68/04partial_state_rooms.sql +60 -0
  824. synapse/storage/schema/main/delta/68/05_delete_non_strings_from_event_search.sql.sqlite +22 -0
  825. synapse/storage/schema/main/delta/68/05partial_state_rooms_triggers.py +80 -0
  826. synapse/storage/schema/main/delta/68/06_msc3202_add_device_list_appservice_stream_type.sql +42 -0
  827. synapse/storage/schema/main/delta/69/01as_txn_seq.py +54 -0
  828. synapse/storage/schema/main/delta/69/01device_list_oubound_by_room.sql +57 -0
  829. synapse/storage/schema/main/delta/69/02cache_invalidation_index.sql +37 -0
  830. synapse/storage/schema/main/delta/70/01clean_table_purged_rooms.sql +39 -0
  831. synapse/storage/schema/main/delta/71/01rebuild_event_edges.sql.postgres +43 -0
  832. synapse/storage/schema/main/delta/71/01rebuild_event_edges.sql.sqlite +47 -0
  833. synapse/storage/schema/main/delta/71/01remove_noop_background_updates.sql +80 -0
  834. synapse/storage/schema/main/delta/71/02event_push_summary_unique.sql +37 -0
  835. synapse/storage/schema/main/delta/72/01add_room_type_to_state_stats.sql +38 -0
  836. synapse/storage/schema/main/delta/72/01event_push_summary_receipt.sql +54 -0
  837. synapse/storage/schema/main/delta/72/02event_push_actions_index.sql +38 -0
  838. synapse/storage/schema/main/delta/72/03bg_populate_events_columns.py +57 -0
  839. synapse/storage/schema/main/delta/72/03drop_event_reference_hashes.sql +36 -0
  840. synapse/storage/schema/main/delta/72/03remove_groups.sql +50 -0
  841. synapse/storage/schema/main/delta/72/04drop_column_application_services_state_last_txn.sql.postgres +17 -0
  842. synapse/storage/schema/main/delta/72/04drop_column_application_services_state_last_txn.sql.sqlite +40 -0
  843. synapse/storage/schema/main/delta/72/05receipts_event_stream_ordering.sql +38 -0
  844. synapse/storage/schema/main/delta/72/05remove_unstable_private_read_receipts.sql +38 -0
  845. synapse/storage/schema/main/delta/72/06add_consent_ts_to_users.sql +35 -0
  846. synapse/storage/schema/main/delta/72/06thread_notifications.sql +49 -0
  847. synapse/storage/schema/main/delta/72/07force_update_current_state_events_membership.py +67 -0
  848. synapse/storage/schema/main/delta/72/07thread_receipts.sql.postgres +30 -0
  849. synapse/storage/schema/main/delta/72/07thread_receipts.sql.sqlite +70 -0
  850. synapse/storage/schema/main/delta/72/08begin_cache_invalidation_seq_at_2.sql.postgres +23 -0
  851. synapse/storage/schema/main/delta/72/08thread_receipts.sql +39 -0
  852. synapse/storage/schema/main/delta/72/09partial_indices.sql.sqlite +56 -0
  853. synapse/storage/schema/main/delta/73/01event_failed_pull_attempts.sql +48 -0
  854. synapse/storage/schema/main/delta/73/02add_pusher_enabled.sql +35 -0
  855. synapse/storage/schema/main/delta/73/02room_id_indexes_for_purging.sql +41 -0
  856. synapse/storage/schema/main/delta/73/03pusher_device_id.sql +39 -0
  857. synapse/storage/schema/main/delta/73/03users_approved_column.sql +39 -0
  858. synapse/storage/schema/main/delta/73/04partial_join_details.sql +42 -0
  859. synapse/storage/schema/main/delta/73/04pending_device_list_updates.sql +47 -0
  860. synapse/storage/schema/main/delta/73/05old_push_actions.sql.postgres +22 -0
  861. synapse/storage/schema/main/delta/73/05old_push_actions.sql.sqlite +24 -0
  862. synapse/storage/schema/main/delta/73/06thread_notifications_thread_id_idx.sql +42 -0
  863. synapse/storage/schema/main/delta/73/08thread_receipts_non_null.sql.postgres +23 -0
  864. synapse/storage/schema/main/delta/73/08thread_receipts_non_null.sql.sqlite +76 -0
  865. synapse/storage/schema/main/delta/73/09partial_joined_via_destination.sql +37 -0
  866. synapse/storage/schema/main/delta/73/09threads_table.sql +49 -0
  867. synapse/storage/schema/main/delta/73/10_update_sqlite_fts4_tokenizer.py +71 -0
  868. synapse/storage/schema/main/delta/73/10login_tokens.sql +54 -0
  869. synapse/storage/schema/main/delta/73/11event_search_room_id_n_distinct.sql.postgres +33 -0
  870. synapse/storage/schema/main/delta/73/12refactor_device_list_outbound_pokes.sql +72 -0
  871. synapse/storage/schema/main/delta/73/13add_device_lists_index.sql +39 -0
  872. synapse/storage/schema/main/delta/73/20_un_partial_stated_room_stream.sql +51 -0
  873. synapse/storage/schema/main/delta/73/21_un_partial_stated_room_stream_seq.sql.postgres +20 -0
  874. synapse/storage/schema/main/delta/73/22_rebuild_user_dir_stats.sql +48 -0
  875. synapse/storage/schema/main/delta/73/22_un_partial_stated_event_stream.sql +53 -0
  876. synapse/storage/schema/main/delta/73/23_fix_thread_index.sql +52 -0
  877. synapse/storage/schema/main/delta/73/23_un_partial_stated_room_stream_seq.sql.postgres +20 -0
  878. synapse/storage/schema/main/delta/73/24_events_jump_to_date_index.sql +36 -0
  879. synapse/storage/schema/main/delta/73/25drop_presence.sql +36 -0
  880. synapse/storage/schema/main/delta/74/01_user_directory_stale_remote_users.sql +58 -0
  881. synapse/storage/schema/main/delta/74/02_set_device_id_for_pushers_bg_update.sql +38 -0
  882. synapse/storage/schema/main/delta/74/03_membership_tables_event_stream_ordering.sql.postgres +29 -0
  883. synapse/storage/schema/main/delta/74/03_membership_tables_event_stream_ordering.sql.sqlite +23 -0
  884. synapse/storage/schema/main/delta/74/03_room_membership_index.sql +38 -0
  885. synapse/storage/schema/main/delta/74/04_delete_e2e_backup_keys_for_deactivated_users.sql +36 -0
  886. synapse/storage/schema/main/delta/74/04_membership_tables_event_stream_ordering_triggers.py +87 -0
  887. synapse/storage/schema/main/delta/74/05_events_txn_id_device_id.sql +72 -0
  888. synapse/storage/schema/main/delta/74/90COMMENTS_destinations.sql.postgres +52 -0
  889. synapse/storage/schema/main/delta/76/01_add_profiles_full_user_id_column.sql +39 -0
  890. synapse/storage/schema/main/delta/76/02_add_user_filters_full_user_id_column.sql +39 -0
  891. synapse/storage/schema/main/delta/76/03_per_user_experimental_features.sql +46 -0
  892. synapse/storage/schema/main/delta/76/04_add_room_forgetter.sql +43 -0
  893. synapse/storage/schema/main/delta/77/01_add_profiles_not_valid_check.sql.postgres +16 -0
  894. synapse/storage/schema/main/delta/77/02_add_user_filters_not_valid_check.sql.postgres +16 -0
  895. synapse/storage/schema/main/delta/77/03bg_populate_full_user_id_profiles.sql +35 -0
  896. synapse/storage/schema/main/delta/77/04bg_populate_full_user_id_user_filters.sql +35 -0
  897. synapse/storage/schema/main/delta/77/05thread_notifications_backfill.sql +67 -0
  898. synapse/storage/schema/main/delta/77/06thread_notifications_not_null.sql.sqlite +102 -0
  899. synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_actions.sql.postgres +27 -0
  900. synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_actions_staging.sql.postgres +27 -0
  901. synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_summary.sql.postgres +29 -0
  902. synapse/storage/schema/main/delta/77/14bg_indices_event_stream_ordering.sql +39 -0
  903. synapse/storage/schema/main/delta/78/01_validate_and_update_profiles.py +99 -0
  904. synapse/storage/schema/main/delta/78/02_validate_and_update_user_filters.py +100 -0
  905. synapse/storage/schema/main/delta/78/03_remove_unused_indexes_user_filters.py +72 -0
  906. synapse/storage/schema/main/delta/78/03event_extremities_constraints.py +65 -0
  907. synapse/storage/schema/main/delta/78/04_add_full_user_id_index_user_filters.py +32 -0
  908. synapse/storage/schema/main/delta/79/03_read_write_locks_triggers.sql.postgres +102 -0
  909. synapse/storage/schema/main/delta/79/03_read_write_locks_triggers.sql.sqlite +72 -0
  910. synapse/storage/schema/main/delta/79/04_mitigate_stream_ordering_update_race.py +70 -0
  911. synapse/storage/schema/main/delta/79/05_read_write_locks_triggers.sql.postgres +69 -0
  912. synapse/storage/schema/main/delta/79/05_read_write_locks_triggers.sql.sqlite +65 -0
  913. synapse/storage/schema/main/delta/80/01_users_alter_locked.sql +35 -0
  914. synapse/storage/schema/main/delta/80/02_read_write_locks_unlogged.sql.postgres +30 -0
  915. synapse/storage/schema/main/delta/80/02_scheduled_tasks.sql +47 -0
  916. synapse/storage/schema/main/delta/80/03_read_write_locks_triggers.sql.postgres +37 -0
  917. synapse/storage/schema/main/delta/80/04_read_write_locks_deadlock.sql.postgres +71 -0
  918. synapse/storage/schema/main/delta/82/02_scheduled_tasks_index.sql +35 -0
  919. synapse/storage/schema/main/delta/82/04_add_indices_for_purging_rooms.sql +39 -0
  920. synapse/storage/schema/main/delta/82/05gaps.sql +44 -0
  921. synapse/storage/schema/main/delta/83/01_drop_old_tables.sql +43 -0
  922. synapse/storage/schema/main/delta/83/03_instance_name_receipts.sql.sqlite +17 -0
  923. synapse/storage/schema/main/delta/83/05_cross_signing_key_update_grant.sql +34 -0
  924. synapse/storage/schema/main/delta/83/06_event_push_summary_room.sql +36 -0
  925. synapse/storage/schema/main/delta/84/01_auth_links_stats.sql.postgres +20 -0
  926. synapse/storage/schema/main/delta/84/02_auth_links_index.sql +16 -0
  927. synapse/storage/schema/main/delta/84/03_auth_links_analyze.sql.postgres +16 -0
  928. synapse/storage/schema/main/delta/84/04_access_token_index.sql +15 -0
  929. synapse/storage/schema/main/delta/85/01_add_suspended.sql +14 -0
  930. synapse/storage/schema/main/delta/85/02_add_instance_names.sql +27 -0
  931. synapse/storage/schema/main/delta/85/03_new_sequences.sql.postgres +54 -0
  932. synapse/storage/schema/main/delta/85/04_cleanup_device_federation_outbox.sql +15 -0
  933. synapse/storage/schema/main/delta/85/05_add_instance_names_converted_pos.sql +16 -0
  934. synapse/storage/schema/main/delta/85/06_add_room_reports.sql +20 -0
  935. synapse/storage/schema/main/delta/86/01_authenticate_media.sql +15 -0
  936. synapse/storage/schema/main/delta/86/02_receipts_event_id_index.sql +15 -0
  937. synapse/storage/schema/main/delta/87/01_sliding_sync_memberships.sql +169 -0
  938. synapse/storage/schema/main/delta/87/02_per_connection_state.sql +81 -0
  939. synapse/storage/schema/main/delta/87/03_current_state_index.sql +19 -0
  940. synapse/storage/schema/main/delta/88/01_add_delayed_events.sql +43 -0
  941. synapse/storage/schema/main/delta/88/01_custom_profile_fields.sql +15 -0
  942. synapse/storage/schema/main/delta/88/02_fix_sliding_sync_membership_snapshots_forgotten_column.sql +21 -0
  943. synapse/storage/schema/main/delta/88/03_add_otk_ts_added_index.sql +18 -0
  944. synapse/storage/schema/main/delta/88/04_current_state_delta_index.sql +18 -0
  945. synapse/storage/schema/main/delta/88/05_drop_old_otks.sql.postgres +19 -0
  946. synapse/storage/schema/main/delta/88/05_drop_old_otks.sql.sqlite +19 -0
  947. synapse/storage/schema/main/delta/88/05_sliding_sync_room_config_index.sql +20 -0
  948. synapse/storage/schema/main/delta/88/06_events_received_ts_index.sql +17 -0
  949. synapse/storage/schema/main/delta/89/01_sliding_sync_membership_snapshot_index.sql +15 -0
  950. synapse/storage/schema/main/delta/90/01_add_column_participant_room_memberships_table.sql +16 -0
  951. synapse/storage/schema/main/delta/91/01_media_hash.sql +28 -0
  952. synapse/storage/schema/main/delta/92/01_remove_trigger.sql.postgres +16 -0
  953. synapse/storage/schema/main/delta/92/01_remove_trigger.sql.sqlite +16 -0
  954. synapse/storage/schema/main/delta/92/02_remove_populate_participant_bg_update.sql +17 -0
  955. synapse/storage/schema/main/delta/92/04_ss_membership_snapshot_idx.sql +16 -0
  956. synapse/storage/schema/main/delta/92/04_thread_subscriptions.sql +59 -0
  957. synapse/storage/schema/main/delta/92/04_thread_subscriptions_seq.sql.postgres +19 -0
  958. synapse/storage/schema/main/delta/92/05_fixup_max_depth_cap.sql +17 -0
  959. synapse/storage/schema/main/delta/92/05_thread_subscriptions_comments.sql.postgres +18 -0
  960. synapse/storage/schema/main/delta/92/06_device_federation_inbox_index.sql +16 -0
  961. synapse/storage/schema/main/delta/92/06_threads_last_sent_stream_ordering_comments.sql.postgres +24 -0
  962. synapse/storage/schema/main/delta/92/07_add_user_reports.sql +22 -0
  963. synapse/storage/schema/main/delta/92/07_event_txn_id_device_id_txn_id2.sql +15 -0
  964. synapse/storage/schema/main/delta/92/08_room_ban_redactions.sql +21 -0
  965. synapse/storage/schema/main/delta/92/08_thread_subscriptions_seq_fixup.sql.postgres +19 -0
  966. synapse/storage/schema/main/delta/92/09_thread_subscriptions_update.sql +20 -0
  967. synapse/storage/schema/main/delta/92/09_thread_subscriptions_update.sql.postgres +18 -0
  968. synapse/storage/schema/main/delta/93/01_add_delayed_events.sql +15 -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 +183 -0
  986. synapse/storage/util/__init__.py +20 -0
  987. synapse/storage/util/id_generators.py +928 -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 +91 -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 +908 -0
  1005. synapse/types/rest/__init__.py +25 -0
  1006. synapse/types/rest/client/__init__.py +413 -0
  1007. synapse/types/state.py +634 -0
  1008. synapse/types/storage/__init__.py +66 -0
  1009. synapse/util/__init__.py +169 -0
  1010. synapse/util/async_helpers.py +1045 -0
  1011. synapse/util/background_queue.py +142 -0
  1012. synapse/util/batching_queue.py +202 -0
  1013. synapse/util/caches/__init__.py +300 -0
  1014. synapse/util/caches/cached_call.py +143 -0
  1015. synapse/util/caches/deferred_cache.py +530 -0
  1016. synapse/util/caches/descriptors.py +692 -0
  1017. synapse/util/caches/dictionary_cache.py +346 -0
  1018. synapse/util/caches/expiringcache.py +249 -0
  1019. synapse/util/caches/lrucache.py +975 -0
  1020. synapse/util/caches/response_cache.py +322 -0
  1021. synapse/util/caches/stream_change_cache.py +370 -0
  1022. synapse/util/caches/treecache.py +189 -0
  1023. synapse/util/caches/ttlcache.py +197 -0
  1024. synapse/util/cancellation.py +63 -0
  1025. synapse/util/check_dependencies.py +335 -0
  1026. synapse/util/clock.py +567 -0
  1027. synapse/util/constants.py +22 -0
  1028. synapse/util/daemonize.py +165 -0
  1029. synapse/util/distributor.py +157 -0
  1030. synapse/util/events.py +134 -0
  1031. synapse/util/file_consumer.py +164 -0
  1032. synapse/util/frozenutils.py +57 -0
  1033. synapse/util/gai_resolver.py +178 -0
  1034. synapse/util/hash.py +38 -0
  1035. synapse/util/httpresourcetree.py +108 -0
  1036. synapse/util/iterutils.py +189 -0
  1037. synapse/util/json.py +56 -0
  1038. synapse/util/linked_list.py +156 -0
  1039. synapse/util/logcontext.py +46 -0
  1040. synapse/util/logformatter.py +28 -0
  1041. synapse/util/macaroons.py +325 -0
  1042. synapse/util/manhole.py +191 -0
  1043. synapse/util/metrics.py +339 -0
  1044. synapse/util/module_loader.py +116 -0
  1045. synapse/util/msisdn.py +51 -0
  1046. synapse/util/patch_inline_callbacks.py +250 -0
  1047. synapse/util/pydantic_models.py +63 -0
  1048. synapse/util/ratelimitutils.py +419 -0
  1049. synapse/util/retryutils.py +339 -0
  1050. synapse/util/rlimit.py +42 -0
  1051. synapse/util/rust.py +133 -0
  1052. synapse/util/sentinel.py +21 -0
  1053. synapse/util/stringutils.py +293 -0
  1054. synapse/util/task_scheduler.py +493 -0
  1055. synapse/util/templates.py +126 -0
  1056. synapse/util/threepids.py +123 -0
  1057. synapse/util/wheel_timer.py +112 -0
  1058. synapse/visibility.py +835 -0
@@ -0,0 +1,1330 @@
1
+ #
2
+ # This file is licensed under the Affero General Public License (AGPL) version 3.
3
+ #
4
+ # Copyright 2017 Vector Creations 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
+ import re
24
+ import unicodedata
25
+ from typing import (
26
+ TYPE_CHECKING,
27
+ Collection,
28
+ Iterable,
29
+ Sequence,
30
+ TypedDict,
31
+ cast,
32
+ )
33
+
34
+ import attr
35
+
36
+ from synapse.api.errors import StoreError
37
+ from synapse.synapse_rust import segmenter as icu
38
+ from synapse.util.stringutils import non_null_str_or_none
39
+
40
+ if TYPE_CHECKING:
41
+ from synapse.server import HomeServer
42
+
43
+ from synapse.api.constants import EventTypes, HistoryVisibility, JoinRules, UserTypes
44
+ from synapse.storage.database import (
45
+ DatabasePool,
46
+ LoggingDatabaseConnection,
47
+ LoggingTransaction,
48
+ )
49
+ from synapse.storage.databases.main.state import StateFilter
50
+ from synapse.storage.databases.main.state_deltas import StateDeltasStore
51
+ from synapse.storage.engines import PostgresEngine, Sqlite3Engine
52
+ from synapse.types import (
53
+ JsonDict,
54
+ UserID,
55
+ UserProfile,
56
+ get_domain_from_id,
57
+ get_localpart_from_id,
58
+ )
59
+
60
+ logger = logging.getLogger(__name__)
61
+
62
+ TEMP_TABLE = "_temp_populate_user_directory"
63
+
64
+
65
+ @attr.s(auto_attribs=True, frozen=True)
66
+ class _UserDirProfile:
67
+ """Helper type for the user directory code for an entry to be inserted into
68
+ the directory.
69
+ """
70
+
71
+ user_id: str
72
+
73
+ # If the display name or avatar URL are unexpected types, replace with None
74
+ display_name: str | None = attr.ib(default=None, converter=non_null_str_or_none)
75
+ avatar_url: str | None = attr.ib(default=None, converter=non_null_str_or_none)
76
+
77
+
78
+ class UserDirectoryBackgroundUpdateStore(StateDeltasStore):
79
+ # How many records do we calculate before sending it to
80
+ # add_users_who_share_private_rooms?
81
+ SHARE_PRIVATE_WORKING_SET = 500
82
+
83
+ def __init__(
84
+ self,
85
+ database: DatabasePool,
86
+ db_conn: LoggingDatabaseConnection,
87
+ hs: "HomeServer",
88
+ ) -> None:
89
+ super().__init__(database, db_conn, hs)
90
+
91
+ self.server_name: str = hs.hostname
92
+
93
+ self.db_pool.updates.register_background_update_handler(
94
+ "populate_user_directory_createtables",
95
+ self._populate_user_directory_createtables,
96
+ )
97
+ self.db_pool.updates.register_background_update_handler(
98
+ "populate_user_directory_process_rooms",
99
+ self._populate_user_directory_process_rooms,
100
+ )
101
+ self.db_pool.updates.register_background_update_handler(
102
+ "populate_user_directory_process_users",
103
+ self._populate_user_directory_process_users,
104
+ )
105
+ self.db_pool.updates.register_background_update_handler(
106
+ "populate_user_directory_cleanup", self._populate_user_directory_cleanup
107
+ )
108
+
109
+ async def _populate_user_directory_createtables(
110
+ self, progress: JsonDict, batch_size: int
111
+ ) -> int:
112
+ # Get all the rooms that we want to process.
113
+ def _make_staging_area(txn: LoggingTransaction) -> None:
114
+ sql = f"""
115
+ CREATE TABLE IF NOT EXISTS {TEMP_TABLE}_rooms AS
116
+ SELECT room_id, count(*) AS events
117
+ FROM current_state_events
118
+ GROUP BY room_id
119
+ """
120
+ txn.execute(sql)
121
+ txn.execute(
122
+ f"CREATE INDEX IF NOT EXISTS {TEMP_TABLE}_rooms_rm ON {TEMP_TABLE}_rooms (room_id)"
123
+ )
124
+ txn.execute(
125
+ f"CREATE INDEX IF NOT EXISTS {TEMP_TABLE}_rooms_evs ON {TEMP_TABLE}_rooms (events)"
126
+ )
127
+
128
+ sql = f"""
129
+ CREATE TABLE IF NOT EXISTS {TEMP_TABLE}_position (
130
+ position TEXT NOT NULL
131
+ )
132
+ """
133
+ txn.execute(sql)
134
+
135
+ sql = f"""
136
+ CREATE TABLE IF NOT EXISTS {TEMP_TABLE}_users AS
137
+ SELECT name AS user_id FROM users
138
+ """
139
+ txn.execute(sql)
140
+ txn.execute(
141
+ f"CREATE INDEX IF NOT EXISTS {TEMP_TABLE}_users_idx ON {TEMP_TABLE}_users (user_id)"
142
+ )
143
+
144
+ new_pos = await self.get_max_stream_id_in_current_state_deltas()
145
+ await self.db_pool.runInteraction(
146
+ "populate_user_directory_temp_build", _make_staging_area
147
+ )
148
+ await self.db_pool.simple_insert(
149
+ TEMP_TABLE + "_position", {"position": new_pos}
150
+ )
151
+
152
+ await self.db_pool.updates._end_background_update(
153
+ "populate_user_directory_createtables"
154
+ )
155
+ return 1
156
+
157
+ async def _populate_user_directory_cleanup(
158
+ self,
159
+ progress: JsonDict,
160
+ batch_size: int,
161
+ ) -> int:
162
+ """
163
+ Update the user directory stream position, then clean up the old tables.
164
+ """
165
+ position = await self.db_pool.simple_select_one_onecol(
166
+ TEMP_TABLE + "_position", {}, "position"
167
+ )
168
+ await self.update_user_directory_stream_pos(position)
169
+
170
+ def _delete_staging_area(txn: LoggingTransaction) -> None:
171
+ txn.execute("DROP TABLE IF EXISTS " + TEMP_TABLE + "_rooms")
172
+ txn.execute("DROP TABLE IF EXISTS " + TEMP_TABLE + "_users")
173
+ txn.execute("DROP TABLE IF EXISTS " + TEMP_TABLE + "_position")
174
+
175
+ await self.db_pool.runInteraction(
176
+ "populate_user_directory_cleanup", _delete_staging_area
177
+ )
178
+
179
+ await self.db_pool.updates._end_background_update(
180
+ "populate_user_directory_cleanup"
181
+ )
182
+ return 1
183
+
184
+ async def _populate_user_directory_process_rooms(
185
+ self, progress: JsonDict, batch_size: int
186
+ ) -> int:
187
+ """
188
+ Rescan the state of all rooms so we can track
189
+
190
+ - who's in a public room;
191
+ - which local users share a private room with other users (local
192
+ and remote); and
193
+ - who should be in the user_directory.
194
+
195
+ Args:
196
+ progress
197
+ batch_size: Maximum number of state events to process per cycle.
198
+
199
+ Returns:
200
+ number of events processed.
201
+ """
202
+ # If we don't have progress filed, delete everything.
203
+ if not progress:
204
+ await self.delete_all_from_user_dir()
205
+
206
+ def _get_next_batch(
207
+ txn: LoggingTransaction,
208
+ ) -> Sequence[tuple[str, int]] | None:
209
+ # Only fetch 250 rooms, so we don't fetch too many at once, even
210
+ # if those 250 rooms have less than batch_size state events.
211
+ sql = """
212
+ SELECT room_id, events FROM %s
213
+ ORDER BY events DESC
214
+ LIMIT 250
215
+ """ % (TEMP_TABLE + "_rooms",)
216
+ txn.execute(sql)
217
+ rooms_to_work_on = cast(list[tuple[str, int]], txn.fetchall())
218
+
219
+ if not rooms_to_work_on:
220
+ return None
221
+
222
+ if "remaining" not in progress:
223
+ # Get how many are left to process, so we can give status on how
224
+ # far we are in processing
225
+ txn.execute("SELECT COUNT(*) FROM " + TEMP_TABLE + "_rooms")
226
+ result = txn.fetchone()
227
+ assert result is not None
228
+ progress["remaining"] = result[0]
229
+
230
+ return rooms_to_work_on
231
+
232
+ rooms_to_work_on = await self.db_pool.runInteraction(
233
+ "populate_user_directory_temp_read", _get_next_batch
234
+ )
235
+
236
+ # No more rooms -- complete the transaction.
237
+ if not rooms_to_work_on:
238
+ await self.db_pool.updates._end_background_update(
239
+ "populate_user_directory_process_rooms"
240
+ )
241
+ return 1
242
+
243
+ logger.debug(
244
+ "Processing the next %d rooms of %d remaining",
245
+ len(rooms_to_work_on),
246
+ progress["remaining"],
247
+ )
248
+
249
+ processed_event_count = 0
250
+
251
+ for room_id, event_count in rooms_to_work_on:
252
+ is_in_room = await self.is_host_joined(room_id, self.server_name) # type: ignore[attr-defined]
253
+
254
+ if is_in_room:
255
+ users_with_profile = await self.get_users_in_room_with_profiles(room_id) # type: ignore[attr-defined]
256
+ # Throw away users excluded from the directory.
257
+ users_with_profile = {
258
+ user_id: profile
259
+ for user_id, profile in users_with_profile.items()
260
+ if not self.hs.is_mine_id(user_id)
261
+ or await self.should_include_local_user_in_dir(user_id)
262
+ }
263
+
264
+ # Upsert a user_directory record for each remote user we see.
265
+ for user_id, profile in users_with_profile.items():
266
+ # Local users are processed separately in
267
+ # `_populate_user_directory_users`; there we can read from
268
+ # the `profiles` table to ensure we don't leak their per-room
269
+ # profiles. It also means we write local users to this table
270
+ # exactly once, rather than once for every room they're in.
271
+ if self.hs.is_mine_id(user_id):
272
+ continue
273
+ # TODO `users_with_profile` above reads from the `user_directory`
274
+ # table, meaning that `profile` is bespoke to this room.
275
+ # and this leaks remote users' per-room profiles to the user directory.
276
+ await self.update_profile_in_user_dir(
277
+ user_id, profile.display_name, profile.avatar_url
278
+ )
279
+
280
+ # Now update the room sharing tables to include this room.
281
+ is_public = await self.is_room_world_readable_or_publicly_joinable(
282
+ room_id
283
+ )
284
+ if is_public:
285
+ if users_with_profile:
286
+ await self.add_users_in_public_rooms(
287
+ room_id, users_with_profile.keys()
288
+ )
289
+ else:
290
+ to_insert = set()
291
+ for user_id in users_with_profile:
292
+ # We want the set of pairs (L, M) where L and M are
293
+ # in `users_with_profile` and L is local.
294
+ # Do so by looking for the local user L first.
295
+ if not self.hs.is_mine_id(user_id):
296
+ continue
297
+
298
+ for other_user_id in users_with_profile:
299
+ if user_id == other_user_id:
300
+ continue
301
+
302
+ user_set = (user_id, other_user_id)
303
+ to_insert.add(user_set)
304
+
305
+ # If it gets too big, stop and write to the database
306
+ # to prevent storing too much in RAM.
307
+ if len(to_insert) >= self.SHARE_PRIVATE_WORKING_SET:
308
+ await self.add_users_who_share_private_room(
309
+ room_id, to_insert
310
+ )
311
+ to_insert.clear()
312
+
313
+ if to_insert:
314
+ await self.add_users_who_share_private_room(room_id, to_insert)
315
+ to_insert.clear()
316
+
317
+ # We've finished a room. Delete it from the table.
318
+ await self.db_pool.simple_delete_one(
319
+ TEMP_TABLE + "_rooms", {"room_id": room_id}
320
+ )
321
+ # Update the remaining counter.
322
+ progress["remaining"] -= 1
323
+ await self.db_pool.runInteraction(
324
+ "populate_user_directory",
325
+ self.db_pool.updates._background_update_progress_txn,
326
+ "populate_user_directory_process_rooms",
327
+ progress,
328
+ )
329
+
330
+ processed_event_count += event_count
331
+
332
+ if processed_event_count > batch_size:
333
+ # Don't process any more rooms, we've hit our batch size.
334
+ break
335
+
336
+ await self.db_pool.runInteraction(
337
+ "populate_user_directory",
338
+ self.db_pool.updates._background_update_progress_txn,
339
+ "populate_user_directory_process_rooms",
340
+ progress,
341
+ )
342
+
343
+ return processed_event_count
344
+
345
+ async def _populate_user_directory_process_users(
346
+ self, progress: JsonDict, batch_size: int
347
+ ) -> int:
348
+ """
349
+ Add all local users to the user directory.
350
+ """
351
+
352
+ def _populate_user_directory_process_users_txn(
353
+ txn: LoggingTransaction,
354
+ ) -> int | None:
355
+ # Note: we use an ORDER BY in the SELECT to force usage of an
356
+ # index. Otherwise, postgres does a sequential scan that is
357
+ # surprisingly slow (I think due to the fact it will read/skip
358
+ # over lots of already deleted rows).
359
+ sql = f"""
360
+ DELETE FROM {TEMP_TABLE + "_users"}
361
+ WHERE user_id IN (
362
+ SELECT user_id FROM {TEMP_TABLE + "_users"} ORDER BY user_id LIMIT ?
363
+ )
364
+ RETURNING user_id
365
+ """
366
+ txn.execute(sql, (batch_size,))
367
+ user_result = cast(list[tuple[str]], txn.fetchall())
368
+
369
+ if not user_result:
370
+ return None
371
+
372
+ users_to_work_on = [x[0] for x in user_result]
373
+
374
+ if "remaining" not in progress:
375
+ # Get how many are left to process, so we can give status on how
376
+ # far we are in processing
377
+ sql = "SELECT COUNT(*) FROM " + TEMP_TABLE + "_users"
378
+ txn.execute(sql)
379
+ count_result = txn.fetchone()
380
+ assert count_result is not None
381
+ progress["remaining"] = count_result[0]
382
+
383
+ if not users_to_work_on:
384
+ return None
385
+
386
+ logger.debug(
387
+ "Processing the next %d users of %d remaining",
388
+ len(users_to_work_on),
389
+ progress["remaining"],
390
+ )
391
+
392
+ # First filter down to users we want to insert into the user directory.
393
+ users_to_insert = self._filter_local_users_for_dir_txn(
394
+ txn, users_to_work_on
395
+ )
396
+
397
+ # Next fetch their profiles. Note that not all users have profiles.
398
+ profile_rows = cast(
399
+ list[tuple[str, str | None, str | None]],
400
+ self.db_pool.simple_select_many_txn(
401
+ txn,
402
+ table="profiles",
403
+ column="full_user_id",
404
+ iterable=list(users_to_insert),
405
+ retcols=(
406
+ "full_user_id",
407
+ "displayname",
408
+ "avatar_url",
409
+ ),
410
+ keyvalues={},
411
+ ),
412
+ )
413
+ profiles = {
414
+ full_user_id: _UserDirProfile(full_user_id, displayname, avatar_url)
415
+ for full_user_id, displayname, avatar_url in profile_rows
416
+ }
417
+
418
+ profiles_to_insert = [
419
+ profiles.get(user_id) or _UserDirProfile(user_id)
420
+ for user_id in users_to_insert
421
+ ]
422
+
423
+ # Actually insert the users with their profiles into the directory.
424
+ self._update_profiles_in_user_dir_txn(txn, profiles_to_insert)
425
+
426
+ # Update the remaining counter.
427
+ progress["remaining"] -= len(users_to_work_on)
428
+ self.db_pool.updates._background_update_progress_txn(
429
+ txn, "populate_user_directory_process_users", progress
430
+ )
431
+ return len(users_to_work_on)
432
+
433
+ processed_count = await self.db_pool.runInteraction(
434
+ "populate_user_directory_temp", _populate_user_directory_process_users_txn
435
+ )
436
+
437
+ # No more users -- complete the transaction.
438
+ if not processed_count:
439
+ await self.db_pool.updates._end_background_update(
440
+ "populate_user_directory_process_users"
441
+ )
442
+ return 1
443
+
444
+ return processed_count
445
+
446
+ async def should_include_local_user_in_dir(self, user: str) -> bool:
447
+ """Certain classes of local user are omitted from the user directory.
448
+ Is this user one of them?
449
+ """
450
+ # We're opting to exclude the appservice sender (user defined by the
451
+ # `sender_localpart` in the appservice registration) even though
452
+ # technically it could be DM-able. In the future, this could potentially
453
+ # be configurable per-appservice whether the appservice sender can be
454
+ # contacted.
455
+ if self.get_app_service_by_user_id(user) is not None: # type: ignore[attr-defined]
456
+ return False
457
+
458
+ # We're opting to exclude appservice users (anyone matching the user
459
+ # namespace regex in the appservice registration) even though technically
460
+ # they could be DM-able. In the future, this could potentially
461
+ # be configurable per-appservice whether the appservice users can be
462
+ # contacted.
463
+ if self.get_if_app_services_interested_in_user(user): # type: ignore[attr-defined]
464
+ # TODO we might want to make this configurable for each app service
465
+ return False
466
+
467
+ # Support users are for diagnostics and should not appear in the user directory.
468
+ if await self.is_support_user(user): # type: ignore[attr-defined]
469
+ return False
470
+
471
+ # Deactivated users aren't contactable, so should not appear in the user directory.
472
+ try:
473
+ if await self.get_user_deactivated_status(user): # type: ignore[attr-defined]
474
+ return False
475
+ except StoreError:
476
+ # No such user in the users table. No need to do this when calling
477
+ # is_support_user---that returns False if the user is missing.
478
+ return False
479
+
480
+ return True
481
+
482
+ def _filter_local_users_for_dir_txn(
483
+ self, txn: LoggingTransaction, users: Collection[str]
484
+ ) -> Collection[str]:
485
+ """A batched version of `should_include_local_user_in_dir`"""
486
+ users = [
487
+ user
488
+ for user in users
489
+ if self.get_app_service_by_user_id(user) is None # type: ignore[attr-defined]
490
+ and not self.get_if_app_services_interested_in_user(user) # type: ignore[attr-defined]
491
+ ]
492
+
493
+ rows = cast(
494
+ list[tuple[str, str | None]],
495
+ self.db_pool.simple_select_many_txn(
496
+ txn,
497
+ table="users",
498
+ column="name",
499
+ iterable=users,
500
+ keyvalues={
501
+ "deactivated": 0,
502
+ },
503
+ retcols=("name", "user_type"),
504
+ ),
505
+ )
506
+
507
+ return [name for name, user_type in rows if user_type != UserTypes.SUPPORT]
508
+
509
+ async def is_room_world_readable_or_publicly_joinable(self, room_id: str) -> bool:
510
+ """Check if the room is either world_readable or publically joinable"""
511
+
512
+ # Create a state filter that only queries join and history state event
513
+ types_to_filter = (
514
+ (EventTypes.JoinRules, ""),
515
+ (EventTypes.RoomHistoryVisibility, ""),
516
+ )
517
+
518
+ # Getting the partial state is fine, as we're not looking at membership
519
+ # events.
520
+ current_state_ids = await self.get_partial_filtered_current_state_ids( # type: ignore[attr-defined]
521
+ room_id, StateFilter.from_types(types_to_filter)
522
+ )
523
+
524
+ join_rules_id = current_state_ids.get((EventTypes.JoinRules, ""))
525
+ if join_rules_id:
526
+ join_rule_ev = await self.get_event(join_rules_id, allow_none=True) # type: ignore[attr-defined]
527
+ if join_rule_ev:
528
+ if join_rule_ev.content.get("join_rule") == JoinRules.PUBLIC:
529
+ return True
530
+
531
+ hist_vis_id = current_state_ids.get((EventTypes.RoomHistoryVisibility, ""))
532
+ if hist_vis_id:
533
+ hist_vis_ev = await self.get_event(hist_vis_id, allow_none=True) # type: ignore[attr-defined]
534
+ if hist_vis_ev:
535
+ if (
536
+ hist_vis_ev.content.get("history_visibility")
537
+ == HistoryVisibility.WORLD_READABLE
538
+ ):
539
+ return True
540
+
541
+ return False
542
+
543
+ async def set_remote_user_profile_in_user_dir_stale(
544
+ self, user_id: str, next_try_at_ms: int, retry_counter: int
545
+ ) -> None:
546
+ """
547
+ Marks a remote user as having a possibly-stale user directory profile.
548
+
549
+ Args:
550
+ user_id: the remote user who may have a stale profile on this server.
551
+ next_try_at_ms: timestamp in ms after which the user directory profile can be
552
+ refreshed.
553
+ retry_counter: number of failures in refreshing the profile so far. Used for
554
+ exponential backoff calculations.
555
+ """
556
+ assert not self.hs.is_mine_id(user_id), (
557
+ "Can't mark a local user as a stale remote user."
558
+ )
559
+
560
+ server_name = UserID.from_string(user_id).domain
561
+
562
+ await self.db_pool.simple_upsert(
563
+ table="user_directory_stale_remote_users",
564
+ keyvalues={"user_id": user_id},
565
+ values={
566
+ "next_try_at_ts": next_try_at_ms,
567
+ "retry_counter": retry_counter,
568
+ "user_server_name": server_name,
569
+ },
570
+ desc="set_remote_user_profile_in_user_dir_stale",
571
+ )
572
+
573
+ async def clear_remote_user_profile_in_user_dir_stale(self, user_id: str) -> None:
574
+ """
575
+ Marks a remote user as no longer having a possibly-stale user directory profile.
576
+
577
+ Args:
578
+ user_id: the remote user who no longer has a stale profile on this server.
579
+ """
580
+ await self.db_pool.simple_delete(
581
+ table="user_directory_stale_remote_users",
582
+ keyvalues={"user_id": user_id},
583
+ desc="clear_remote_user_profile_in_user_dir_stale",
584
+ )
585
+
586
+ async def get_remote_servers_with_profiles_to_refresh(
587
+ self, now_ts: int, limit: int
588
+ ) -> list[str]:
589
+ """
590
+ Get a list of up to `limit` server names which have users whose
591
+ locally-cached profiles we believe to be stale
592
+ and are refreshable given the current time `now_ts` in milliseconds.
593
+ """
594
+
595
+ def _get_remote_servers_with_refreshable_profiles_txn(
596
+ txn: LoggingTransaction,
597
+ ) -> list[str]:
598
+ sql = """
599
+ SELECT user_server_name
600
+ FROM user_directory_stale_remote_users
601
+ WHERE next_try_at_ts < ?
602
+ GROUP BY user_server_name
603
+ ORDER BY MIN(next_try_at_ts), user_server_name
604
+ LIMIT ?
605
+ """
606
+ txn.execute(sql, (now_ts, limit))
607
+ return [row[0] for row in txn]
608
+
609
+ return await self.db_pool.runInteraction(
610
+ "get_remote_servers_with_profiles_to_refresh",
611
+ _get_remote_servers_with_refreshable_profiles_txn,
612
+ )
613
+
614
+ async def get_remote_users_to_refresh_on_server(
615
+ self, server_name: str, now_ts: int, limit: int
616
+ ) -> list[tuple[str, int, int]]:
617
+ """
618
+ Get a list of up to `limit` user IDs from the server `server_name`
619
+ whose locally-cached profiles we believe to be stale
620
+ and are refreshable given the current time `now_ts` in milliseconds.
621
+
622
+ Returns:
623
+ tuple of:
624
+ - User ID
625
+ - Retry counter (number of failures so far)
626
+ - Time the retry is scheduled for, in milliseconds
627
+ """
628
+
629
+ def _get_remote_users_to_refresh_on_server_txn(
630
+ txn: LoggingTransaction,
631
+ ) -> list[tuple[str, int, int]]:
632
+ sql = """
633
+ SELECT user_id, retry_counter, next_try_at_ts
634
+ FROM user_directory_stale_remote_users
635
+ WHERE user_server_name = ? AND next_try_at_ts < ?
636
+ ORDER BY next_try_at_ts
637
+ LIMIT ?
638
+ """
639
+ txn.execute(sql, (server_name, now_ts, limit))
640
+ return cast(list[tuple[str, int, int]], txn.fetchall())
641
+
642
+ return await self.db_pool.runInteraction(
643
+ "get_remote_users_to_refresh_on_server",
644
+ _get_remote_users_to_refresh_on_server_txn,
645
+ )
646
+
647
+ async def update_profile_in_user_dir(
648
+ self, user_id: str, display_name: str | None, avatar_url: str | None
649
+ ) -> None:
650
+ """
651
+ Update or add a user's profile in the user directory.
652
+ If the user is remote, the profile will be marked as not stale.
653
+ """
654
+ await self.db_pool.runInteraction(
655
+ "update_profiles_in_user_dir",
656
+ self._update_profiles_in_user_dir_txn,
657
+ [_UserDirProfile(user_id, display_name, avatar_url)],
658
+ )
659
+
660
+ def _update_profiles_in_user_dir_txn(
661
+ self,
662
+ txn: LoggingTransaction,
663
+ profiles: Sequence[_UserDirProfile],
664
+ ) -> None:
665
+ self.db_pool.simple_upsert_many_txn(
666
+ txn,
667
+ table="user_directory",
668
+ key_names=("user_id",),
669
+ key_values=[(p.user_id,) for p in profiles],
670
+ value_names=("display_name", "avatar_url"),
671
+ value_values=[
672
+ (
673
+ p.display_name,
674
+ p.avatar_url,
675
+ )
676
+ for p in profiles
677
+ ],
678
+ )
679
+
680
+ # Remote users: Make sure the profile is not marked as stale anymore.
681
+ remote_users = [
682
+ p.user_id for p in profiles if not self.hs.is_mine_id(p.user_id)
683
+ ]
684
+ if remote_users:
685
+ self.db_pool.simple_delete_many_txn(
686
+ txn,
687
+ table="user_directory_stale_remote_users",
688
+ column="user_id",
689
+ values=remote_users,
690
+ keyvalues={},
691
+ )
692
+
693
+ if isinstance(self.database_engine, PostgresEngine):
694
+ # We weight the localpart most highly, then display name and finally
695
+ # server name
696
+ template = """
697
+ (
698
+ %s,
699
+ setweight(to_tsvector('simple', %s), 'A')
700
+ || setweight(to_tsvector('simple', %s), 'D')
701
+ || setweight(to_tsvector('simple', COALESCE(%s, '')), 'B')
702
+ )
703
+ """
704
+
705
+ sql = """
706
+ INSERT INTO user_directory_search(user_id, vector)
707
+ VALUES ? ON CONFLICT (user_id) DO UPDATE SET vector=EXCLUDED.vector
708
+ """
709
+ txn.execute_values(
710
+ sql,
711
+ [
712
+ (
713
+ p.user_id,
714
+ get_localpart_from_id(p.user_id),
715
+ get_domain_from_id(p.user_id),
716
+ (
717
+ _filter_text_for_index(p.display_name)
718
+ if p.display_name
719
+ else None
720
+ ),
721
+ )
722
+ for p in profiles
723
+ ],
724
+ template=template,
725
+ fetch=False,
726
+ )
727
+ elif isinstance(self.database_engine, Sqlite3Engine):
728
+ values = []
729
+ for p in profiles:
730
+ if p.display_name is not None:
731
+ index_display_name = _filter_text_for_index(p.display_name)
732
+ value = f"{p.user_id} {index_display_name}"
733
+ else:
734
+ value = p.user_id
735
+
736
+ values.append((value,))
737
+
738
+ self.db_pool.simple_upsert_many_txn(
739
+ txn,
740
+ table="user_directory_search",
741
+ key_names=("user_id",),
742
+ key_values=[(p.user_id,) for p in profiles],
743
+ value_names=("value",),
744
+ value_values=values,
745
+ )
746
+ else:
747
+ # This should be unreachable.
748
+ raise Exception("Unrecognized database engine")
749
+
750
+ async def add_users_who_share_private_room(
751
+ self, room_id: str, user_id_tuples: Iterable[tuple[str, str]]
752
+ ) -> None:
753
+ """Insert entries into the users_who_share_private_rooms table. The first
754
+ user should be a local user.
755
+
756
+ Args:
757
+ room_id
758
+ user_id_tuples: iterable of 2-tuple of user IDs.
759
+ """
760
+
761
+ await self.db_pool.simple_upsert_many(
762
+ table="users_who_share_private_rooms",
763
+ key_names=["user_id", "other_user_id", "room_id"],
764
+ key_values=[
765
+ (user_id, other_user_id, room_id)
766
+ for user_id, other_user_id in user_id_tuples
767
+ ],
768
+ value_names=(),
769
+ value_values=(),
770
+ desc="add_users_who_share_room",
771
+ )
772
+
773
+ async def add_users_in_public_rooms(
774
+ self, room_id: str, user_ids: Iterable[str]
775
+ ) -> None:
776
+ """Insert entries into the users_in_public_rooms table.
777
+
778
+ Args:
779
+ room_id
780
+ user_ids
781
+ """
782
+
783
+ await self.db_pool.simple_upsert_many(
784
+ table="users_in_public_rooms",
785
+ key_names=["user_id", "room_id"],
786
+ key_values=[(user_id, room_id) for user_id in user_ids],
787
+ value_names=(),
788
+ value_values=(),
789
+ desc="add_users_in_public_rooms",
790
+ )
791
+
792
+ async def delete_all_from_user_dir(self) -> None:
793
+ """Delete the entire user directory"""
794
+
795
+ def _delete_all_from_user_dir_txn(txn: LoggingTransaction) -> None:
796
+ # SQLite doesn't support TRUNCATE.
797
+ # On Postgres, DELETE FROM does a table scan but TRUNCATE is more efficient.
798
+ truncate = (
799
+ "DELETE FROM"
800
+ if isinstance(self.database_engine, Sqlite3Engine)
801
+ else "TRUNCATE"
802
+ )
803
+ txn.execute(f"{truncate} user_directory")
804
+ txn.execute(f"{truncate} user_directory_search")
805
+ txn.execute(f"{truncate} users_in_public_rooms")
806
+ txn.execute(f"{truncate} users_who_share_private_rooms")
807
+
808
+ await self.db_pool.runInteraction(
809
+ "delete_all_from_user_dir", _delete_all_from_user_dir_txn
810
+ )
811
+
812
+ async def _get_user_in_directory(
813
+ self, user_id: str
814
+ ) -> tuple[str | None, str | None] | None:
815
+ """
816
+ Fetch the user information in the user directory.
817
+
818
+ Returns:
819
+ None if the user is unknown, otherwise a tuple of display name and
820
+ avatar URL (both of which may be None).
821
+ """
822
+ return cast(
823
+ tuple[str | None, str | None] | None,
824
+ await self.db_pool.simple_select_one(
825
+ table="user_directory",
826
+ keyvalues={"user_id": user_id},
827
+ retcols=("display_name", "avatar_url"),
828
+ allow_none=True,
829
+ desc="get_user_in_directory",
830
+ ),
831
+ )
832
+
833
+ async def update_user_directory_stream_pos(self, stream_id: int | None) -> None:
834
+ await self.db_pool.simple_update_one(
835
+ table="user_directory_stream_pos",
836
+ keyvalues={},
837
+ updatevalues={"stream_id": stream_id},
838
+ desc="update_user_directory_stream_pos",
839
+ )
840
+
841
+
842
+ class SearchResult(TypedDict):
843
+ limited: bool
844
+ results: list[UserProfile]
845
+
846
+
847
+ class UserDirectoryStore(UserDirectoryBackgroundUpdateStore):
848
+ # How many records do we calculate before sending it to
849
+ # add_users_who_share_private_rooms?
850
+ SHARE_PRIVATE_WORKING_SET = 500
851
+
852
+ def __init__(
853
+ self,
854
+ database: DatabasePool,
855
+ db_conn: LoggingDatabaseConnection,
856
+ hs: "HomeServer",
857
+ ) -> None:
858
+ super().__init__(database, db_conn, hs)
859
+
860
+ self._prefer_local_users_in_search = (
861
+ hs.config.userdirectory.user_directory_search_prefer_local_users
862
+ )
863
+ self._server_name = hs.config.server.server_name
864
+
865
+ async def remove_from_user_dir(self, user_id: str) -> None:
866
+ def _remove_from_user_dir_txn(txn: LoggingTransaction) -> None:
867
+ self.db_pool.simple_delete_txn(
868
+ txn, table="user_directory", keyvalues={"user_id": user_id}
869
+ )
870
+ self.db_pool.simple_delete_txn(
871
+ txn, table="user_directory_search", keyvalues={"user_id": user_id}
872
+ )
873
+ self.db_pool.simple_delete_txn(
874
+ txn, table="users_in_public_rooms", keyvalues={"user_id": user_id}
875
+ )
876
+ self.db_pool.simple_delete_txn(
877
+ txn,
878
+ table="users_who_share_private_rooms",
879
+ keyvalues={"user_id": user_id},
880
+ )
881
+ self.db_pool.simple_delete_txn(
882
+ txn,
883
+ table="users_who_share_private_rooms",
884
+ keyvalues={"other_user_id": user_id},
885
+ )
886
+
887
+ await self.db_pool.runInteraction(
888
+ "remove_from_user_dir", _remove_from_user_dir_txn
889
+ )
890
+
891
+ async def get_users_in_dir_due_to_room(self, room_id: str) -> set[str]:
892
+ """Get all user_ids that are in the room directory because they're
893
+ in the given room_id
894
+ """
895
+ user_ids_share_pub = await self.db_pool.simple_select_onecol(
896
+ table="users_in_public_rooms",
897
+ keyvalues={"room_id": room_id},
898
+ retcol="user_id",
899
+ desc="get_users_in_dir_due_to_room",
900
+ )
901
+
902
+ user_ids_share_priv = await self.db_pool.simple_select_onecol(
903
+ table="users_who_share_private_rooms",
904
+ keyvalues={"room_id": room_id},
905
+ retcol="other_user_id",
906
+ desc="get_users_in_dir_due_to_room",
907
+ )
908
+
909
+ user_ids = set(user_ids_share_pub)
910
+ user_ids.update(user_ids_share_priv)
911
+
912
+ return user_ids
913
+
914
+ async def remove_user_who_share_room(self, user_id: str, room_id: str) -> None:
915
+ """
916
+ Deletes entries in the users_who_share_*_rooms table. The first
917
+ user should be a local user.
918
+
919
+ Args:
920
+ user_id
921
+ room_id
922
+ """
923
+
924
+ def _remove_user_who_share_room_txn(txn: LoggingTransaction) -> None:
925
+ self.db_pool.simple_delete_txn(
926
+ txn,
927
+ table="users_who_share_private_rooms",
928
+ keyvalues={"user_id": user_id, "room_id": room_id},
929
+ )
930
+ self.db_pool.simple_delete_txn(
931
+ txn,
932
+ table="users_who_share_private_rooms",
933
+ keyvalues={"other_user_id": user_id, "room_id": room_id},
934
+ )
935
+ self.db_pool.simple_delete_txn(
936
+ txn,
937
+ table="users_in_public_rooms",
938
+ keyvalues={"user_id": user_id, "room_id": room_id},
939
+ )
940
+
941
+ await self.db_pool.runInteraction(
942
+ "remove_user_who_share_room", _remove_user_who_share_room_txn
943
+ )
944
+
945
+ async def get_user_dir_rooms_user_is_in(self, user_id: str) -> list[str]:
946
+ """
947
+ Returns the rooms that a user is in.
948
+
949
+ Args:
950
+ user_id: Must be a local user
951
+
952
+ Returns:
953
+ List of room IDs
954
+ """
955
+ rows = await self.db_pool.simple_select_onecol(
956
+ table="users_who_share_private_rooms",
957
+ keyvalues={"user_id": user_id},
958
+ retcol="room_id",
959
+ desc="get_rooms_user_is_in",
960
+ )
961
+
962
+ pub_rows = await self.db_pool.simple_select_onecol(
963
+ table="users_in_public_rooms",
964
+ keyvalues={"user_id": user_id},
965
+ retcol="room_id",
966
+ desc="get_rooms_user_is_in",
967
+ )
968
+
969
+ users = set(pub_rows)
970
+ users.update(rows)
971
+ return list(users)
972
+
973
+ async def get_user_directory_stream_pos(self) -> int | None:
974
+ """
975
+ Get the stream ID of the user directory stream.
976
+
977
+ Returns:
978
+ The stream token or None if the initial background update hasn't happened yet.
979
+ """
980
+ return await self.db_pool.simple_select_one_onecol(
981
+ table="user_directory_stream_pos",
982
+ keyvalues={},
983
+ retcol="stream_id",
984
+ desc="get_user_directory_stream_pos",
985
+ )
986
+
987
+ async def search_user_dir(
988
+ self,
989
+ user_id: str,
990
+ search_term: str,
991
+ limit: int,
992
+ show_locked_users: bool = False,
993
+ ) -> SearchResult:
994
+ """Searches for users in directory
995
+
996
+ Returns:
997
+ dict of the form::
998
+
999
+ {
1000
+ "limited": <bool>, # whether there were more results or not
1001
+ "results": [ # Ordered by best match first
1002
+ {
1003
+ "user_id": <user_id>,
1004
+ "display_name": <display_name>,
1005
+ "avatar_url": <avatar_url>
1006
+ }
1007
+ ]
1008
+ }
1009
+ """
1010
+
1011
+ join_args: tuple[str, ...] = (user_id,)
1012
+
1013
+ if self.hs.config.userdirectory.user_directory_search_all_users:
1014
+ where_clause = "user_id != ?"
1015
+ else:
1016
+ where_clause = """
1017
+ (
1018
+ EXISTS (select 1 from users_in_public_rooms WHERE user_id = t.user_id)
1019
+ OR EXISTS (
1020
+ SELECT 1 FROM users_who_share_private_rooms
1021
+ WHERE user_id = ? AND other_user_id = t.user_id
1022
+ )
1023
+ )
1024
+ """
1025
+
1026
+ if not show_locked_users:
1027
+ where_clause += " AND (u.locked IS NULL OR u.locked = FALSE)"
1028
+
1029
+ # Adjust the JOIN type based on the exclude_remote_users flag (the users
1030
+ # table only contains local users so an inner join is a good way to
1031
+ # to exclude remote users)
1032
+ if self.hs.config.userdirectory.user_directory_exclude_remote_users:
1033
+ join_type = "JOIN"
1034
+ else:
1035
+ join_type = "LEFT JOIN"
1036
+
1037
+ # We allow manipulating the ranking algorithm by injecting statements
1038
+ # based on config options.
1039
+ additional_ordering_statements = []
1040
+ ordering_arguments: tuple[str, ...] = ()
1041
+
1042
+ if isinstance(self.database_engine, PostgresEngine):
1043
+ full_query, exact_query, prefix_query = _parse_query_postgres(search_term)
1044
+
1045
+ # If enabled, this config option will rank local users higher than those on
1046
+ # remote instances.
1047
+ if self._prefer_local_users_in_search:
1048
+ # This statement checks whether a given user's user ID contains a server name
1049
+ # that matches the local server
1050
+ statement = "* (CASE WHEN user_id LIKE ? THEN 2.0 ELSE 1.0 END)"
1051
+ additional_ordering_statements.append(statement)
1052
+
1053
+ ordering_arguments += ("%:" + self._server_name,)
1054
+
1055
+ # We order by rank and then if they have profile info
1056
+ # The ranking algorithm is hand tweaked for "best" results. Broadly
1057
+ # the idea is we give a higher weight to exact matches.
1058
+ # The array of numbers are the weights for the various part of the
1059
+ # search: (domain, _, display name, localpart)
1060
+ sql = """
1061
+ WITH matching_users AS (
1062
+ SELECT user_id, vector FROM user_directory_search WHERE vector @@ to_tsquery('simple', ?)
1063
+ LIMIT 10000
1064
+ )
1065
+ SELECT d.user_id AS user_id, display_name, avatar_url
1066
+ FROM matching_users as t
1067
+ INNER JOIN user_directory AS d USING (user_id)
1068
+ %(join_type)s users AS u ON t.user_id = u.name
1069
+ WHERE
1070
+ %(where_clause)s
1071
+ ORDER BY
1072
+ (CASE WHEN d.user_id IS NOT NULL THEN 4.0 ELSE 1.0 END)
1073
+ * (CASE WHEN display_name IS NOT NULL THEN 1.2 ELSE 1.0 END)
1074
+ * (CASE WHEN avatar_url IS NOT NULL THEN 1.2 ELSE 1.0 END)
1075
+ * (
1076
+ 3 * ts_rank_cd(
1077
+ '{0.1, 0.1, 0.9, 1.0}',
1078
+ vector,
1079
+ to_tsquery('simple', ?),
1080
+ 8
1081
+ )
1082
+ + ts_rank_cd(
1083
+ '{0.1, 0.1, 0.9, 1.0}',
1084
+ vector,
1085
+ to_tsquery('simple', ?),
1086
+ 8
1087
+ )
1088
+ )
1089
+ %(order_case_statements)s
1090
+ DESC,
1091
+ display_name IS NULL,
1092
+ avatar_url IS NULL
1093
+ LIMIT ?
1094
+ """ % {
1095
+ "where_clause": where_clause,
1096
+ "order_case_statements": " ".join(additional_ordering_statements),
1097
+ "join_type": join_type,
1098
+ }
1099
+ args = (
1100
+ (full_query,)
1101
+ + join_args
1102
+ + (exact_query, prefix_query)
1103
+ + ordering_arguments
1104
+ + (limit + 1,)
1105
+ )
1106
+ elif isinstance(self.database_engine, Sqlite3Engine):
1107
+ search_query = _parse_query_sqlite(search_term)
1108
+
1109
+ # If enabled, this config option will rank local users higher than those on
1110
+ # remote instances.
1111
+ if self._prefer_local_users_in_search:
1112
+ # This statement checks whether a given user's user ID contains a server name
1113
+ # that matches the local server
1114
+ #
1115
+ # Note that we need to include a comma at the end for valid SQL
1116
+ statement = "user_id LIKE ? DESC,"
1117
+ additional_ordering_statements.append(statement)
1118
+
1119
+ ordering_arguments += ("%:" + self._server_name,)
1120
+
1121
+ sql = """
1122
+ SELECT d.user_id AS user_id, display_name, avatar_url
1123
+ FROM user_directory_search as t
1124
+ INNER JOIN user_directory AS d USING (user_id)
1125
+ %(join_type)s users AS u ON t.user_id = u.name
1126
+ WHERE
1127
+ %(where_clause)s
1128
+ AND value MATCH ?
1129
+ ORDER BY
1130
+ rank(matchinfo(user_directory_search)) DESC,
1131
+ %(order_statements)s
1132
+ display_name IS NULL,
1133
+ avatar_url IS NULL
1134
+ LIMIT ?
1135
+ """ % {
1136
+ "where_clause": where_clause,
1137
+ "order_statements": " ".join(additional_ordering_statements),
1138
+ "join_type": join_type,
1139
+ }
1140
+ args = join_args + (search_query,) + ordering_arguments + (limit + 1,)
1141
+ else:
1142
+ # This should be unreachable.
1143
+ raise Exception("Unrecognized database engine")
1144
+
1145
+ results = cast(
1146
+ list[tuple[str, str | None, str | None]],
1147
+ await self.db_pool.execute("search_user_dir", sql, *args),
1148
+ )
1149
+
1150
+ limited = len(results) > limit
1151
+
1152
+ return {
1153
+ "limited": limited,
1154
+ "results": [
1155
+ {"user_id": r[0], "display_name": r[1], "avatar_url": r[2]}
1156
+ for r in results[0:limit]
1157
+ ],
1158
+ }
1159
+
1160
+
1161
+ def _filter_text_for_index(text: str) -> str:
1162
+ """Transforms text before it is inserted into the user directory index, or searched
1163
+ for in the user directory index.
1164
+
1165
+ Note that the user directory search table needs to be rebuilt whenever this function
1166
+ changes.
1167
+ """
1168
+ # Lowercase the text, to make searches case-insensitive.
1169
+ # This is necessary for both PostgreSQL and SQLite. PostgreSQL's
1170
+ # `to_tsquery/to_tsvector` functions don't lowercase non-ASCII characters when using
1171
+ # the "C" collation, while SQLite just doesn't lowercase non-ASCII characters at
1172
+ # all.
1173
+ text = text.lower()
1174
+
1175
+ # Normalize the text. NFKC normalization has two effects:
1176
+ # 1. It canonicalizes the text, ie. maps all visually identical strings to the same
1177
+ # string. For example, ["e", "◌́"] is mapped to ["é"].
1178
+ # 2. It maps strings that are roughly equivalent to the same string.
1179
+ # For example, ["dž"] is mapped to ["d", "ž"], ["①"] to ["1"] and ["i⁹"] to
1180
+ # ["i", "9"].
1181
+ text = unicodedata.normalize("NFKC", text)
1182
+
1183
+ # Note that nothing is done to make searches accent-insensitive.
1184
+ # That could be achieved by converting to NFKD form instead (with combining accents
1185
+ # split out) and filtering out combining accents using `unicodedata.combining(c)`.
1186
+ # The downside of this may be noisier search results, since search terms with
1187
+ # explicit accents will match characters with no accents, or completely different
1188
+ # accents.
1189
+ #
1190
+ # text = unicodedata.normalize("NFKD", text)
1191
+ # text = "".join([c for c in text if not unicodedata.combining(c)])
1192
+
1193
+ return text
1194
+
1195
+
1196
+ def _parse_query_sqlite(search_term: str) -> str:
1197
+ """Takes a plain unicode string from the user and converts it into a form
1198
+ that can be passed to the database.
1199
+ We use this so that we can add prefix matching, which isn't something
1200
+ that is supported by default.
1201
+
1202
+ We specifically add both a prefix and non prefix matching term so that
1203
+ exact matches get ranked higher.
1204
+ """
1205
+ search_term = _filter_text_for_index(search_term)
1206
+
1207
+ # Pull out the individual words, discarding any non-word characters.
1208
+ results = _parse_words(search_term)
1209
+ return " & ".join("(%s* OR %s)" % (result, result) for result in results)
1210
+
1211
+
1212
+ def _parse_query_postgres(search_term: str) -> tuple[str, str, str]:
1213
+ """Takes a plain unicode string from the user and converts it into a form
1214
+ that can be passed to the database.
1215
+ We use this so that we can add prefix matching, which isn't something
1216
+ that is supported by default.
1217
+ """
1218
+ search_term = _filter_text_for_index(search_term)
1219
+
1220
+ escaped_words = []
1221
+ for index, word in enumerate(_parse_words(search_term)):
1222
+ if index >= 10:
1223
+ # We limit how many terms we include, as otherwise it can use
1224
+ # excessive database time if people accidentally search for large
1225
+ # strings.
1226
+ break
1227
+
1228
+ # Postgres tsvector and tsquery quoting rules:
1229
+ # words potentially containing punctuation should be quoted
1230
+ # and then existing quotes and backslashes should be doubled
1231
+ # See: https://www.postgresql.org/docs/current/datatype-textsearch.html#DATATYPE-TSQUERY
1232
+
1233
+ quoted_word = word.replace("'", "''").replace("\\", "\\\\")
1234
+ escaped_words.append(f"'{quoted_word}'")
1235
+
1236
+ both = " & ".join("(%s:* | %s)" % (word, word) for word in escaped_words)
1237
+ exact = " & ".join("%s" % (word,) for word in escaped_words)
1238
+ prefix = " & ".join("%s:*" % (word,) for word in escaped_words)
1239
+
1240
+ return both, exact, prefix
1241
+
1242
+
1243
+ def _parse_words(search_term: str) -> list[str]:
1244
+ """Split the provided search string into a list of its words using ICU.
1245
+
1246
+ Args:
1247
+ search_term: The search string.
1248
+
1249
+ Returns:
1250
+ A list of the words in the search string.
1251
+ """
1252
+ return _parse_words_with_icu(search_term)
1253
+
1254
+
1255
+ def _parse_words_with_icu(search_term: str) -> list[str]:
1256
+ """Break down the provided search string into its individual words using ICU
1257
+ (International Components for Unicode).
1258
+
1259
+ Args:
1260
+ search_term: The search string.
1261
+
1262
+ Returns:
1263
+ A list of the words in the search string.
1264
+ """
1265
+ results = []
1266
+ for part in icu.parse_words(search_term):
1267
+ # We want to make sure that we split on `@` and `:` specifically, as
1268
+ # they occur in user IDs.
1269
+ for result in re.split(r"[@:]+", part):
1270
+ results.append(result.strip())
1271
+
1272
+ # icu will break up words that have punctuation in them, but to handle
1273
+ # cases where user IDs have '-', '.' and '_' in them we want to *not* break
1274
+ # those into words and instead allow the DB to tokenise them how it wants.
1275
+ #
1276
+ # In particular, user-71 in postgres gets tokenised to "user, -71", and this
1277
+ # will not match a query for "user, 71".
1278
+ new_results: list[str] = []
1279
+ i = 0
1280
+ while i < len(results):
1281
+ curr = results[i]
1282
+
1283
+ prev = None
1284
+ next = None
1285
+ if i > 0:
1286
+ prev = results[i - 1]
1287
+ if i + 1 < len(results):
1288
+ next = results[i + 1]
1289
+
1290
+ i += 1
1291
+
1292
+ # libicu considers spaces and punctuation between words as words, but we don't
1293
+ # want to include those in results as they would result in syntax errors in SQL
1294
+ # queries (e.g. "foo bar" would result in the search query including "foo & &
1295
+ # bar").
1296
+ if not curr:
1297
+ continue
1298
+
1299
+ if curr in ["-", ".", "_"]:
1300
+ prefix = ""
1301
+ suffix = ""
1302
+
1303
+ # Check if the next item is a word, and if so use it as the suffix.
1304
+ # We check for if its a word as we don't want to concatenate
1305
+ # multiple punctuation marks.
1306
+ if next is not None and re.match(r"\w", next):
1307
+ suffix = next
1308
+ i += 1 # We're using next, so we skip it in the outer loop.
1309
+ else:
1310
+ # We want to avoid creating terms like "user-", as we should
1311
+ # strip trailing punctuation.
1312
+ continue
1313
+
1314
+ if prev and re.match(r"\w", prev) and new_results:
1315
+ prefix = new_results[-1]
1316
+ new_results.pop()
1317
+
1318
+ # We might not have a prefix here, but that's fine as we want to
1319
+ # ensure that we don't strip preceding punctuation e.g. '-71'
1320
+ # shouldn't be converted to '71'.
1321
+
1322
+ new_results.append(f"{prefix}{curr}{suffix}")
1323
+ continue
1324
+ elif not re.match(r"\w", curr):
1325
+ # Ignore other punctuation
1326
+ continue
1327
+
1328
+ new_results.append(curr)
1329
+
1330
+ return new_results