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,2132 @@
1
+ #
2
+ # This file is licensed under the Affero General Public License (AGPL) version 3.
3
+ #
4
+ # Copyright 2020 Sorunome
5
+ # Copyright 2015-2022 The Matrix.org Foundation C.I.C.
6
+ # Copyright (C) 2023 New Vector, Ltd
7
+ #
8
+ # This program is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU Affero General Public License as
10
+ # published by the Free Software Foundation, either version 3 of the
11
+ # License, or (at your option) any later version.
12
+ #
13
+ # See the GNU Affero General Public License for more details:
14
+ # <https://www.gnu.org/licenses/agpl-3.0.html>.
15
+ #
16
+ # Originally licensed under the Apache License, Version 2.0:
17
+ # <http://www.apache.org/licenses/LICENSE-2.0>.
18
+ #
19
+ # [This file includes modifications made by New Vector Limited]
20
+ #
21
+ #
22
+
23
+
24
+ import copy
25
+ import itertools
26
+ import logging
27
+ from typing import (
28
+ TYPE_CHECKING,
29
+ AbstractSet,
30
+ Awaitable,
31
+ BinaryIO,
32
+ Callable,
33
+ Collection,
34
+ Container,
35
+ Iterable,
36
+ Mapping,
37
+ Optional,
38
+ Sequence,
39
+ TypeVar,
40
+ )
41
+
42
+ import attr
43
+ from prometheus_client import Counter
44
+
45
+ from synapse.api.constants import Direction, EventContentFields, EventTypes, Membership
46
+ from synapse.api.errors import (
47
+ CodeMessageException,
48
+ Codes,
49
+ FederationDeniedError,
50
+ HttpResponseException,
51
+ RequestSendFailed,
52
+ SynapseError,
53
+ UnsupportedRoomVersionError,
54
+ )
55
+ from synapse.api.ratelimiting import Ratelimiter
56
+ from synapse.api.room_versions import (
57
+ KNOWN_ROOM_VERSIONS,
58
+ EventFormatVersions,
59
+ RoomVersion,
60
+ RoomVersions,
61
+ )
62
+ from synapse.events import EventBase, builder, make_event_from_dict
63
+ from synapse.federation.federation_base import (
64
+ FederationBase,
65
+ InvalidEventSignatureError,
66
+ event_from_pdu_json,
67
+ parse_events_from_pdu_json,
68
+ )
69
+ from synapse.federation.transport.client import SendJoinResponse
70
+ from synapse.http.client import is_unknown_endpoint
71
+ from synapse.http.types import QueryParams
72
+ from synapse.logging.opentracing import SynapseTags, log_kv, set_tag, tag_args, trace
73
+ from synapse.metrics import SERVER_NAME_LABEL
74
+ from synapse.types import JsonDict, StrCollection, UserID, get_domain_from_id
75
+ from synapse.types.handlers.policy_server import RECOMMENDATION_OK, RECOMMENDATION_SPAM
76
+ from synapse.util.async_helpers import concurrently_execute
77
+ from synapse.util.caches.expiringcache import ExpiringCache
78
+ from synapse.util.retryutils import NotRetryingDestination
79
+
80
+ if TYPE_CHECKING:
81
+ from synapse.server import HomeServer
82
+
83
+ logger = logging.getLogger(__name__)
84
+
85
+ sent_queries_counter = Counter(
86
+ "synapse_federation_client_sent_queries", "", labelnames=["type", SERVER_NAME_LABEL]
87
+ )
88
+
89
+
90
+ PDU_RETRY_TIME_MS = 1 * 60 * 1000
91
+
92
+ T = TypeVar("T")
93
+
94
+
95
+ @attr.s(frozen=True, slots=True, auto_attribs=True)
96
+ class PulledPduInfo:
97
+ """
98
+ A result object that stores the PDU and info about it like which homeserver we
99
+ pulled it from (`pull_origin`)
100
+ """
101
+
102
+ pdu: EventBase
103
+ # Which homeserver we pulled the PDU from
104
+ pull_origin: str
105
+
106
+
107
+ class InvalidResponseError(RuntimeError):
108
+ """Helper for _try_destination_list: indicates that the server returned a response
109
+ we couldn't parse
110
+ """
111
+
112
+
113
+ @attr.s(slots=True, frozen=True, auto_attribs=True)
114
+ class SendJoinResult:
115
+ # The event to persist.
116
+ event: EventBase
117
+ # A string giving the server the event was sent to.
118
+ origin: str
119
+ state: list[EventBase]
120
+ auth_chain: list[EventBase]
121
+
122
+ # True if 'state' elides non-critical membership events
123
+ partial_state: bool
124
+
125
+ # If 'partial_state' is set, a set of the servers in the room (otherwise empty).
126
+ # Always contains the server we joined off.
127
+ servers_in_room: AbstractSet[str]
128
+
129
+
130
+ class FederationClient(FederationBase):
131
+ def __init__(self, hs: "HomeServer"):
132
+ super().__init__(hs)
133
+
134
+ self.pdu_destination_tried: dict[str, dict[str, int]] = {}
135
+ self._clock.looping_call(self._clear_tried_cache, 60 * 1000)
136
+ self.state = hs.get_state_handler()
137
+ self.transport_layer = hs.get_federation_transport_client()
138
+
139
+ self.server_name = hs.hostname
140
+ self.signing_key = hs.signing_key
141
+
142
+ # Cache mapping `event_id` to a tuple of the event itself and the `pull_origin`
143
+ # (which server we pulled the event from)
144
+ self._get_pdu_cache: ExpiringCache[str, tuple[EventBase, str]] = ExpiringCache(
145
+ cache_name="get_pdu_cache",
146
+ server_name=self.server_name,
147
+ hs=self.hs,
148
+ clock=self._clock,
149
+ max_len=1000,
150
+ expiry_ms=120 * 1000,
151
+ reset_expiry_on_get=False,
152
+ )
153
+
154
+ # A cache for fetching the room hierarchy over federation.
155
+ #
156
+ # Some stale data over federation is OK, but must be refreshed
157
+ # periodically since the local server is in the room.
158
+ #
159
+ # It is a map of (room ID, suggested-only) -> the response of
160
+ # get_room_hierarchy.
161
+ self._get_room_hierarchy_cache: ExpiringCache[
162
+ tuple[str, bool],
163
+ tuple[JsonDict, Sequence[JsonDict], Sequence[JsonDict], Sequence[str]],
164
+ ] = ExpiringCache(
165
+ cache_name="get_room_hierarchy_cache",
166
+ server_name=self.server_name,
167
+ hs=self.hs,
168
+ clock=self._clock,
169
+ max_len=1000,
170
+ expiry_ms=5 * 60 * 1000,
171
+ reset_expiry_on_get=False,
172
+ )
173
+
174
+ def _clear_tried_cache(self) -> None:
175
+ """Clear pdu_destination_tried cache"""
176
+ now = self._clock.time_msec()
177
+
178
+ old_dict = self.pdu_destination_tried
179
+ self.pdu_destination_tried = {}
180
+
181
+ for event_id, destination_dict in old_dict.items():
182
+ destination_dict = {
183
+ dest: time
184
+ for dest, time in destination_dict.items()
185
+ if time + PDU_RETRY_TIME_MS > now
186
+ }
187
+ if destination_dict:
188
+ self.pdu_destination_tried[event_id] = destination_dict
189
+
190
+ async def make_query(
191
+ self,
192
+ destination: str,
193
+ query_type: str,
194
+ args: QueryParams,
195
+ retry_on_dns_fail: bool = False,
196
+ ignore_backoff: bool = False,
197
+ ) -> JsonDict:
198
+ """Sends a federation Query to a remote homeserver of the given type
199
+ and arguments.
200
+
201
+ Args:
202
+ destination: Domain name of the remote homeserver
203
+ query_type: Category of the query type; should match the
204
+ handler name used in register_query_handler().
205
+ args: Mapping of strings to strings containing the details
206
+ of the query request.
207
+ ignore_backoff: true to ignore the historical backoff data
208
+ and try the request anyway.
209
+
210
+ Returns:
211
+ The JSON object from the response
212
+ """
213
+ sent_queries_counter.labels(
214
+ type=query_type,
215
+ **{SERVER_NAME_LABEL: self.server_name},
216
+ ).inc()
217
+
218
+ return await self.transport_layer.make_query(
219
+ destination,
220
+ query_type,
221
+ args,
222
+ retry_on_dns_fail=retry_on_dns_fail,
223
+ ignore_backoff=ignore_backoff,
224
+ )
225
+
226
+ async def query_client_keys(
227
+ self, destination: str, content: JsonDict, timeout: int
228
+ ) -> JsonDict:
229
+ """Query device keys for a device hosted on a remote server.
230
+
231
+ Args:
232
+ destination: Domain name of the remote homeserver
233
+ content: The query content.
234
+
235
+ Returns:
236
+ The JSON object from the response
237
+ """
238
+ sent_queries_counter.labels(
239
+ type="client_device_keys",
240
+ **{SERVER_NAME_LABEL: self.server_name},
241
+ ).inc()
242
+ return await self.transport_layer.query_client_keys(
243
+ destination, content, timeout
244
+ )
245
+
246
+ async def query_user_devices(
247
+ self, destination: str, user_id: str, timeout: int = 30000
248
+ ) -> JsonDict:
249
+ """Query the device keys for a list of user ids hosted on a remote
250
+ server.
251
+ """
252
+ sent_queries_counter.labels(
253
+ type="user_devices",
254
+ **{SERVER_NAME_LABEL: self.server_name},
255
+ ).inc()
256
+ return await self.transport_layer.query_user_devices(
257
+ destination, user_id, timeout
258
+ )
259
+
260
+ async def claim_client_keys(
261
+ self,
262
+ user: UserID,
263
+ destination: str,
264
+ query: dict[str, dict[str, dict[str, int]]],
265
+ timeout: int | None,
266
+ ) -> JsonDict:
267
+ """Claims one-time keys for a device hosted on a remote server.
268
+
269
+ Args:
270
+ user: The user id of the requesting user
271
+ destination: Domain name of the remote homeserver
272
+ content: The query content.
273
+
274
+ Returns:
275
+ The JSON object from the response
276
+ """
277
+ sent_queries_counter.labels(
278
+ type="client_one_time_keys",
279
+ **{SERVER_NAME_LABEL: self.server_name},
280
+ ).inc()
281
+
282
+ # Convert the query with counts into a stable and unstable query and check
283
+ # if attempting to claim more than 1 OTK.
284
+ content: dict[str, dict[str, str]] = {}
285
+ unstable_content: dict[str, dict[str, list[str]]] = {}
286
+ use_unstable = False
287
+ for user_id, one_time_keys in query.items():
288
+ for device_id, algorithms in one_time_keys.items():
289
+ # If more than one algorithm is requested, attempt to use the unstable
290
+ # endpoint.
291
+ if sum(algorithms.values()) > 1:
292
+ use_unstable = True
293
+ if algorithms:
294
+ # For the stable query, choose only the first algorithm.
295
+ content.setdefault(user_id, {})[device_id] = next(iter(algorithms))
296
+ # For the unstable query, repeat each algorithm by count, then
297
+ # splat those into chain to get a flattened list of all algorithms.
298
+ #
299
+ # Converts from {"algo1": 2, "algo2": 2} to ["algo1", "algo1", "algo2"].
300
+ unstable_content.setdefault(user_id, {})[device_id] = list(
301
+ itertools.chain(
302
+ *(
303
+ itertools.repeat(algorithm, count)
304
+ for algorithm, count in algorithms.items()
305
+ )
306
+ )
307
+ )
308
+
309
+ if use_unstable:
310
+ try:
311
+ return await self.transport_layer.claim_client_keys_unstable(
312
+ user, destination, unstable_content, timeout
313
+ )
314
+ except HttpResponseException as e:
315
+ # If an error is received that is due to an unrecognised endpoint,
316
+ # fallback to the v1 endpoint. Otherwise, consider it a legitimate error
317
+ # and raise.
318
+ if not is_unknown_endpoint(e):
319
+ raise
320
+
321
+ logger.debug(
322
+ "Couldn't claim client keys with the unstable API, falling back to the v1 API"
323
+ )
324
+ else:
325
+ logger.debug("Skipping unstable claim client keys API")
326
+
327
+ # TODO Potentially attempt multiple queries and combine the results?
328
+ return await self.transport_layer.claim_client_keys(
329
+ user, destination, content, timeout
330
+ )
331
+
332
+ @trace
333
+ @tag_args
334
+ async def backfill(
335
+ self, dest: str, room_id: str, limit: int, extremities: Collection[str]
336
+ ) -> list[EventBase] | None:
337
+ """Requests some more historic PDUs for the given room from the
338
+ given destination server.
339
+
340
+ Args:
341
+ dest: The remote homeserver to ask.
342
+ room_id: The room_id to backfill.
343
+ limit: The maximum number of events to return.
344
+ extremities: our current backwards extremities, to backfill from
345
+ Must be a Collection that is falsy when empty.
346
+ (Iterable is not enough here!)
347
+ """
348
+ logger.debug("backfill extrem=%s", extremities)
349
+
350
+ # If there are no extremities then we've (probably) reached the start.
351
+ if not extremities:
352
+ return None
353
+
354
+ transaction_data = await self.transport_layer.backfill(
355
+ dest, room_id, extremities, limit
356
+ )
357
+
358
+ logger.debug("backfill transaction_data=%r", transaction_data)
359
+
360
+ if not isinstance(transaction_data, dict):
361
+ raise InvalidResponseError("Backfill transaction_data is not a dict.")
362
+
363
+ transaction_data_pdus = transaction_data.get("pdus")
364
+ if not isinstance(transaction_data_pdus, list):
365
+ raise InvalidResponseError("transaction_data.pdus is not a list.")
366
+
367
+ room_version = await self.store.get_room_version(room_id)
368
+
369
+ pdus = parse_events_from_pdu_json(transaction_data_pdus, room_version)
370
+
371
+ # Check signatures and hash of pdus, removing any from the list that fail checks
372
+ pdus[:] = await self._check_sigs_and_hash_for_pulled_events_and_fetch(
373
+ dest, pdus, room_version=room_version
374
+ )
375
+
376
+ return pdus
377
+
378
+ async def get_pdu_from_destination_raw(
379
+ self,
380
+ destination: str,
381
+ event_id: str,
382
+ room_version: RoomVersion,
383
+ timeout: int | None = None,
384
+ ) -> EventBase | None:
385
+ """Requests the PDU with given origin and ID from the remote home
386
+ server. Does not have any caching or rate limiting!
387
+
388
+ Args:
389
+ destination: Which homeserver to query
390
+ event_id: event to fetch
391
+ room_version: version of the room
392
+ timeout: How long to try (in ms) each destination for before
393
+ moving to the next destination. None indicates no timeout.
394
+
395
+ Returns:
396
+ A copy of the requested PDU that is safe to modify, or None if we
397
+ were unable to find it.
398
+
399
+ Raises:
400
+ SynapseError, NotRetryingDestination, FederationDeniedError
401
+ """
402
+ transaction_data = await self.transport_layer.get_event(
403
+ destination, event_id, timeout=timeout
404
+ )
405
+
406
+ logger.debug(
407
+ "get_pdu_from_destination_raw: retrieved event id %s from %s: %r",
408
+ event_id,
409
+ destination,
410
+ transaction_data,
411
+ )
412
+
413
+ pdu_list = parse_events_from_pdu_json(transaction_data["pdus"], room_version)
414
+
415
+ if pdu_list and pdu_list[0]:
416
+ pdu = pdu_list[0]
417
+
418
+ # Check signatures are correct.
419
+ try:
420
+
421
+ async def _record_failure_callback(
422
+ event: EventBase, cause: str
423
+ ) -> None:
424
+ await self.store.record_event_failed_pull_attempt(
425
+ event.room_id, event.event_id, cause
426
+ )
427
+
428
+ signed_pdu = await self._check_sigs_and_hash(
429
+ room_version, pdu, _record_failure_callback
430
+ )
431
+ except InvalidEventSignatureError as e:
432
+ errmsg = f"event id {pdu.event_id}: {e}"
433
+ logger.warning("%s", errmsg)
434
+ raise SynapseError(403, errmsg, Codes.FORBIDDEN)
435
+
436
+ return signed_pdu
437
+
438
+ return None
439
+
440
+ @trace
441
+ @tag_args
442
+ async def get_pdu_policy_recommendation(
443
+ self, destination: str, pdu: EventBase, timeout: int | None = None
444
+ ) -> str:
445
+ """Requests that the destination server (typically a policy server)
446
+ check the event and return its recommendation on how to handle the
447
+ event.
448
+
449
+ If the policy server could not be contacted or the policy server
450
+ returned an unknown recommendation, this returns an OK recommendation.
451
+ This type fixing behaviour is done because the typical caller will be
452
+ in a critical call path and would generally interpret a `None` or similar
453
+ response as "weird value; don't care; move on without taking action". We
454
+ just frontload that logic here.
455
+
456
+
457
+ Args:
458
+ destination: The remote homeserver to ask (a policy server)
459
+ pdu: The event to check
460
+ timeout: How long to try (in ms) the destination for before
461
+ giving up. None indicates no timeout.
462
+
463
+ Returns:
464
+ The policy recommendation, or RECOMMENDATION_OK if the policy server was
465
+ uncontactable or returned an unknown recommendation.
466
+ """
467
+
468
+ logger.debug(
469
+ "get_pdu_policy_recommendation for event_id=%s from %s",
470
+ pdu.event_id,
471
+ destination,
472
+ )
473
+
474
+ try:
475
+ res = await self.transport_layer.get_policy_recommendation_for_pdu(
476
+ destination, pdu, timeout=timeout
477
+ )
478
+ recommendation = res.get("recommendation")
479
+ if not isinstance(recommendation, str):
480
+ raise InvalidResponseError("recommendation is not a string")
481
+ if recommendation not in (RECOMMENDATION_OK, RECOMMENDATION_SPAM):
482
+ logger.warning(
483
+ "get_pdu_policy_recommendation: unknown recommendation: %s",
484
+ recommendation,
485
+ )
486
+ return RECOMMENDATION_OK
487
+ return recommendation
488
+ except Exception as e:
489
+ logger.warning(
490
+ "get_pdu_policy_recommendation: server %s responded with error, assuming OK recommendation: %s",
491
+ destination,
492
+ e,
493
+ )
494
+ return RECOMMENDATION_OK
495
+
496
+ @trace
497
+ @tag_args
498
+ async def ask_policy_server_to_sign_event(
499
+ self, destination: str, pdu: EventBase, timeout: int | None = None
500
+ ) -> JsonDict | None:
501
+ """Requests that the destination server (typically a policy server)
502
+ sign the event as not spam.
503
+
504
+ If the policy server could not be contacted or the policy server
505
+ returned an error, this returns no signature.
506
+
507
+ Args:
508
+ destination: The remote homeserver to ask (a policy server)
509
+ pdu: The event to sign
510
+ timeout: How long to try (in ms) the destination for before
511
+ giving up. None indicates no timeout.
512
+ Returns:
513
+ The signature from the policy server, structured in the same was as the 'signatures'
514
+ JSON in the event e.g { "$policy_server_via_domain" : { "ed25519:policy_server": "signature_base64" }}
515
+ """
516
+ logger.debug(
517
+ "ask_policy_server_to_sign_event for event_id=%s from %s",
518
+ pdu.event_id,
519
+ destination,
520
+ )
521
+ try:
522
+ return await self.transport_layer.ask_policy_server_to_sign_event(
523
+ destination, pdu, timeout=timeout
524
+ )
525
+ except Exception as e:
526
+ logger.warning(
527
+ "ask_policy_server_to_sign_event: server %s responded with error: %s",
528
+ destination,
529
+ e,
530
+ )
531
+ return None
532
+
533
+ @trace
534
+ @tag_args
535
+ async def get_pdu(
536
+ self,
537
+ destinations: Collection[str],
538
+ event_id: str,
539
+ room_version: RoomVersion,
540
+ timeout: int | None = None,
541
+ ) -> PulledPduInfo | None:
542
+ """Requests the PDU with given origin and ID from the remote home
543
+ servers.
544
+
545
+ Will attempt to get the PDU from each destination in the list until
546
+ one succeeds.
547
+
548
+ Args:
549
+ destinations: Which homeservers to query
550
+ event_id: event to fetch
551
+ room_version: version of the room
552
+ timeout: How long to try (in ms) each destination for before
553
+ moving to the next destination. None indicates no timeout.
554
+
555
+ Returns:
556
+ The requested PDU wrapped in `PulledPduInfo`, or None if we were unable to find it.
557
+ """
558
+
559
+ logger.debug(
560
+ "get_pdu(event_id=%s): from destinations=%s", event_id, destinations
561
+ )
562
+
563
+ # TODO: Rate limit the number of times we try and get the same event.
564
+
565
+ # We might need the same event multiple times in quick succession (before
566
+ # it gets persisted to the database), so we cache the results of the lookup.
567
+ # Note that this is separate to the regular get_event cache which caches
568
+ # events once they have been persisted.
569
+ get_pdu_cache_entry = self._get_pdu_cache.get(event_id)
570
+
571
+ event = None
572
+ pull_origin = None
573
+ if get_pdu_cache_entry:
574
+ event, pull_origin = get_pdu_cache_entry
575
+ # If we don't see the event in the cache, go try to fetch it from the
576
+ # provided remote federated destinations
577
+ else:
578
+ pdu_attempts = self.pdu_destination_tried.setdefault(event_id, {})
579
+
580
+ # TODO: We can probably refactor this to use `_try_destination_list`
581
+ for destination in destinations:
582
+ now = self._clock.time_msec()
583
+ last_attempt = pdu_attempts.get(destination, 0)
584
+ if last_attempt + PDU_RETRY_TIME_MS > now:
585
+ logger.debug(
586
+ "get_pdu(event_id=%s): skipping destination=%s because we tried it recently last_attempt=%s and we only check every %s (now=%s)",
587
+ event_id,
588
+ destination,
589
+ last_attempt,
590
+ PDU_RETRY_TIME_MS,
591
+ now,
592
+ )
593
+ continue
594
+
595
+ try:
596
+ event = await self.get_pdu_from_destination_raw(
597
+ destination=destination,
598
+ event_id=event_id,
599
+ room_version=room_version,
600
+ timeout=timeout,
601
+ )
602
+ pull_origin = destination
603
+
604
+ pdu_attempts[destination] = now
605
+
606
+ if event:
607
+ # Prime the cache
608
+ self._get_pdu_cache[event.event_id] = (event, pull_origin)
609
+
610
+ # Now that we have an event, we can break out of this
611
+ # loop and stop asking other destinations.
612
+ break
613
+
614
+ except NotRetryingDestination as e:
615
+ logger.info("get_pdu(event_id=%s): %s", event_id, e)
616
+ continue
617
+ except FederationDeniedError:
618
+ logger.info(
619
+ "get_pdu(event_id=%s): Not attempting to fetch PDU from %s because the homeserver is not on our federation whitelist",
620
+ event_id,
621
+ destination,
622
+ )
623
+ continue
624
+ except SynapseError as e:
625
+ logger.info(
626
+ "get_pdu(event_id=%s): Failed to get PDU from %s because %s",
627
+ event_id,
628
+ destination,
629
+ e,
630
+ )
631
+ continue
632
+ except Exception as e:
633
+ pdu_attempts[destination] = now
634
+
635
+ logger.info(
636
+ "get_pdu(event_id=%s): Failed to get PDU from %s because %s",
637
+ event_id,
638
+ destination,
639
+ e,
640
+ )
641
+ continue
642
+
643
+ if not event or not pull_origin:
644
+ return None
645
+
646
+ # `event` now refers to an object stored in `get_pdu_cache`. Our
647
+ # callers may need to modify the returned object (eg to set
648
+ # `event.internal_metadata.outlier = true`), so we return a copy
649
+ # rather than the original object.
650
+ event_copy = make_event_from_dict(
651
+ event.get_pdu_json(),
652
+ event.room_version,
653
+ )
654
+
655
+ return PulledPduInfo(event_copy, pull_origin)
656
+
657
+ @trace
658
+ @tag_args
659
+ async def get_room_state_ids(
660
+ self, destination: str, room_id: str, event_id: str
661
+ ) -> tuple[list[str], list[str]]:
662
+ """Calls the /state_ids endpoint to fetch the state at a particular point
663
+ in the room, and the auth events for the given event
664
+
665
+ Returns:
666
+ a tuple of (state event_ids, auth event_ids)
667
+
668
+ Raises:
669
+ InvalidResponseError: if fields in the response have the wrong type.
670
+ """
671
+ result = await self.transport_layer.get_room_state_ids(
672
+ destination, room_id, event_id=event_id
673
+ )
674
+
675
+ state_event_ids = result["pdu_ids"]
676
+ auth_event_ids = result.get("auth_chain_ids", [])
677
+
678
+ set_tag(
679
+ SynapseTags.RESULT_PREFIX + "state_event_ids",
680
+ str(state_event_ids),
681
+ )
682
+ set_tag(
683
+ SynapseTags.RESULT_PREFIX + "state_event_ids.length",
684
+ str(len(state_event_ids)),
685
+ )
686
+ set_tag(
687
+ SynapseTags.RESULT_PREFIX + "auth_event_ids",
688
+ str(auth_event_ids),
689
+ )
690
+ set_tag(
691
+ SynapseTags.RESULT_PREFIX + "auth_event_ids.length",
692
+ str(len(auth_event_ids)),
693
+ )
694
+
695
+ if not isinstance(state_event_ids, list) or not isinstance(
696
+ auth_event_ids, list
697
+ ):
698
+ raise InvalidResponseError("invalid response from /state_ids")
699
+
700
+ return state_event_ids, auth_event_ids
701
+
702
+ @trace
703
+ @tag_args
704
+ async def get_room_state(
705
+ self,
706
+ destination: str,
707
+ room_id: str,
708
+ event_id: str,
709
+ room_version: RoomVersion,
710
+ ) -> tuple[list[EventBase], list[EventBase]]:
711
+ """Calls the /state endpoint to fetch the state at a particular point
712
+ in the room.
713
+
714
+ Any invalid events (those with incorrect or unverifiable signatures or hashes)
715
+ are filtered out from the response, and any duplicate events are removed.
716
+
717
+ (Size limits and other event-format checks are *not* performed.)
718
+
719
+ Note that the result is not ordered, so callers must be careful to process
720
+ the events in an order that handles dependencies.
721
+
722
+ Returns:
723
+ a tuple of (state events, auth events)
724
+ """
725
+ result = await self.transport_layer.get_room_state(
726
+ room_version,
727
+ destination,
728
+ room_id,
729
+ event_id,
730
+ )
731
+ state_events = result.state
732
+ auth_events = result.auth_events
733
+
734
+ # we may as well filter out any duplicates from the response, to save
735
+ # processing them multiple times. (In particular, events may be present in
736
+ # `auth_events` as well as `state`, which is redundant).
737
+ #
738
+ # We don't rely on the sort order of the events, so we can just stick them
739
+ # in a dict.
740
+ state_event_map = {event.event_id: event for event in state_events}
741
+ auth_event_map = {
742
+ event.event_id: event
743
+ for event in auth_events
744
+ if event.event_id not in state_event_map
745
+ }
746
+
747
+ logger.info(
748
+ "Processing from /state: %d state events, %d auth events",
749
+ len(state_event_map),
750
+ len(auth_event_map),
751
+ )
752
+
753
+ valid_auth_events = await self._check_sigs_and_hash_for_pulled_events_and_fetch(
754
+ destination, auth_event_map.values(), room_version
755
+ )
756
+
757
+ valid_state_events = (
758
+ await self._check_sigs_and_hash_for_pulled_events_and_fetch(
759
+ destination, state_event_map.values(), room_version
760
+ )
761
+ )
762
+
763
+ return valid_state_events, valid_auth_events
764
+
765
+ @trace
766
+ async def _check_sigs_and_hash_for_pulled_events_and_fetch(
767
+ self,
768
+ origin: str,
769
+ pdus: Collection[EventBase],
770
+ room_version: RoomVersion,
771
+ ) -> list[EventBase]:
772
+ """
773
+ Checks the signatures and hashes of a list of pulled events we got from
774
+ federation and records any signature failures as failed pull attempts.
775
+
776
+ If a PDU fails its signature check then we check if we have it in
777
+ the database, and if not then request it from the sender's server (if that
778
+ is different from `origin`). If that still fails, the event is omitted from
779
+ the returned list.
780
+
781
+ If a PDU fails its content hash check then it is redacted.
782
+
783
+ Also runs each event through the spam checker; if it fails, redacts the event
784
+ and flags it as soft-failed.
785
+
786
+ The given list of PDUs are not modified; instead the function returns
787
+ a new list.
788
+
789
+ Args:
790
+ origin: The server that sent us these events
791
+ pdus: The events to be checked
792
+ room_version: the version of the room these events are in
793
+
794
+ Returns:
795
+ A list of PDUs that have valid signatures and hashes.
796
+ """
797
+ set_tag(
798
+ SynapseTags.RESULT_PREFIX + "pdus.length",
799
+ str(len(pdus)),
800
+ )
801
+
802
+ # We limit how many PDUs we check at once, as if we try to do hundreds
803
+ # of thousands of PDUs at once we see large memory spikes.
804
+
805
+ valid_pdus: list[EventBase] = []
806
+
807
+ async def _record_failure_callback(event: EventBase, cause: str) -> None:
808
+ await self.store.record_event_failed_pull_attempt(
809
+ event.room_id, event.event_id, cause
810
+ )
811
+
812
+ async def _execute(pdu: EventBase) -> None:
813
+ valid_pdu = await self._check_sigs_and_hash_and_fetch_one(
814
+ pdu=pdu,
815
+ origin=origin,
816
+ room_version=room_version,
817
+ record_failure_callback=_record_failure_callback,
818
+ )
819
+
820
+ if valid_pdu:
821
+ valid_pdus.append(valid_pdu)
822
+
823
+ await concurrently_execute(_execute, pdus, 10000)
824
+
825
+ return valid_pdus
826
+
827
+ @trace
828
+ @tag_args
829
+ async def _check_sigs_and_hash_and_fetch_one(
830
+ self,
831
+ pdu: EventBase,
832
+ origin: str,
833
+ room_version: RoomVersion,
834
+ record_failure_callback: Callable[[EventBase, str], Awaitable[None]]
835
+ | None = None,
836
+ ) -> EventBase | None:
837
+ """Takes a PDU and checks its signatures and hashes.
838
+
839
+ If the PDU fails its signature check then we check if we have it in the
840
+ database; if not, we then request it from sender's server (if that is not the
841
+ same as `origin`). If that still fails, we return None.
842
+
843
+ If the PDU fails its content hash check, it is redacted.
844
+
845
+ Also runs the event through the spam checker; if it fails, redacts the event
846
+ and flags it as soft-failed.
847
+
848
+ Args:
849
+ origin
850
+ pdu
851
+ room_version
852
+ record_failure_callback: A callback to run whenever the given event
853
+ fails signature or hash checks. This includes exceptions
854
+ that would be normally be thrown/raised but also things like
855
+ checking for event tampering where we just return the redacted
856
+ event.
857
+
858
+ Returns:
859
+ The PDU (possibly redacted) if it has valid signatures and hashes.
860
+ None if no valid copy could be found.
861
+ """
862
+
863
+ try:
864
+ return await self._check_sigs_and_hash(
865
+ room_version, pdu, record_failure_callback
866
+ )
867
+ except InvalidEventSignatureError as e:
868
+ logger.warning(
869
+ "Signature on retrieved event %s was invalid (%s). "
870
+ "Checking local store/origin server",
871
+ pdu.event_id,
872
+ e,
873
+ )
874
+ log_kv(
875
+ {
876
+ "message": "Signature on retrieved event was invalid. "
877
+ "Checking local store/origin server",
878
+ "event_id": pdu.event_id,
879
+ "InvalidEventSignatureError": e,
880
+ }
881
+ )
882
+
883
+ # Check local db.
884
+ res = await self.store.get_event(
885
+ pdu.event_id, allow_rejected=True, allow_none=True
886
+ )
887
+
888
+ # If the PDU fails its signature check and we don't have it in our
889
+ # database, we then request it from sender's server (if that is not the
890
+ # same as `origin`).
891
+ pdu_origin = get_domain_from_id(pdu.sender)
892
+ if not res and pdu_origin != origin:
893
+ try:
894
+ pulled_pdu_info = await self.get_pdu(
895
+ destinations=[pdu_origin],
896
+ event_id=pdu.event_id,
897
+ room_version=room_version,
898
+ timeout=10000,
899
+ )
900
+ if pulled_pdu_info is not None:
901
+ res = pulled_pdu_info.pdu
902
+ except SynapseError:
903
+ pass
904
+
905
+ if not res:
906
+ logger.warning(
907
+ "Failed to find copy of %s with valid signature", pdu.event_id
908
+ )
909
+
910
+ return res
911
+
912
+ async def get_event_auth(
913
+ self, destination: str, room_id: str, event_id: str
914
+ ) -> list[EventBase]:
915
+ res = await self.transport_layer.get_event_auth(destination, room_id, event_id)
916
+
917
+ room_version = await self.store.get_room_version(room_id)
918
+
919
+ auth_chain = parse_events_from_pdu_json(res["auth_chain"], room_version)
920
+
921
+ signed_auth = await self._check_sigs_and_hash_for_pulled_events_and_fetch(
922
+ destination, auth_chain, room_version=room_version
923
+ )
924
+
925
+ return signed_auth
926
+
927
+ async def _try_destination_list(
928
+ self,
929
+ description: str,
930
+ destinations: Iterable[str],
931
+ callback: Callable[[str], Awaitable[T]],
932
+ failover_errcodes: Container[str] | None = None,
933
+ failover_on_unknown_endpoint: bool = False,
934
+ ) -> T:
935
+ """Try an operation on a series of servers, until it succeeds
936
+
937
+ Args:
938
+ description: description of the operation we're doing, for logging
939
+
940
+ destinations: list of server_names to try
941
+
942
+ callback: Function to run for each server. Passed a single
943
+ argument: the server_name to try.
944
+
945
+ If the callback raises a CodeMessageException with a 300/400 code or
946
+ an UnsupportedRoomVersionError, attempts to perform the operation
947
+ stop immediately and the exception is reraised.
948
+
949
+ Otherwise, if the callback raises an Exception the error is logged and the
950
+ next server tried. Normally the stacktrace is logged but this is
951
+ suppressed if the exception is an InvalidResponseError.
952
+
953
+ failover_errcodes: Error codes (specific to this endpoint) which should
954
+ cause a failover when received as part of an HTTP 400 error.
955
+
956
+ failover_on_unknown_endpoint: if True, we will try other servers if it looks
957
+ like a server doesn't support the endpoint. This is typically useful
958
+ if the endpoint in question is new or experimental.
959
+
960
+ Returns:
961
+ The result of callback, if it succeeds
962
+
963
+ Raises:
964
+ SynapseError if the chosen remote server returns a 300/400 code, or
965
+ no servers were reachable.
966
+ """
967
+ if failover_errcodes is None:
968
+ failover_errcodes = ()
969
+
970
+ if not destinations:
971
+ # Give a bit of a clearer message if no servers were specified at all.
972
+ raise SynapseError(
973
+ 502, f"Failed to {description} via any server: No servers specified."
974
+ )
975
+
976
+ for destination in destinations:
977
+ # We don't want to ask our own server for information we don't have
978
+ if self._is_mine_server_name(destination):
979
+ continue
980
+
981
+ try:
982
+ return await callback(destination)
983
+ except (
984
+ RequestSendFailed,
985
+ InvalidResponseError,
986
+ ) as e:
987
+ logger.warning("Failed to %s via %s: %s", description, destination, e)
988
+ # Skip to the next homeserver in the list to try.
989
+ continue
990
+ except NotRetryingDestination as e:
991
+ logger.info("%s: %s", description, e)
992
+ continue
993
+ except FederationDeniedError:
994
+ logger.info(
995
+ "%s: Not attempting to %s from %s because the homeserver is not on our federation whitelist",
996
+ description,
997
+ description,
998
+ destination,
999
+ )
1000
+ continue
1001
+ except UnsupportedRoomVersionError:
1002
+ raise
1003
+ except HttpResponseException as e:
1004
+ synapse_error = e.to_synapse_error()
1005
+ failover = False
1006
+
1007
+ # Failover should occur:
1008
+ #
1009
+ # * On internal server errors.
1010
+ # * If the destination responds that it cannot complete the request.
1011
+ # * If the destination doesn't implemented the endpoint for some reason.
1012
+ if 500 <= e.code < 600:
1013
+ failover = True
1014
+
1015
+ elif 400 <= e.code < 500 and synapse_error.errcode in failover_errcodes:
1016
+ failover = True
1017
+
1018
+ elif failover_on_unknown_endpoint and is_unknown_endpoint(
1019
+ e, synapse_error
1020
+ ):
1021
+ failover = True
1022
+
1023
+ if not failover:
1024
+ raise synapse_error from e
1025
+
1026
+ logger.warning(
1027
+ "Failed to %s via %s: %i %s",
1028
+ description,
1029
+ destination,
1030
+ e.code,
1031
+ e.args[0],
1032
+ )
1033
+ except Exception:
1034
+ logger.warning(
1035
+ "Failed to %s via %s", description, destination, exc_info=True
1036
+ )
1037
+
1038
+ raise SynapseError(502, f"Failed to {description} via any server")
1039
+
1040
+ async def make_membership_event(
1041
+ self,
1042
+ destinations: Iterable[str],
1043
+ room_id: str,
1044
+ user_id: str,
1045
+ membership: str,
1046
+ content: dict,
1047
+ params: Mapping[str, str | Iterable[str]] | None,
1048
+ ) -> tuple[str, EventBase, RoomVersion]:
1049
+ """
1050
+ Creates an m.room.member event, with context, without participating in the room.
1051
+
1052
+ Does so by asking one of the already participating servers to create an
1053
+ event with proper context.
1054
+
1055
+ Returns a fully signed and hashed event.
1056
+
1057
+ Note that this does not append any events to any graphs.
1058
+
1059
+ Args:
1060
+ destinations: Candidate homeservers which are probably
1061
+ participating in the room.
1062
+ room_id: The room in which the event will happen.
1063
+ user_id: The user whose membership is being evented.
1064
+ membership: The "membership" property of the event. Must be one of
1065
+ "join" or "leave".
1066
+ content: Any additional data to put into the content field of the
1067
+ event.
1068
+ params: Query parameters to include in the request.
1069
+
1070
+ Returns:
1071
+ `(origin, event, room_version)` where origin is the remote
1072
+ homeserver which generated the event, and room_version is the
1073
+ version of the room.
1074
+
1075
+ Raises:
1076
+ UnsupportedRoomVersionError: if remote responds with
1077
+ a room version we don't understand.
1078
+
1079
+ SynapseError: if the chosen remote server returns a 300/400 code, or
1080
+ no servers successfully handle the request.
1081
+ """
1082
+ valid_memberships = {Membership.JOIN, Membership.LEAVE, Membership.KNOCK}
1083
+
1084
+ if membership not in valid_memberships:
1085
+ raise RuntimeError(
1086
+ "make_membership_event called with membership='%s', must be one of %s"
1087
+ % (membership, ",".join(valid_memberships))
1088
+ )
1089
+
1090
+ async def send_request(destination: str) -> tuple[str, EventBase, RoomVersion]:
1091
+ ret = await self.transport_layer.make_membership_event(
1092
+ destination, room_id, user_id, membership, params
1093
+ )
1094
+
1095
+ # Note: If not supplied, the room version may be either v1 or v2,
1096
+ # however either way the event format version will be v1.
1097
+ room_version_id = ret.get("room_version", RoomVersions.V1.identifier)
1098
+ room_version = KNOWN_ROOM_VERSIONS.get(room_version_id)
1099
+ if not room_version:
1100
+ raise UnsupportedRoomVersionError()
1101
+
1102
+ if not room_version.knock_join_rule and membership == Membership.KNOCK:
1103
+ raise SynapseError(
1104
+ 400,
1105
+ "This room version does not support knocking",
1106
+ errcode=Codes.FORBIDDEN,
1107
+ )
1108
+
1109
+ pdu_dict = ret.get("event", None)
1110
+ if not isinstance(pdu_dict, dict):
1111
+ raise InvalidResponseError("Bad 'event' field in response")
1112
+
1113
+ logger.debug("Got response to make_%s: %s", membership, pdu_dict)
1114
+
1115
+ pdu_dict["content"].update(content)
1116
+
1117
+ # The protoevent received over the JSON wire may not have all
1118
+ # the required fields. Lets just gloss over that because
1119
+ # there's some we never care about
1120
+ ev = builder.create_local_event_from_event_dict(
1121
+ self._clock,
1122
+ self.server_name,
1123
+ self.signing_key,
1124
+ room_version=room_version,
1125
+ event_dict=pdu_dict,
1126
+ )
1127
+
1128
+ return destination, ev, room_version
1129
+
1130
+ failover_errcodes = {Codes.NOT_FOUND}
1131
+ # MSC3083 defines additional error codes for room joins. Unfortunately
1132
+ # we do not yet know the room version, assume these will only be returned
1133
+ # by valid room versions.
1134
+ if membership == Membership.JOIN:
1135
+ failover_errcodes.add(Codes.UNABLE_AUTHORISE_JOIN)
1136
+ failover_errcodes.add(Codes.UNABLE_TO_GRANT_JOIN)
1137
+
1138
+ return await self._try_destination_list(
1139
+ "make_" + membership,
1140
+ destinations,
1141
+ send_request,
1142
+ failover_errcodes=failover_errcodes,
1143
+ )
1144
+
1145
+ async def send_join(
1146
+ self,
1147
+ destinations: Iterable[str],
1148
+ pdu: EventBase,
1149
+ room_version: RoomVersion,
1150
+ partial_state: bool = True,
1151
+ ) -> SendJoinResult:
1152
+ """Sends a join event to one of a list of homeservers.
1153
+
1154
+ Doing so will cause the remote server to add the event to the graph,
1155
+ and send the event out to the rest of the federation.
1156
+
1157
+ Args:
1158
+ destinations: Candidate homeservers which are probably
1159
+ participating in the room.
1160
+ pdu: event to be sent
1161
+ room_version: the version of the room (according to the server that
1162
+ did the make_join)
1163
+ partial_state: whether to ask the remote server to omit membership state
1164
+ events from the response. If the remote server complies,
1165
+ `partial_state` in the send join result will be set. Defaults to
1166
+ `True`.
1167
+
1168
+ Returns:
1169
+ The result of the send join request.
1170
+
1171
+ Raises:
1172
+ SynapseError: if the chosen remote server returns a 300/400 code, or
1173
+ no servers successfully handle the request.
1174
+ """
1175
+
1176
+ async def send_request(destination: str) -> SendJoinResult:
1177
+ response = await self._do_send_join(
1178
+ room_version, destination, pdu, omit_members=partial_state
1179
+ )
1180
+
1181
+ # If an event was returned (and expected to be returned):
1182
+ #
1183
+ # * Ensure it has the same event ID (note that the event ID is a hash
1184
+ # of the event fields for versions which support MSC3083).
1185
+ # * Ensure the signatures are good.
1186
+ #
1187
+ # Otherwise, fallback to the provided event.
1188
+ if room_version.restricted_join_rule and response.event:
1189
+ event = response.event
1190
+
1191
+ valid_pdu = await self._check_sigs_and_hash_and_fetch_one(
1192
+ pdu=event,
1193
+ origin=destination,
1194
+ room_version=room_version,
1195
+ )
1196
+
1197
+ if valid_pdu is None or event.event_id != pdu.event_id:
1198
+ raise InvalidResponseError("Returned an invalid join event")
1199
+ else:
1200
+ event = pdu
1201
+
1202
+ state = response.state
1203
+ auth_chain = response.auth_events
1204
+
1205
+ create_event = None
1206
+ for e in state:
1207
+ if (e.type, e.state_key) == (EventTypes.Create, ""):
1208
+ create_event = e
1209
+ break
1210
+
1211
+ if create_event is None:
1212
+ # If the state doesn't have a create event then the room is
1213
+ # invalid, and it would fail auth checks anyway.
1214
+ raise InvalidResponseError("No create event in state")
1215
+
1216
+ # the room version should be sane.
1217
+ create_room_version = create_event.content.get(
1218
+ "room_version", RoomVersions.V1.identifier
1219
+ )
1220
+ if create_room_version != room_version.identifier:
1221
+ # either the server that fulfilled the make_join, or the server that is
1222
+ # handling the send_join, is lying.
1223
+ raise InvalidResponseError(
1224
+ "Unexpected room version %s in create event"
1225
+ % (create_room_version,)
1226
+ )
1227
+
1228
+ logger.info(
1229
+ "Processing from send_join %d events", len(state) + len(auth_chain)
1230
+ )
1231
+
1232
+ # We now go and check the signatures and hashes for the event. Note
1233
+ # that we limit how many events we process at a time to keep the
1234
+ # memory overhead from exploding.
1235
+ valid_pdus_map: dict[str, EventBase] = {}
1236
+
1237
+ async def _execute(pdu: EventBase) -> None:
1238
+ valid_pdu = await self._check_sigs_and_hash_and_fetch_one(
1239
+ pdu=pdu,
1240
+ origin=destination,
1241
+ room_version=room_version,
1242
+ )
1243
+
1244
+ if valid_pdu:
1245
+ valid_pdus_map[valid_pdu.event_id] = valid_pdu
1246
+
1247
+ await concurrently_execute(
1248
+ _execute, itertools.chain(state, auth_chain), 10000
1249
+ )
1250
+
1251
+ # NB: We *need* to copy to ensure that we don't have multiple
1252
+ # references being passed on, as that causes... issues.
1253
+ signed_state = [
1254
+ copy.copy(valid_pdus_map[p.event_id])
1255
+ for p in state
1256
+ if p.event_id in valid_pdus_map
1257
+ ]
1258
+
1259
+ signed_auth = [
1260
+ valid_pdus_map[p.event_id]
1261
+ for p in auth_chain
1262
+ if p.event_id in valid_pdus_map
1263
+ ]
1264
+
1265
+ # NB: We *need* to copy to ensure that we don't have multiple
1266
+ # references being passed on, as that causes... issues.
1267
+ for s in signed_state:
1268
+ s.internal_metadata = s.internal_metadata.copy()
1269
+
1270
+ # double-check that the auth chain doesn't include a different create event
1271
+ auth_chain_create_events = [
1272
+ e.event_id
1273
+ for e in signed_auth
1274
+ if (e.type, e.state_key) == (EventTypes.Create, "")
1275
+ ]
1276
+ if auth_chain_create_events and auth_chain_create_events != [
1277
+ create_event.event_id
1278
+ ]:
1279
+ raise InvalidResponseError(
1280
+ "Unexpected create event(s) in auth chain: %s"
1281
+ % (auth_chain_create_events,)
1282
+ )
1283
+
1284
+ servers_in_room = None
1285
+ if response.servers_in_room is not None:
1286
+ servers_in_room = set(response.servers_in_room)
1287
+
1288
+ if response.members_omitted:
1289
+ if not servers_in_room:
1290
+ raise InvalidResponseError(
1291
+ "members_omitted was set, but no servers were listed in the room"
1292
+ )
1293
+
1294
+ if not partial_state:
1295
+ raise InvalidResponseError(
1296
+ "members_omitted was set, but we asked for full state"
1297
+ )
1298
+
1299
+ # `servers_in_room` is supposed to be a complete list.
1300
+ # Fix things up in case the remote homeserver is badly behaved.
1301
+ servers_in_room.add(destination)
1302
+
1303
+ return SendJoinResult(
1304
+ event=event,
1305
+ state=signed_state,
1306
+ auth_chain=signed_auth,
1307
+ origin=destination,
1308
+ partial_state=response.members_omitted,
1309
+ servers_in_room=servers_in_room or frozenset(),
1310
+ )
1311
+
1312
+ # MSC3083 defines additional error codes for room joins.
1313
+ failover_errcodes = None
1314
+ if room_version.restricted_join_rule:
1315
+ failover_errcodes = (
1316
+ Codes.UNABLE_AUTHORISE_JOIN,
1317
+ Codes.UNABLE_TO_GRANT_JOIN,
1318
+ )
1319
+
1320
+ # If the join is being authorised via allow rules, we need to send
1321
+ # the /send_join back to the same server that was originally used
1322
+ # with /make_join.
1323
+ if EventContentFields.AUTHORISING_USER in pdu.content:
1324
+ destinations = [
1325
+ get_domain_from_id(pdu.content[EventContentFields.AUTHORISING_USER])
1326
+ ]
1327
+
1328
+ return await self._try_destination_list(
1329
+ "send_join", destinations, send_request, failover_errcodes=failover_errcodes
1330
+ )
1331
+
1332
+ async def _do_send_join(
1333
+ self,
1334
+ room_version: RoomVersion,
1335
+ destination: str,
1336
+ pdu: EventBase,
1337
+ omit_members: bool,
1338
+ ) -> SendJoinResponse:
1339
+ time_now = self._clock.time_msec()
1340
+
1341
+ try:
1342
+ return await self.transport_layer.send_join_v2(
1343
+ room_version=room_version,
1344
+ destination=destination,
1345
+ room_id=pdu.room_id,
1346
+ event_id=pdu.event_id,
1347
+ content=pdu.get_pdu_json(time_now),
1348
+ omit_members=omit_members,
1349
+ )
1350
+ except HttpResponseException as e:
1351
+ # If an error is received that is due to an unrecognised endpoint,
1352
+ # fallback to the v1 endpoint. Otherwise, consider it a legitimate error
1353
+ # and raise.
1354
+ if not is_unknown_endpoint(e):
1355
+ raise
1356
+
1357
+ logger.debug("Couldn't send_join with the v2 API, falling back to the v1 API")
1358
+
1359
+ return await self.transport_layer.send_join_v1(
1360
+ room_version=room_version,
1361
+ destination=destination,
1362
+ room_id=pdu.room_id,
1363
+ event_id=pdu.event_id,
1364
+ content=pdu.get_pdu_json(time_now),
1365
+ )
1366
+
1367
+ async def send_invite(
1368
+ self,
1369
+ destination: str,
1370
+ room_id: str,
1371
+ event_id: str,
1372
+ pdu: EventBase,
1373
+ ) -> EventBase:
1374
+ room_version = await self.store.get_room_version(room_id)
1375
+
1376
+ content = await self._do_send_invite(destination, pdu, room_version)
1377
+
1378
+ pdu_dict = content["event"]
1379
+
1380
+ logger.debug("Got response to send_invite: %s", pdu_dict)
1381
+
1382
+ pdu = event_from_pdu_json(pdu_dict, room_version)
1383
+
1384
+ # Check signatures are correct.
1385
+ try:
1386
+ pdu = await self._check_sigs_and_hash(room_version, pdu)
1387
+ except InvalidEventSignatureError as e:
1388
+ errmsg = f"event id {pdu.event_id}: {e}"
1389
+ logger.warning("%s", errmsg)
1390
+ raise SynapseError(403, errmsg, Codes.FORBIDDEN)
1391
+
1392
+ # FIXME: We should handle signature failures more gracefully.
1393
+
1394
+ return pdu
1395
+
1396
+ async def _do_send_invite(
1397
+ self, destination: str, pdu: EventBase, room_version: RoomVersion
1398
+ ) -> JsonDict:
1399
+ """Actually sends the invite, first trying v2 API and falling back to
1400
+ v1 API if necessary.
1401
+
1402
+ Returns:
1403
+ The event as a dict as returned by the remote server
1404
+
1405
+ Raises:
1406
+ SynapseError: if the remote server returns an error or if the server
1407
+ only supports the v1 endpoint and a room version other than "1"
1408
+ or "2" is requested.
1409
+ """
1410
+ time_now = self._clock.time_msec()
1411
+
1412
+ try:
1413
+ return await self.transport_layer.send_invite_v2(
1414
+ destination=destination,
1415
+ room_id=pdu.room_id,
1416
+ event_id=pdu.event_id,
1417
+ content={
1418
+ "event": pdu.get_pdu_json(time_now),
1419
+ "room_version": room_version.identifier,
1420
+ "invite_room_state": pdu.unsigned.get("invite_room_state", []),
1421
+ },
1422
+ )
1423
+ except HttpResponseException as e:
1424
+ # If an error is received that is due to an unrecognised endpoint,
1425
+ # fallback to the v1 endpoint if the room uses old-style event IDs.
1426
+ # Otherwise, consider it a legitimate error and raise.
1427
+ err = e.to_synapse_error()
1428
+ if is_unknown_endpoint(e, err):
1429
+ if room_version.event_format != EventFormatVersions.ROOM_V1_V2:
1430
+ raise SynapseError(
1431
+ 400,
1432
+ "User's homeserver does not support this room version",
1433
+ Codes.UNSUPPORTED_ROOM_VERSION,
1434
+ )
1435
+ else:
1436
+ raise err
1437
+
1438
+ # Didn't work, try v1 API.
1439
+ # Note the v1 API returns a tuple of `(200, content)`
1440
+
1441
+ _, content = await self.transport_layer.send_invite_v1(
1442
+ destination=destination,
1443
+ room_id=pdu.room_id,
1444
+ event_id=pdu.event_id,
1445
+ content=pdu.get_pdu_json(time_now),
1446
+ )
1447
+ return content
1448
+
1449
+ async def send_leave(self, destinations: Iterable[str], pdu: EventBase) -> None:
1450
+ """Sends a leave event to one of a list of homeservers.
1451
+
1452
+ Doing so will cause the remote server to add the event to the graph,
1453
+ and send the event out to the rest of the federation.
1454
+
1455
+ This is mostly useful to reject received invites.
1456
+
1457
+ Args:
1458
+ destinations: Candidate homeservers which are probably
1459
+ participating in the room.
1460
+ pdu: event to be sent
1461
+
1462
+ Raises:
1463
+ SynapseError: if the chosen remote server returns a 300/400 code, or
1464
+ no servers successfully handle the request.
1465
+ """
1466
+
1467
+ async def send_request(destination: str) -> None:
1468
+ content = await self._do_send_leave(destination, pdu)
1469
+ logger.debug("Got content: %s", content)
1470
+
1471
+ return await self._try_destination_list(
1472
+ "send_leave", destinations, send_request
1473
+ )
1474
+
1475
+ async def _do_send_leave(self, destination: str, pdu: EventBase) -> JsonDict:
1476
+ time_now = self._clock.time_msec()
1477
+
1478
+ try:
1479
+ return await self.transport_layer.send_leave_v2(
1480
+ destination=destination,
1481
+ room_id=pdu.room_id,
1482
+ event_id=pdu.event_id,
1483
+ content=pdu.get_pdu_json(time_now),
1484
+ )
1485
+ except HttpResponseException as e:
1486
+ # If an error is received that is due to an unrecognised endpoint,
1487
+ # fallback to the v1 endpoint. Otherwise, consider it a legitimate error
1488
+ # and raise.
1489
+ if not is_unknown_endpoint(e):
1490
+ raise
1491
+
1492
+ logger.debug("Couldn't send_leave with the v2 API, falling back to the v1 API")
1493
+
1494
+ resp = await self.transport_layer.send_leave_v1(
1495
+ destination=destination,
1496
+ room_id=pdu.room_id,
1497
+ event_id=pdu.event_id,
1498
+ content=pdu.get_pdu_json(time_now),
1499
+ )
1500
+
1501
+ # We expect the v1 API to respond with [200, content], so we only return the
1502
+ # content.
1503
+ return resp[1]
1504
+
1505
+ async def send_knock(self, destinations: list[str], pdu: EventBase) -> JsonDict:
1506
+ """Attempts to send a knock event to a given list of servers. Iterates
1507
+ through the list until one attempt succeeds.
1508
+
1509
+ Doing so will cause the remote server to add the event to the graph,
1510
+ and send the event out to the rest of the federation.
1511
+
1512
+ Args:
1513
+ destinations: A list of candidate homeservers which are likely to be
1514
+ participating in the room.
1515
+ pdu: The event to be sent.
1516
+
1517
+ Returns:
1518
+ The remote homeserver return some state from the room. The response
1519
+ dictionary is in the form:
1520
+
1521
+ {"knock_room_state": [<state event dict>, ...]}
1522
+
1523
+ The list of state events may be empty.
1524
+
1525
+ Raises:
1526
+ SynapseError: If the chosen remote server returns a 3xx/4xx code.
1527
+ RuntimeError: If no servers were reachable.
1528
+ """
1529
+
1530
+ async def send_request(destination: str) -> JsonDict:
1531
+ return await self._do_send_knock(destination, pdu)
1532
+
1533
+ return await self._try_destination_list(
1534
+ "send_knock", destinations, send_request
1535
+ )
1536
+
1537
+ async def _do_send_knock(self, destination: str, pdu: EventBase) -> JsonDict:
1538
+ """Send a knock event to a remote homeserver.
1539
+
1540
+ Args:
1541
+ destination: The homeserver to send to.
1542
+ pdu: The event to send.
1543
+
1544
+ Returns:
1545
+ The remote homeserver can optionally return some state from the room. The response
1546
+ dictionary is in the form:
1547
+
1548
+ {"knock_room_state": [<state event dict>, ...]}
1549
+
1550
+ The list of state events may be empty.
1551
+ """
1552
+ time_now = self._clock.time_msec()
1553
+
1554
+ return await self.transport_layer.send_knock_v1(
1555
+ destination=destination,
1556
+ room_id=pdu.room_id,
1557
+ event_id=pdu.event_id,
1558
+ content=pdu.get_pdu_json(time_now),
1559
+ )
1560
+
1561
+ async def get_public_rooms(
1562
+ self,
1563
+ remote_server: str,
1564
+ limit: int | None = None,
1565
+ since_token: str | None = None,
1566
+ search_filter: dict | None = None,
1567
+ include_all_networks: bool = False,
1568
+ third_party_instance_id: str | None = None,
1569
+ ) -> JsonDict:
1570
+ """Get the list of public rooms from a remote homeserver
1571
+
1572
+ Args:
1573
+ remote_server: The name of the remote server
1574
+ limit: Maximum amount of rooms to return
1575
+ since_token: Used for result pagination
1576
+ search_filter: A filter dictionary to send the remote homeserver
1577
+ and filter the result set
1578
+ include_all_networks: Whether to include results from all third party instances
1579
+ third_party_instance_id: Whether to only include results from a specific third
1580
+ party instance
1581
+
1582
+ Returns:
1583
+ The response from the remote server.
1584
+
1585
+ Raises:
1586
+ HttpResponseException / RequestSendFailed: There was an exception
1587
+ returned from the remote server
1588
+ SynapseException: M_FORBIDDEN when the remote server has disallowed publicRoom
1589
+ requests over federation
1590
+
1591
+ """
1592
+ return await self.transport_layer.get_public_rooms(
1593
+ remote_server,
1594
+ limit,
1595
+ since_token,
1596
+ search_filter,
1597
+ include_all_networks=include_all_networks,
1598
+ third_party_instance_id=third_party_instance_id,
1599
+ )
1600
+
1601
+ async def get_missing_events(
1602
+ self,
1603
+ destination: str,
1604
+ room_id: str,
1605
+ earliest_events_ids: Iterable[str],
1606
+ latest_events: Iterable[EventBase],
1607
+ limit: int,
1608
+ min_depth: int,
1609
+ timeout: int,
1610
+ ) -> list[EventBase]:
1611
+ """Tries to fetch events we are missing. This is called when we receive
1612
+ an event without having received all of its ancestors.
1613
+
1614
+ Args:
1615
+ destination
1616
+ room_id
1617
+ earliest_events_ids: List of event ids. Effectively the
1618
+ events we expected to receive, but haven't. `get_missing_events`
1619
+ should only return events that didn't happen before these.
1620
+ latest_events: List of events we have received that we don't
1621
+ have all previous events for.
1622
+ limit: Maximum number of events to return.
1623
+ min_depth: Minimum depth of events to return.
1624
+ timeout: Max time to wait in ms
1625
+ """
1626
+ try:
1627
+ content = await self.transport_layer.get_missing_events(
1628
+ destination=destination,
1629
+ room_id=room_id,
1630
+ earliest_events=earliest_events_ids,
1631
+ latest_events=[e.event_id for e in latest_events],
1632
+ limit=limit,
1633
+ min_depth=min_depth,
1634
+ timeout=timeout,
1635
+ )
1636
+
1637
+ room_version = await self.store.get_room_version(room_id)
1638
+
1639
+ events = parse_events_from_pdu_json(content.get("events", []), room_version)
1640
+
1641
+ signed_events = await self._check_sigs_and_hash_for_pulled_events_and_fetch(
1642
+ destination, events, room_version=room_version
1643
+ )
1644
+ except HttpResponseException as e:
1645
+ if not e.code == 400:
1646
+ raise
1647
+
1648
+ # We are probably hitting an old server that doesn't support
1649
+ # get_missing_events
1650
+ signed_events = []
1651
+
1652
+ return signed_events
1653
+
1654
+ async def forward_third_party_invite(
1655
+ self, destinations: Iterable[str], room_id: str, event_dict: JsonDict
1656
+ ) -> None:
1657
+ for destination in destinations:
1658
+ if self._is_mine_server_name(destination):
1659
+ continue
1660
+
1661
+ try:
1662
+ await self.transport_layer.exchange_third_party_invite(
1663
+ destination=destination, room_id=room_id, event_dict=event_dict
1664
+ )
1665
+ return
1666
+ except CodeMessageException:
1667
+ raise
1668
+ except Exception as e:
1669
+ logger.exception(
1670
+ "Failed to send_third_party_invite via %s: %s", destination, str(e)
1671
+ )
1672
+
1673
+ raise RuntimeError("Failed to send to any server.")
1674
+
1675
+ async def get_room_complexity(
1676
+ self, destination: str, room_id: str
1677
+ ) -> JsonDict | None:
1678
+ """
1679
+ Fetch the complexity of a remote room from another server.
1680
+
1681
+ Args:
1682
+ destination: The remote server
1683
+ room_id: The room ID to ask about.
1684
+
1685
+ Returns:
1686
+ Dict contains the complexity metric versions, while None means we
1687
+ could not fetch the complexity.
1688
+ """
1689
+ try:
1690
+ return await self.transport_layer.get_room_complexity(
1691
+ destination=destination, room_id=room_id
1692
+ )
1693
+ except CodeMessageException as e:
1694
+ # We didn't manage to get it -- probably a 404. We are okay if other
1695
+ # servers don't give it to us.
1696
+ logger.debug(
1697
+ "Failed to fetch room complexity via %s for %s, got a %d",
1698
+ destination,
1699
+ room_id,
1700
+ e.code,
1701
+ )
1702
+ except Exception:
1703
+ logger.exception(
1704
+ "Failed to fetch room complexity via %s for %s", destination, room_id
1705
+ )
1706
+
1707
+ # If we don't manage to find it, return None. It's not an error if a
1708
+ # server doesn't give it to us.
1709
+ return None
1710
+
1711
+ async def get_room_hierarchy(
1712
+ self,
1713
+ destinations: Iterable[str],
1714
+ room_id: str,
1715
+ suggested_only: bool,
1716
+ ) -> tuple[JsonDict, Sequence[JsonDict], Sequence[JsonDict], Sequence[str]]:
1717
+ """
1718
+ Call other servers to get a hierarchy of the given room.
1719
+
1720
+ Performs simple data validates and parsing of the response.
1721
+
1722
+ Args:
1723
+ destinations: The remote servers. We will try them in turn, omitting any
1724
+ that have been blacklisted.
1725
+ room_id: ID of the space to be queried
1726
+ suggested_only: If true, ask the remote server to only return children
1727
+ with the "suggested" flag set
1728
+
1729
+ Returns:
1730
+ A tuple of:
1731
+ The room as a JSON dictionary, without a "children_state" key.
1732
+ A list of `m.space.child` state events.
1733
+ A list of children rooms, as JSON dictionaries.
1734
+ A list of inaccessible children room IDs.
1735
+
1736
+ Raises:
1737
+ SynapseError if we were unable to get a valid summary from any of the
1738
+ remote servers
1739
+ """
1740
+
1741
+ cached_result = self._get_room_hierarchy_cache.get((room_id, suggested_only))
1742
+ if cached_result:
1743
+ return cached_result
1744
+
1745
+ async def send_request(
1746
+ destination: str,
1747
+ ) -> tuple[JsonDict, Sequence[JsonDict], Sequence[JsonDict], Sequence[str]]:
1748
+ try:
1749
+ res = await self.transport_layer.get_room_hierarchy(
1750
+ destination=destination,
1751
+ room_id=room_id,
1752
+ suggested_only=suggested_only,
1753
+ )
1754
+ except HttpResponseException as e:
1755
+ # If an error is received that is due to an unrecognised endpoint,
1756
+ # fallback to the unstable endpoint. Otherwise, consider it a
1757
+ # legitimate error and raise.
1758
+ if not is_unknown_endpoint(e):
1759
+ raise
1760
+
1761
+ logger.debug(
1762
+ "Couldn't fetch room hierarchy with the v1 API, falling back to the unstable API"
1763
+ )
1764
+
1765
+ res = await self.transport_layer.get_room_hierarchy_unstable(
1766
+ destination=destination,
1767
+ room_id=room_id,
1768
+ suggested_only=suggested_only,
1769
+ )
1770
+
1771
+ room = res.get("room")
1772
+ if not isinstance(room, dict):
1773
+ raise InvalidResponseError("'room' must be a dict")
1774
+ if room.get("room_id") != room_id:
1775
+ raise InvalidResponseError("wrong room returned in hierarchy response")
1776
+
1777
+ # Validate children_state of the room.
1778
+ children_state = room.pop("children_state", [])
1779
+ if not isinstance(children_state, list):
1780
+ raise InvalidResponseError("'room.children_state' must be a list")
1781
+ if any(not isinstance(e, dict) for e in children_state):
1782
+ raise InvalidResponseError("Invalid event in 'children_state' list")
1783
+ try:
1784
+ for child_state in children_state:
1785
+ _validate_hierarchy_event(child_state)
1786
+ except ValueError as e:
1787
+ raise InvalidResponseError(str(e))
1788
+
1789
+ # Validate the children rooms.
1790
+ children = res.get("children", [])
1791
+ if not isinstance(children, list):
1792
+ raise InvalidResponseError("'children' must be a list")
1793
+ if any(not isinstance(r, dict) for r in children):
1794
+ raise InvalidResponseError("Invalid room in 'children' list")
1795
+
1796
+ # Validate the inaccessible children.
1797
+ inaccessible_children = res.get("inaccessible_children", [])
1798
+ if not isinstance(inaccessible_children, list):
1799
+ raise InvalidResponseError("'inaccessible_children' must be a list")
1800
+ if any(not isinstance(r, str) for r in inaccessible_children):
1801
+ raise InvalidResponseError(
1802
+ "Invalid room ID in 'inaccessible_children' list"
1803
+ )
1804
+
1805
+ return room, children_state, children, inaccessible_children
1806
+
1807
+ result = await self._try_destination_list(
1808
+ "fetch room hierarchy",
1809
+ destinations,
1810
+ send_request,
1811
+ failover_on_unknown_endpoint=True,
1812
+ )
1813
+
1814
+ # Cache the result to avoid fetching data over federation every time.
1815
+ self._get_room_hierarchy_cache[(room_id, suggested_only)] = result
1816
+ return result
1817
+
1818
+ async def timestamp_to_event(
1819
+ self,
1820
+ *,
1821
+ destinations: StrCollection,
1822
+ room_id: str,
1823
+ timestamp: int,
1824
+ direction: Direction,
1825
+ ) -> Optional["TimestampToEventResponse"]:
1826
+ """
1827
+ Calls each remote federating server from `destinations` asking for their closest
1828
+ event to the given timestamp in the given direction until we get a response.
1829
+ Also validates the response to always return the expected keys or raises an
1830
+ error.
1831
+
1832
+ Args:
1833
+ destinations: The domains of homeservers to try fetching from
1834
+ room_id: Room to fetch the event from
1835
+ timestamp: The point in time (inclusive) we should navigate from in
1836
+ the given direction to find the closest event.
1837
+ direction: indicates whether we should navigate forward
1838
+ or backward from the given timestamp to find the closest event.
1839
+
1840
+ Returns:
1841
+ A parsed TimestampToEventResponse including the closest event_id
1842
+ and origin_server_ts or None if no destination has a response.
1843
+ """
1844
+
1845
+ async def _timestamp_to_event_from_destination(
1846
+ destination: str,
1847
+ ) -> TimestampToEventResponse:
1848
+ return await self._timestamp_to_event_from_destination(
1849
+ destination, room_id, timestamp, direction
1850
+ )
1851
+
1852
+ try:
1853
+ # Loop through each homeserver candidate until we get a succesful response
1854
+ timestamp_to_event_response = await self._try_destination_list(
1855
+ "timestamp_to_event",
1856
+ destinations,
1857
+ # TODO: The requested timestamp may lie in a part of the
1858
+ # event graph that the remote server *also* didn't have,
1859
+ # in which case they will have returned another event
1860
+ # which may be nowhere near the requested timestamp. In
1861
+ # the future, we may need to reconcile that gap and ask
1862
+ # other homeservers, and/or extend `/timestamp_to_event`
1863
+ # to return events on *both* sides of the timestamp to
1864
+ # help reconcile the gap faster.
1865
+ _timestamp_to_event_from_destination,
1866
+ # Since this endpoint is new, we should try other servers before giving up.
1867
+ # We can safely remove this in a year (remove after 2023-11-16).
1868
+ failover_on_unknown_endpoint=True,
1869
+ )
1870
+ return timestamp_to_event_response
1871
+ except SynapseError as e:
1872
+ logger.warning(
1873
+ "timestamp_to_event(room_id=%s, timestamp=%s, direction=%s): encountered error when trying to fetch from destinations: %s",
1874
+ room_id,
1875
+ timestamp,
1876
+ direction,
1877
+ e,
1878
+ )
1879
+ return None
1880
+
1881
+ async def _timestamp_to_event_from_destination(
1882
+ self, destination: str, room_id: str, timestamp: int, direction: Direction
1883
+ ) -> "TimestampToEventResponse":
1884
+ """
1885
+ Calls a remote federating server at `destination` asking for their
1886
+ closest event to the given timestamp in the given direction. Also
1887
+ validates the response to always return the expected keys or raises an
1888
+ error.
1889
+
1890
+ Args:
1891
+ destination: Domain name of the remote homeserver
1892
+ room_id: Room to fetch the event from
1893
+ timestamp: The point in time (inclusive) we should navigate from in
1894
+ the given direction to find the closest event.
1895
+ direction: indicates whether we should navigate forward
1896
+ or backward from the given timestamp to find the closest event.
1897
+
1898
+ Returns:
1899
+ A parsed TimestampToEventResponse including the closest event_id
1900
+ and origin_server_ts
1901
+
1902
+ Raises:
1903
+ Various exceptions when the request fails
1904
+ InvalidResponseError when the response does not have the correct
1905
+ keys or wrong types
1906
+ """
1907
+ remote_response = await self.transport_layer.timestamp_to_event(
1908
+ destination, room_id, timestamp, direction
1909
+ )
1910
+
1911
+ if not isinstance(remote_response, dict):
1912
+ raise InvalidResponseError(
1913
+ "Response must be a JSON dictionary but received %r" % remote_response
1914
+ )
1915
+
1916
+ try:
1917
+ return TimestampToEventResponse.from_json_dict(remote_response)
1918
+ except ValueError as e:
1919
+ raise InvalidResponseError(str(e))
1920
+
1921
+ async def get_account_status(
1922
+ self, destination: str, user_ids: list[str]
1923
+ ) -> tuple[JsonDict, list[str]]:
1924
+ """Retrieves account statuses for a given list of users on a given remote
1925
+ homeserver.
1926
+
1927
+ If the request fails for any reason, all user IDs for this destination are marked
1928
+ as failed.
1929
+
1930
+ Args:
1931
+ destination: the destination to contact
1932
+ user_ids: the user ID(s) for which to request account status(es)
1933
+
1934
+ Returns:
1935
+ The account statuses, as well as the list of user IDs for which it was not
1936
+ possible to retrieve a status.
1937
+ """
1938
+ try:
1939
+ res = await self.transport_layer.get_account_status(destination, user_ids)
1940
+ except Exception:
1941
+ # If the query failed for any reason, mark all the users as failed.
1942
+ return {}, user_ids
1943
+
1944
+ statuses = res.get("account_statuses", {})
1945
+ failures = res.get("failures", [])
1946
+
1947
+ if not isinstance(statuses, dict) or not isinstance(failures, list):
1948
+ # Make sure we're not feeding back malformed data back to the caller.
1949
+ logger.warning(
1950
+ "Destination %s responded with malformed data to account_status query",
1951
+ destination,
1952
+ )
1953
+ return {}, user_ids
1954
+
1955
+ for user_id in user_ids:
1956
+ # Any account whose status is missing is a user we failed to receive the
1957
+ # status of.
1958
+ if user_id not in statuses and user_id not in failures:
1959
+ failures.append(user_id)
1960
+
1961
+ # Filter out any user ID that doesn't belong to the remote server that sent its
1962
+ # status (or failure).
1963
+ def filter_user_id(user_id: str) -> bool:
1964
+ try:
1965
+ return UserID.from_string(user_id).domain == destination
1966
+ except SynapseError:
1967
+ # If the user ID doesn't parse, ignore it.
1968
+ return False
1969
+
1970
+ filtered_statuses = dict(
1971
+ # item is a (key, value) tuple, so item[0] is the user ID.
1972
+ filter(lambda item: filter_user_id(item[0]), statuses.items())
1973
+ )
1974
+
1975
+ filtered_failures = list(filter(filter_user_id, failures))
1976
+
1977
+ return filtered_statuses, filtered_failures
1978
+
1979
+ async def federation_download_media(
1980
+ self,
1981
+ destination: str,
1982
+ media_id: str,
1983
+ output_stream: BinaryIO,
1984
+ max_size: int,
1985
+ max_timeout_ms: int,
1986
+ download_ratelimiter: Ratelimiter,
1987
+ ip_address: str,
1988
+ ) -> (
1989
+ tuple[int, dict[bytes, list[bytes]], bytes]
1990
+ | tuple[int, dict[bytes, list[bytes]]]
1991
+ ):
1992
+ try:
1993
+ return await self.transport_layer.federation_download_media(
1994
+ destination,
1995
+ media_id,
1996
+ output_stream=output_stream,
1997
+ max_size=max_size,
1998
+ max_timeout_ms=max_timeout_ms,
1999
+ download_ratelimiter=download_ratelimiter,
2000
+ ip_address=ip_address,
2001
+ )
2002
+ except HttpResponseException as e:
2003
+ # If an error is received that is due to an unrecognised endpoint,
2004
+ # fallback to the _matrix/media/v3/download endpoint. Otherwise, consider it a legitimate error
2005
+ # and raise.
2006
+ if not is_unknown_endpoint(e):
2007
+ raise
2008
+
2009
+ logger.debug(
2010
+ "Couldn't download media %s/%s over _matrix/federation/v1/media/download, falling back to _matrix/media/v3/download path",
2011
+ destination,
2012
+ media_id,
2013
+ )
2014
+
2015
+ return await self.transport_layer.download_media_v3(
2016
+ destination,
2017
+ media_id,
2018
+ output_stream=output_stream,
2019
+ max_size=max_size,
2020
+ max_timeout_ms=max_timeout_ms,
2021
+ download_ratelimiter=download_ratelimiter,
2022
+ ip_address=ip_address,
2023
+ )
2024
+
2025
+ async def download_media(
2026
+ self,
2027
+ destination: str,
2028
+ media_id: str,
2029
+ output_stream: BinaryIO,
2030
+ max_size: int,
2031
+ max_timeout_ms: int,
2032
+ download_ratelimiter: Ratelimiter,
2033
+ ip_address: str,
2034
+ ) -> tuple[int, dict[bytes, list[bytes]]]:
2035
+ try:
2036
+ return await self.transport_layer.download_media_v3(
2037
+ destination,
2038
+ media_id,
2039
+ output_stream=output_stream,
2040
+ max_size=max_size,
2041
+ max_timeout_ms=max_timeout_ms,
2042
+ download_ratelimiter=download_ratelimiter,
2043
+ ip_address=ip_address,
2044
+ )
2045
+ except HttpResponseException as e:
2046
+ # If an error is received that is due to an unrecognised endpoint,
2047
+ # fallback to the r0 endpoint. Otherwise, consider it a legitimate error
2048
+ # and raise.
2049
+ if not is_unknown_endpoint(e):
2050
+ raise
2051
+
2052
+ logger.debug(
2053
+ "Couldn't download media %s/%s with the v3 API, falling back to the r0 API",
2054
+ destination,
2055
+ media_id,
2056
+ )
2057
+
2058
+ return await self.transport_layer.download_media_r0(
2059
+ destination,
2060
+ media_id,
2061
+ output_stream=output_stream,
2062
+ max_size=max_size,
2063
+ max_timeout_ms=max_timeout_ms,
2064
+ download_ratelimiter=download_ratelimiter,
2065
+ ip_address=ip_address,
2066
+ )
2067
+
2068
+
2069
+ @attr.s(frozen=True, slots=True, auto_attribs=True)
2070
+ class TimestampToEventResponse:
2071
+ """Typed response dictionary for the federation /timestamp_to_event endpoint"""
2072
+
2073
+ event_id: str
2074
+ origin_server_ts: int
2075
+
2076
+ # the raw data, including the above keys
2077
+ data: JsonDict
2078
+
2079
+ @classmethod
2080
+ def from_json_dict(cls, d: JsonDict) -> "TimestampToEventResponse":
2081
+ """Parsed response from the federation /timestamp_to_event endpoint
2082
+
2083
+ Args:
2084
+ d: JSON object response to be parsed
2085
+
2086
+ Raises:
2087
+ ValueError if d does not the correct keys or they are the wrong types
2088
+ """
2089
+
2090
+ event_id = d.get("event_id")
2091
+ if not isinstance(event_id, str):
2092
+ raise ValueError(
2093
+ "Invalid response: 'event_id' must be a str but received %r" % event_id
2094
+ )
2095
+
2096
+ origin_server_ts = d.get("origin_server_ts")
2097
+ if type(origin_server_ts) is not int: # noqa: E721
2098
+ raise ValueError(
2099
+ "Invalid response: 'origin_server_ts' must be a int but received %r"
2100
+ % origin_server_ts
2101
+ )
2102
+
2103
+ return cls(event_id, origin_server_ts, d)
2104
+
2105
+
2106
+ def _validate_hierarchy_event(d: JsonDict) -> None:
2107
+ """Validate an event within the result of a /hierarchy request
2108
+
2109
+ Args:
2110
+ d: json object to be parsed
2111
+
2112
+ Raises:
2113
+ ValueError if d is not a valid event
2114
+ """
2115
+
2116
+ event_type = d.get("type")
2117
+ if not isinstance(event_type, str):
2118
+ raise ValueError("Invalid event: 'event_type' must be a str")
2119
+
2120
+ state_key = d.get("state_key")
2121
+ if not isinstance(state_key, str):
2122
+ raise ValueError("Invalid event: 'state_key' must be a str")
2123
+
2124
+ content = d.get("content")
2125
+ if not isinstance(content, dict):
2126
+ raise ValueError("Invalid event: 'content' must be a dict")
2127
+
2128
+ via = content.get("via")
2129
+ if not isinstance(via, list):
2130
+ raise ValueError("Invalid event: 'via' must be a list")
2131
+ if any(not isinstance(v, str) for v in via):
2132
+ raise ValueError("Invalid event: 'via' must be a list of strings")