matrix-synapse 1.142.0rc3__cp314-abi3-musllinux_1_2_aarch64.whl

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

Potentially problematic release.


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

Files changed (1057) hide show
  1. matrix_synapse-1.142.0rc3.dist-info/AUTHORS.rst +51 -0
  2. matrix_synapse-1.142.0rc3.dist-info/LICENSE-AGPL-3.0 +661 -0
  3. matrix_synapse-1.142.0rc3.dist-info/LICENSE-COMMERCIAL +6 -0
  4. matrix_synapse-1.142.0rc3.dist-info/METADATA +375 -0
  5. matrix_synapse-1.142.0rc3.dist-info/RECORD +1057 -0
  6. matrix_synapse-1.142.0rc3.dist-info/WHEEL +4 -0
  7. matrix_synapse-1.142.0rc3.dist-info/entry_points.txt +14 -0
  8. matrix_synapse.libs/libgcc_s-2d945d6c.so.1 +0 -0
  9. synapse/__init__.py +97 -0
  10. synapse/_scripts/__init__.py +0 -0
  11. synapse/_scripts/export_signing_key.py +109 -0
  12. synapse/_scripts/generate_config.py +83 -0
  13. synapse/_scripts/generate_log_config.py +56 -0
  14. synapse/_scripts/generate_signing_key.py +55 -0
  15. synapse/_scripts/generate_workers_map.py +318 -0
  16. synapse/_scripts/hash_password.py +95 -0
  17. synapse/_scripts/move_remote_media_to_new_store.py +128 -0
  18. synapse/_scripts/register_new_matrix_user.py +374 -0
  19. synapse/_scripts/review_recent_signups.py +212 -0
  20. synapse/_scripts/synapse_port_db.py +1603 -0
  21. synapse/_scripts/synctl.py +365 -0
  22. synapse/_scripts/update_synapse_database.py +130 -0
  23. synapse/api/__init__.py +20 -0
  24. synapse/api/auth/__init__.py +207 -0
  25. synapse/api/auth/base.py +406 -0
  26. synapse/api/auth/internal.py +299 -0
  27. synapse/api/auth/mas.py +457 -0
  28. synapse/api/auth/msc3861_delegated.py +617 -0
  29. synapse/api/auth_blocking.py +144 -0
  30. synapse/api/constants.py +362 -0
  31. synapse/api/errors.py +907 -0
  32. synapse/api/filtering.py +539 -0
  33. synapse/api/presence.py +104 -0
  34. synapse/api/ratelimiting.py +482 -0
  35. synapse/api/room_versions.py +535 -0
  36. synapse/api/urls.py +119 -0
  37. synapse/app/__init__.py +60 -0
  38. synapse/app/_base.py +866 -0
  39. synapse/app/admin_cmd.py +388 -0
  40. synapse/app/appservice.py +30 -0
  41. synapse/app/client_reader.py +30 -0
  42. synapse/app/complement_fork_starter.py +206 -0
  43. synapse/app/event_creator.py +29 -0
  44. synapse/app/federation_reader.py +30 -0
  45. synapse/app/federation_sender.py +30 -0
  46. synapse/app/frontend_proxy.py +30 -0
  47. synapse/app/generic_worker.py +475 -0
  48. synapse/app/homeserver.py +504 -0
  49. synapse/app/media_repository.py +30 -0
  50. synapse/app/phone_stats_home.py +296 -0
  51. synapse/app/pusher.py +30 -0
  52. synapse/app/synchrotron.py +30 -0
  53. synapse/app/user_dir.py +31 -0
  54. synapse/appservice/__init__.py +461 -0
  55. synapse/appservice/api.py +569 -0
  56. synapse/appservice/scheduler.py +567 -0
  57. synapse/config/__init__.py +27 -0
  58. synapse/config/__main__.py +62 -0
  59. synapse/config/_base.py +1108 -0
  60. synapse/config/_base.pyi +217 -0
  61. synapse/config/_util.py +99 -0
  62. synapse/config/account_validity.py +116 -0
  63. synapse/config/api.py +141 -0
  64. synapse/config/appservice.py +210 -0
  65. synapse/config/auth.py +80 -0
  66. synapse/config/auto_accept_invites.py +43 -0
  67. synapse/config/background_updates.py +44 -0
  68. synapse/config/cache.py +231 -0
  69. synapse/config/captcha.py +90 -0
  70. synapse/config/cas.py +116 -0
  71. synapse/config/consent.py +73 -0
  72. synapse/config/database.py +184 -0
  73. synapse/config/emailconfig.py +367 -0
  74. synapse/config/experimental.py +595 -0
  75. synapse/config/federation.py +114 -0
  76. synapse/config/homeserver.py +141 -0
  77. synapse/config/jwt.py +55 -0
  78. synapse/config/key.py +447 -0
  79. synapse/config/logger.py +390 -0
  80. synapse/config/mas.py +191 -0
  81. synapse/config/matrixrtc.py +66 -0
  82. synapse/config/metrics.py +84 -0
  83. synapse/config/modules.py +40 -0
  84. synapse/config/oembed.py +185 -0
  85. synapse/config/oidc.py +509 -0
  86. synapse/config/password_auth_providers.py +82 -0
  87. synapse/config/push.py +64 -0
  88. synapse/config/ratelimiting.py +254 -0
  89. synapse/config/redis.py +74 -0
  90. synapse/config/registration.py +296 -0
  91. synapse/config/repository.py +311 -0
  92. synapse/config/retention.py +162 -0
  93. synapse/config/room.py +88 -0
  94. synapse/config/room_directory.py +165 -0
  95. synapse/config/saml2.py +251 -0
  96. synapse/config/server.py +1170 -0
  97. synapse/config/server_notices.py +84 -0
  98. synapse/config/spam_checker.py +66 -0
  99. synapse/config/sso.py +121 -0
  100. synapse/config/stats.py +54 -0
  101. synapse/config/third_party_event_rules.py +40 -0
  102. synapse/config/tls.py +192 -0
  103. synapse/config/tracer.py +71 -0
  104. synapse/config/user_directory.py +47 -0
  105. synapse/config/user_types.py +44 -0
  106. synapse/config/voip.py +59 -0
  107. synapse/config/workers.py +642 -0
  108. synapse/crypto/__init__.py +20 -0
  109. synapse/crypto/context_factory.py +278 -0
  110. synapse/crypto/event_signing.py +194 -0
  111. synapse/crypto/keyring.py +931 -0
  112. synapse/event_auth.py +1266 -0
  113. synapse/events/__init__.py +668 -0
  114. synapse/events/auto_accept_invites.py +216 -0
  115. synapse/events/builder.py +387 -0
  116. synapse/events/presence_router.py +245 -0
  117. synapse/events/snapshot.py +559 -0
  118. synapse/events/utils.py +928 -0
  119. synapse/events/validator.py +305 -0
  120. synapse/federation/__init__.py +22 -0
  121. synapse/federation/federation_base.py +383 -0
  122. synapse/federation/federation_client.py +2134 -0
  123. synapse/federation/federation_server.py +1544 -0
  124. synapse/federation/persistence.py +71 -0
  125. synapse/federation/send_queue.py +532 -0
  126. synapse/federation/sender/__init__.py +1165 -0
  127. synapse/federation/sender/per_destination_queue.py +884 -0
  128. synapse/federation/sender/transaction_manager.py +210 -0
  129. synapse/federation/transport/__init__.py +28 -0
  130. synapse/federation/transport/client.py +1201 -0
  131. synapse/federation/transport/server/__init__.py +334 -0
  132. synapse/federation/transport/server/_base.py +429 -0
  133. synapse/federation/transport/server/federation.py +912 -0
  134. synapse/federation/units.py +133 -0
  135. synapse/handlers/__init__.py +20 -0
  136. synapse/handlers/account.py +162 -0
  137. synapse/handlers/account_data.py +362 -0
  138. synapse/handlers/account_validity.py +361 -0
  139. synapse/handlers/admin.py +618 -0
  140. synapse/handlers/appservice.py +991 -0
  141. synapse/handlers/auth.py +2494 -0
  142. synapse/handlers/cas.py +413 -0
  143. synapse/handlers/deactivate_account.py +363 -0
  144. synapse/handlers/delayed_events.py +635 -0
  145. synapse/handlers/device.py +1873 -0
  146. synapse/handlers/devicemessage.py +399 -0
  147. synapse/handlers/directory.py +554 -0
  148. synapse/handlers/e2e_keys.py +1834 -0
  149. synapse/handlers/e2e_room_keys.py +455 -0
  150. synapse/handlers/event_auth.py +390 -0
  151. synapse/handlers/events.py +201 -0
  152. synapse/handlers/federation.py +2043 -0
  153. synapse/handlers/federation_event.py +2420 -0
  154. synapse/handlers/identity.py +812 -0
  155. synapse/handlers/initial_sync.py +528 -0
  156. synapse/handlers/jwt.py +120 -0
  157. synapse/handlers/message.py +2347 -0
  158. synapse/handlers/oidc.py +1803 -0
  159. synapse/handlers/pagination.py +768 -0
  160. synapse/handlers/password_policy.py +102 -0
  161. synapse/handlers/presence.py +2638 -0
  162. synapse/handlers/profile.py +655 -0
  163. synapse/handlers/push_rules.py +164 -0
  164. synapse/handlers/read_marker.py +79 -0
  165. synapse/handlers/receipts.py +351 -0
  166. synapse/handlers/register.py +1060 -0
  167. synapse/handlers/relations.py +624 -0
  168. synapse/handlers/reports.py +98 -0
  169. synapse/handlers/room.py +2447 -0
  170. synapse/handlers/room_list.py +632 -0
  171. synapse/handlers/room_member.py +2365 -0
  172. synapse/handlers/room_member_worker.py +146 -0
  173. synapse/handlers/room_policy.py +186 -0
  174. synapse/handlers/room_summary.py +1057 -0
  175. synapse/handlers/saml.py +524 -0
  176. synapse/handlers/search.py +723 -0
  177. synapse/handlers/send_email.py +209 -0
  178. synapse/handlers/set_password.py +71 -0
  179. synapse/handlers/sliding_sync/__init__.py +1701 -0
  180. synapse/handlers/sliding_sync/extensions.py +970 -0
  181. synapse/handlers/sliding_sync/room_lists.py +2266 -0
  182. synapse/handlers/sliding_sync/store.py +128 -0
  183. synapse/handlers/sso.py +1292 -0
  184. synapse/handlers/state_deltas.py +82 -0
  185. synapse/handlers/stats.py +322 -0
  186. synapse/handlers/sync.py +3109 -0
  187. synapse/handlers/thread_subscriptions.py +190 -0
  188. synapse/handlers/typing.py +606 -0
  189. synapse/handlers/ui_auth/__init__.py +48 -0
  190. synapse/handlers/ui_auth/checkers.py +332 -0
  191. synapse/handlers/user_directory.py +783 -0
  192. synapse/handlers/worker_lock.py +365 -0
  193. synapse/http/__init__.py +106 -0
  194. synapse/http/additional_resource.py +62 -0
  195. synapse/http/client.py +1360 -0
  196. synapse/http/connectproxyclient.py +309 -0
  197. synapse/http/federation/__init__.py +19 -0
  198. synapse/http/federation/matrix_federation_agent.py +490 -0
  199. synapse/http/federation/srv_resolver.py +196 -0
  200. synapse/http/federation/well_known_resolver.py +367 -0
  201. synapse/http/matrixfederationclient.py +1875 -0
  202. synapse/http/proxy.py +290 -0
  203. synapse/http/proxyagent.py +497 -0
  204. synapse/http/replicationagent.py +203 -0
  205. synapse/http/request_metrics.py +309 -0
  206. synapse/http/server.py +1114 -0
  207. synapse/http/servlet.py +1019 -0
  208. synapse/http/site.py +825 -0
  209. synapse/http/types.py +27 -0
  210. synapse/logging/__init__.py +31 -0
  211. synapse/logging/_remote.py +261 -0
  212. synapse/logging/_terse_json.py +95 -0
  213. synapse/logging/context.py +1211 -0
  214. synapse/logging/formatter.py +63 -0
  215. synapse/logging/handlers.py +99 -0
  216. synapse/logging/loggers.py +25 -0
  217. synapse/logging/opentracing.py +1132 -0
  218. synapse/logging/scopecontextmanager.py +161 -0
  219. synapse/media/_base.py +827 -0
  220. synapse/media/filepath.py +417 -0
  221. synapse/media/media_repository.py +1580 -0
  222. synapse/media/media_storage.py +704 -0
  223. synapse/media/oembed.py +277 -0
  224. synapse/media/preview_html.py +559 -0
  225. synapse/media/storage_provider.py +195 -0
  226. synapse/media/thumbnailer.py +833 -0
  227. synapse/media/url_previewer.py +875 -0
  228. synapse/metrics/__init__.py +754 -0
  229. synapse/metrics/_gc.py +219 -0
  230. synapse/metrics/_reactor_metrics.py +171 -0
  231. synapse/metrics/_types.py +38 -0
  232. synapse/metrics/background_process_metrics.py +556 -0
  233. synapse/metrics/common_usage_metrics.py +94 -0
  234. synapse/metrics/jemalloc.py +248 -0
  235. synapse/module_api/__init__.py +2154 -0
  236. synapse/module_api/callbacks/__init__.py +50 -0
  237. synapse/module_api/callbacks/account_validity_callbacks.py +106 -0
  238. synapse/module_api/callbacks/media_repository_callbacks.py +160 -0
  239. synapse/module_api/callbacks/ratelimit_callbacks.py +79 -0
  240. synapse/module_api/callbacks/spamchecker_callbacks.py +1113 -0
  241. synapse/module_api/callbacks/third_party_event_rules_callbacks.py +599 -0
  242. synapse/module_api/errors.py +42 -0
  243. synapse/notifier.py +972 -0
  244. synapse/push/__init__.py +212 -0
  245. synapse/push/bulk_push_rule_evaluator.py +637 -0
  246. synapse/push/clientformat.py +126 -0
  247. synapse/push/emailpusher.py +333 -0
  248. synapse/push/httppusher.py +564 -0
  249. synapse/push/mailer.py +1012 -0
  250. synapse/push/presentable_names.py +216 -0
  251. synapse/push/push_tools.py +114 -0
  252. synapse/push/push_types.py +141 -0
  253. synapse/push/pusher.py +87 -0
  254. synapse/push/pusherpool.py +501 -0
  255. synapse/push/rulekinds.py +33 -0
  256. synapse/py.typed +0 -0
  257. synapse/replication/__init__.py +20 -0
  258. synapse/replication/http/__init__.py +68 -0
  259. synapse/replication/http/_base.py +468 -0
  260. synapse/replication/http/account_data.py +297 -0
  261. synapse/replication/http/deactivate_account.py +81 -0
  262. synapse/replication/http/delayed_events.py +62 -0
  263. synapse/replication/http/devices.py +254 -0
  264. synapse/replication/http/federation.py +334 -0
  265. synapse/replication/http/login.py +106 -0
  266. synapse/replication/http/membership.py +364 -0
  267. synapse/replication/http/presence.py +133 -0
  268. synapse/replication/http/push.py +156 -0
  269. synapse/replication/http/register.py +172 -0
  270. synapse/replication/http/send_events.py +182 -0
  271. synapse/replication/http/state.py +82 -0
  272. synapse/replication/http/streams.py +101 -0
  273. synapse/replication/tcp/__init__.py +56 -0
  274. synapse/replication/tcp/client.py +552 -0
  275. synapse/replication/tcp/commands.py +569 -0
  276. synapse/replication/tcp/context.py +41 -0
  277. synapse/replication/tcp/external_cache.py +156 -0
  278. synapse/replication/tcp/handler.py +942 -0
  279. synapse/replication/tcp/protocol.py +608 -0
  280. synapse/replication/tcp/redis.py +509 -0
  281. synapse/replication/tcp/resource.py +348 -0
  282. synapse/replication/tcp/streams/__init__.py +96 -0
  283. synapse/replication/tcp/streams/_base.py +766 -0
  284. synapse/replication/tcp/streams/events.py +287 -0
  285. synapse/replication/tcp/streams/federation.py +92 -0
  286. synapse/replication/tcp/streams/partial_state.py +80 -0
  287. synapse/res/providers.json +29 -0
  288. synapse/res/templates/_base.html +29 -0
  289. synapse/res/templates/account_previously_renewed.html +6 -0
  290. synapse/res/templates/account_renewed.html +6 -0
  291. synapse/res/templates/add_threepid.html +8 -0
  292. synapse/res/templates/add_threepid.txt +6 -0
  293. synapse/res/templates/add_threepid_failure.html +7 -0
  294. synapse/res/templates/add_threepid_success.html +6 -0
  295. synapse/res/templates/already_in_use.html +12 -0
  296. synapse/res/templates/already_in_use.txt +10 -0
  297. synapse/res/templates/auth_success.html +21 -0
  298. synapse/res/templates/invalid_token.html +6 -0
  299. synapse/res/templates/mail-Element.css +7 -0
  300. synapse/res/templates/mail-Vector.css +7 -0
  301. synapse/res/templates/mail-expiry.css +4 -0
  302. synapse/res/templates/mail.css +156 -0
  303. synapse/res/templates/notice_expiry.html +46 -0
  304. synapse/res/templates/notice_expiry.txt +7 -0
  305. synapse/res/templates/notif.html +51 -0
  306. synapse/res/templates/notif.txt +22 -0
  307. synapse/res/templates/notif_mail.html +59 -0
  308. synapse/res/templates/notif_mail.txt +10 -0
  309. synapse/res/templates/password_reset.html +10 -0
  310. synapse/res/templates/password_reset.txt +7 -0
  311. synapse/res/templates/password_reset_confirmation.html +15 -0
  312. synapse/res/templates/password_reset_failure.html +7 -0
  313. synapse/res/templates/password_reset_success.html +6 -0
  314. synapse/res/templates/recaptcha.html +42 -0
  315. synapse/res/templates/registration.html +12 -0
  316. synapse/res/templates/registration.txt +10 -0
  317. synapse/res/templates/registration_failure.html +6 -0
  318. synapse/res/templates/registration_success.html +6 -0
  319. synapse/res/templates/registration_token.html +18 -0
  320. synapse/res/templates/room.html +33 -0
  321. synapse/res/templates/room.txt +9 -0
  322. synapse/res/templates/sso.css +129 -0
  323. synapse/res/templates/sso_account_deactivated.html +25 -0
  324. synapse/res/templates/sso_auth_account_details.html +186 -0
  325. synapse/res/templates/sso_auth_account_details.js +116 -0
  326. synapse/res/templates/sso_auth_bad_user.html +26 -0
  327. synapse/res/templates/sso_auth_confirm.html +27 -0
  328. synapse/res/templates/sso_auth_success.html +26 -0
  329. synapse/res/templates/sso_error.html +71 -0
  330. synapse/res/templates/sso_footer.html +19 -0
  331. synapse/res/templates/sso_login_idp_picker.html +60 -0
  332. synapse/res/templates/sso_new_user_consent.html +30 -0
  333. synapse/res/templates/sso_partial_profile.html +19 -0
  334. synapse/res/templates/sso_redirect_confirm.html +39 -0
  335. synapse/res/templates/style.css +33 -0
  336. synapse/res/templates/terms.html +27 -0
  337. synapse/rest/__init__.py +197 -0
  338. synapse/rest/admin/__init__.py +390 -0
  339. synapse/rest/admin/_base.py +72 -0
  340. synapse/rest/admin/background_updates.py +171 -0
  341. synapse/rest/admin/devices.py +221 -0
  342. synapse/rest/admin/event_reports.py +173 -0
  343. synapse/rest/admin/events.py +69 -0
  344. synapse/rest/admin/experimental_features.py +137 -0
  345. synapse/rest/admin/federation.py +243 -0
  346. synapse/rest/admin/media.py +540 -0
  347. synapse/rest/admin/registration_tokens.py +358 -0
  348. synapse/rest/admin/rooms.py +1061 -0
  349. synapse/rest/admin/scheduled_tasks.py +70 -0
  350. synapse/rest/admin/server_notice_servlet.py +132 -0
  351. synapse/rest/admin/statistics.py +132 -0
  352. synapse/rest/admin/username_available.py +58 -0
  353. synapse/rest/admin/users.py +1608 -0
  354. synapse/rest/client/__init__.py +20 -0
  355. synapse/rest/client/_base.py +113 -0
  356. synapse/rest/client/account.py +930 -0
  357. synapse/rest/client/account_data.py +319 -0
  358. synapse/rest/client/account_validity.py +103 -0
  359. synapse/rest/client/appservice_ping.py +125 -0
  360. synapse/rest/client/auth.py +218 -0
  361. synapse/rest/client/auth_metadata.py +122 -0
  362. synapse/rest/client/capabilities.py +121 -0
  363. synapse/rest/client/delayed_events.py +111 -0
  364. synapse/rest/client/devices.py +587 -0
  365. synapse/rest/client/directory.py +211 -0
  366. synapse/rest/client/events.py +116 -0
  367. synapse/rest/client/filter.py +112 -0
  368. synapse/rest/client/initial_sync.py +65 -0
  369. synapse/rest/client/keys.py +678 -0
  370. synapse/rest/client/knock.py +104 -0
  371. synapse/rest/client/login.py +754 -0
  372. synapse/rest/client/login_token_request.py +127 -0
  373. synapse/rest/client/logout.py +93 -0
  374. synapse/rest/client/matrixrtc.py +52 -0
  375. synapse/rest/client/media.py +286 -0
  376. synapse/rest/client/mutual_rooms.py +93 -0
  377. synapse/rest/client/notifications.py +137 -0
  378. synapse/rest/client/openid.py +109 -0
  379. synapse/rest/client/password_policy.py +69 -0
  380. synapse/rest/client/presence.py +131 -0
  381. synapse/rest/client/profile.py +291 -0
  382. synapse/rest/client/push_rule.py +331 -0
  383. synapse/rest/client/pusher.py +181 -0
  384. synapse/rest/client/read_marker.py +104 -0
  385. synapse/rest/client/receipts.py +165 -0
  386. synapse/rest/client/register.py +1067 -0
  387. synapse/rest/client/relations.py +138 -0
  388. synapse/rest/client/rendezvous.py +76 -0
  389. synapse/rest/client/reporting.py +207 -0
  390. synapse/rest/client/room.py +1669 -0
  391. synapse/rest/client/room_keys.py +426 -0
  392. synapse/rest/client/room_upgrade_rest_servlet.py +112 -0
  393. synapse/rest/client/sendtodevice.py +85 -0
  394. synapse/rest/client/sync.py +1131 -0
  395. synapse/rest/client/tags.py +129 -0
  396. synapse/rest/client/thirdparty.py +130 -0
  397. synapse/rest/client/thread_subscriptions.py +247 -0
  398. synapse/rest/client/tokenrefresh.py +52 -0
  399. synapse/rest/client/transactions.py +149 -0
  400. synapse/rest/client/user_directory.py +90 -0
  401. synapse/rest/client/versions.py +191 -0
  402. synapse/rest/client/voip.py +88 -0
  403. synapse/rest/consent/__init__.py +0 -0
  404. synapse/rest/consent/consent_resource.py +210 -0
  405. synapse/rest/health.py +38 -0
  406. synapse/rest/key/__init__.py +20 -0
  407. synapse/rest/key/v2/__init__.py +40 -0
  408. synapse/rest/key/v2/local_key_resource.py +125 -0
  409. synapse/rest/key/v2/remote_key_resource.py +302 -0
  410. synapse/rest/media/__init__.py +0 -0
  411. synapse/rest/media/config_resource.py +53 -0
  412. synapse/rest/media/create_resource.py +90 -0
  413. synapse/rest/media/download_resource.py +110 -0
  414. synapse/rest/media/media_repository_resource.py +113 -0
  415. synapse/rest/media/preview_url_resource.py +77 -0
  416. synapse/rest/media/thumbnail_resource.py +142 -0
  417. synapse/rest/media/upload_resource.py +187 -0
  418. synapse/rest/media/v1/__init__.py +39 -0
  419. synapse/rest/media/v1/_base.py +23 -0
  420. synapse/rest/media/v1/media_storage.py +23 -0
  421. synapse/rest/media/v1/storage_provider.py +23 -0
  422. synapse/rest/synapse/__init__.py +20 -0
  423. synapse/rest/synapse/client/__init__.py +93 -0
  424. synapse/rest/synapse/client/federation_whitelist.py +66 -0
  425. synapse/rest/synapse/client/jwks.py +77 -0
  426. synapse/rest/synapse/client/new_user_consent.py +115 -0
  427. synapse/rest/synapse/client/oidc/__init__.py +45 -0
  428. synapse/rest/synapse/client/oidc/backchannel_logout_resource.py +42 -0
  429. synapse/rest/synapse/client/oidc/callback_resource.py +48 -0
  430. synapse/rest/synapse/client/password_reset.py +129 -0
  431. synapse/rest/synapse/client/pick_idp.py +107 -0
  432. synapse/rest/synapse/client/pick_username.py +153 -0
  433. synapse/rest/synapse/client/rendezvous.py +58 -0
  434. synapse/rest/synapse/client/saml2/__init__.py +42 -0
  435. synapse/rest/synapse/client/saml2/metadata_resource.py +46 -0
  436. synapse/rest/synapse/client/saml2/response_resource.py +52 -0
  437. synapse/rest/synapse/client/sso_register.py +56 -0
  438. synapse/rest/synapse/client/unsubscribe.py +88 -0
  439. synapse/rest/synapse/mas/__init__.py +71 -0
  440. synapse/rest/synapse/mas/_base.py +55 -0
  441. synapse/rest/synapse/mas/devices.py +239 -0
  442. synapse/rest/synapse/mas/users.py +469 -0
  443. synapse/rest/well_known.py +148 -0
  444. synapse/server.py +1258 -0
  445. synapse/server_notices/__init__.py +0 -0
  446. synapse/server_notices/consent_server_notices.py +136 -0
  447. synapse/server_notices/resource_limits_server_notices.py +215 -0
  448. synapse/server_notices/server_notices_manager.py +388 -0
  449. synapse/server_notices/server_notices_sender.py +67 -0
  450. synapse/server_notices/worker_server_notices_sender.py +46 -0
  451. synapse/spam_checker_api/__init__.py +31 -0
  452. synapse/state/__init__.py +1022 -0
  453. synapse/state/v1.py +370 -0
  454. synapse/state/v2.py +985 -0
  455. synapse/static/client/login/index.html +47 -0
  456. synapse/static/client/login/js/jquery-3.4.1.min.js +2 -0
  457. synapse/static/client/login/js/login.js +291 -0
  458. synapse/static/client/login/spinner.gif +0 -0
  459. synapse/static/client/login/style.css +79 -0
  460. synapse/static/index.html +63 -0
  461. synapse/storage/__init__.py +43 -0
  462. synapse/storage/_base.py +245 -0
  463. synapse/storage/admin_client_config.py +26 -0
  464. synapse/storage/background_updates.py +1189 -0
  465. synapse/storage/controllers/__init__.py +57 -0
  466. synapse/storage/controllers/persist_events.py +1239 -0
  467. synapse/storage/controllers/purge_events.py +456 -0
  468. synapse/storage/controllers/state.py +954 -0
  469. synapse/storage/controllers/stats.py +119 -0
  470. synapse/storage/database.py +2720 -0
  471. synapse/storage/databases/__init__.py +175 -0
  472. synapse/storage/databases/main/__init__.py +424 -0
  473. synapse/storage/databases/main/account_data.py +1060 -0
  474. synapse/storage/databases/main/appservice.py +473 -0
  475. synapse/storage/databases/main/cache.py +911 -0
  476. synapse/storage/databases/main/censor_events.py +225 -0
  477. synapse/storage/databases/main/client_ips.py +817 -0
  478. synapse/storage/databases/main/delayed_events.py +560 -0
  479. synapse/storage/databases/main/deviceinbox.py +1272 -0
  480. synapse/storage/databases/main/devices.py +2581 -0
  481. synapse/storage/databases/main/directory.py +212 -0
  482. synapse/storage/databases/main/e2e_room_keys.py +690 -0
  483. synapse/storage/databases/main/end_to_end_keys.py +1896 -0
  484. synapse/storage/databases/main/event_federation.py +2509 -0
  485. synapse/storage/databases/main/event_push_actions.py +1937 -0
  486. synapse/storage/databases/main/events.py +3746 -0
  487. synapse/storage/databases/main/events_bg_updates.py +2910 -0
  488. synapse/storage/databases/main/events_forward_extremities.py +126 -0
  489. synapse/storage/databases/main/events_worker.py +2784 -0
  490. synapse/storage/databases/main/experimental_features.py +130 -0
  491. synapse/storage/databases/main/filtering.py +231 -0
  492. synapse/storage/databases/main/keys.py +291 -0
  493. synapse/storage/databases/main/lock.py +553 -0
  494. synapse/storage/databases/main/media_repository.py +1070 -0
  495. synapse/storage/databases/main/metrics.py +460 -0
  496. synapse/storage/databases/main/monthly_active_users.py +443 -0
  497. synapse/storage/databases/main/openid.py +61 -0
  498. synapse/storage/databases/main/presence.py +511 -0
  499. synapse/storage/databases/main/profile.py +541 -0
  500. synapse/storage/databases/main/purge_events.py +511 -0
  501. synapse/storage/databases/main/push_rule.py +972 -0
  502. synapse/storage/databases/main/pusher.py +794 -0
  503. synapse/storage/databases/main/receipts.py +1342 -0
  504. synapse/storage/databases/main/registration.py +3076 -0
  505. synapse/storage/databases/main/rejections.py +38 -0
  506. synapse/storage/databases/main/relations.py +1118 -0
  507. synapse/storage/databases/main/room.py +2781 -0
  508. synapse/storage/databases/main/roommember.py +2112 -0
  509. synapse/storage/databases/main/search.py +941 -0
  510. synapse/storage/databases/main/session.py +151 -0
  511. synapse/storage/databases/main/signatures.py +94 -0
  512. synapse/storage/databases/main/sliding_sync.py +603 -0
  513. synapse/storage/databases/main/state.py +1006 -0
  514. synapse/storage/databases/main/state_deltas.py +329 -0
  515. synapse/storage/databases/main/stats.py +791 -0
  516. synapse/storage/databases/main/stream.py +2580 -0
  517. synapse/storage/databases/main/tags.py +360 -0
  518. synapse/storage/databases/main/task_scheduler.py +225 -0
  519. synapse/storage/databases/main/thread_subscriptions.py +591 -0
  520. synapse/storage/databases/main/transactions.py +681 -0
  521. synapse/storage/databases/main/ui_auth.py +420 -0
  522. synapse/storage/databases/main/user_directory.py +1331 -0
  523. synapse/storage/databases/main/user_erasure_store.py +117 -0
  524. synapse/storage/databases/state/__init__.py +22 -0
  525. synapse/storage/databases/state/bg_updates.py +499 -0
  526. synapse/storage/databases/state/deletion.py +558 -0
  527. synapse/storage/databases/state/store.py +949 -0
  528. synapse/storage/engines/__init__.py +70 -0
  529. synapse/storage/engines/_base.py +154 -0
  530. synapse/storage/engines/postgres.py +261 -0
  531. synapse/storage/engines/sqlite.py +199 -0
  532. synapse/storage/invite_rule.py +112 -0
  533. synapse/storage/keys.py +40 -0
  534. synapse/storage/prepare_database.py +731 -0
  535. synapse/storage/push_rule.py +28 -0
  536. synapse/storage/roommember.py +89 -0
  537. synapse/storage/schema/README.md +4 -0
  538. synapse/storage/schema/__init__.py +182 -0
  539. synapse/storage/schema/common/delta/25/00background_updates.sql +40 -0
  540. synapse/storage/schema/common/delta/35/00background_updates_add_col.sql +36 -0
  541. synapse/storage/schema/common/delta/58/00background_update_ordering.sql +38 -0
  542. synapse/storage/schema/common/full_schemas/72/full.sql.postgres +8 -0
  543. synapse/storage/schema/common/full_schemas/72/full.sql.sqlite +6 -0
  544. synapse/storage/schema/common/schema_version.sql +60 -0
  545. synapse/storage/schema/main/delta/12/v12.sql +82 -0
  546. synapse/storage/schema/main/delta/13/v13.sql +38 -0
  547. synapse/storage/schema/main/delta/14/v14.sql +42 -0
  548. synapse/storage/schema/main/delta/15/appservice_txns.sql +50 -0
  549. synapse/storage/schema/main/delta/15/presence_indices.sql +2 -0
  550. synapse/storage/schema/main/delta/15/v15.sql +24 -0
  551. synapse/storage/schema/main/delta/16/events_order_index.sql +4 -0
  552. synapse/storage/schema/main/delta/16/remote_media_cache_index.sql +2 -0
  553. synapse/storage/schema/main/delta/16/remove_duplicates.sql +9 -0
  554. synapse/storage/schema/main/delta/16/room_alias_index.sql +3 -0
  555. synapse/storage/schema/main/delta/16/unique_constraints.sql +72 -0
  556. synapse/storage/schema/main/delta/16/users.sql +56 -0
  557. synapse/storage/schema/main/delta/17/drop_indexes.sql +37 -0
  558. synapse/storage/schema/main/delta/17/server_keys.sql +43 -0
  559. synapse/storage/schema/main/delta/17/user_threepids.sql +9 -0
  560. synapse/storage/schema/main/delta/18/server_keys_bigger_ints.sql +51 -0
  561. synapse/storage/schema/main/delta/19/event_index.sql +38 -0
  562. synapse/storage/schema/main/delta/20/dummy.sql +1 -0
  563. synapse/storage/schema/main/delta/20/pushers.py +93 -0
  564. synapse/storage/schema/main/delta/21/end_to_end_keys.sql +53 -0
  565. synapse/storage/schema/main/delta/21/receipts.sql +57 -0
  566. synapse/storage/schema/main/delta/22/receipts_index.sql +41 -0
  567. synapse/storage/schema/main/delta/22/user_threepids_unique.sql +19 -0
  568. synapse/storage/schema/main/delta/24/stats_reporting.sql +37 -0
  569. synapse/storage/schema/main/delta/25/fts.py +81 -0
  570. synapse/storage/schema/main/delta/25/guest_access.sql +44 -0
  571. synapse/storage/schema/main/delta/25/history_visibility.sql +44 -0
  572. synapse/storage/schema/main/delta/25/tags.sql +57 -0
  573. synapse/storage/schema/main/delta/26/account_data.sql +36 -0
  574. synapse/storage/schema/main/delta/27/account_data.sql +55 -0
  575. synapse/storage/schema/main/delta/27/forgotten_memberships.sql +45 -0
  576. synapse/storage/schema/main/delta/27/ts.py +61 -0
  577. synapse/storage/schema/main/delta/28/event_push_actions.sql +46 -0
  578. synapse/storage/schema/main/delta/28/events_room_stream.sql +39 -0
  579. synapse/storage/schema/main/delta/28/public_roms_index.sql +39 -0
  580. synapse/storage/schema/main/delta/28/receipts_user_id_index.sql +41 -0
  581. synapse/storage/schema/main/delta/28/upgrade_times.sql +40 -0
  582. synapse/storage/schema/main/delta/28/users_is_guest.sql +41 -0
  583. synapse/storage/schema/main/delta/29/push_actions.sql +54 -0
  584. synapse/storage/schema/main/delta/30/alias_creator.sql +35 -0
  585. synapse/storage/schema/main/delta/30/as_users.py +82 -0
  586. synapse/storage/schema/main/delta/30/deleted_pushers.sql +44 -0
  587. synapse/storage/schema/main/delta/30/presence_stream.sql +49 -0
  588. synapse/storage/schema/main/delta/30/public_rooms.sql +42 -0
  589. synapse/storage/schema/main/delta/30/push_rule_stream.sql +57 -0
  590. synapse/storage/schema/main/delta/30/threepid_guest_access_tokens.sql +43 -0
  591. synapse/storage/schema/main/delta/31/invites.sql +61 -0
  592. synapse/storage/schema/main/delta/31/local_media_repository_url_cache.sql +46 -0
  593. synapse/storage/schema/main/delta/31/pushers_0.py +92 -0
  594. synapse/storage/schema/main/delta/31/pushers_index.sql +41 -0
  595. synapse/storage/schema/main/delta/31/search_update.py +65 -0
  596. synapse/storage/schema/main/delta/32/events.sql +35 -0
  597. synapse/storage/schema/main/delta/32/openid.sql +9 -0
  598. synapse/storage/schema/main/delta/32/pusher_throttle.sql +42 -0
  599. synapse/storage/schema/main/delta/32/remove_indices.sql +52 -0
  600. synapse/storage/schema/main/delta/32/reports.sql +44 -0
  601. synapse/storage/schema/main/delta/33/access_tokens_device_index.sql +36 -0
  602. synapse/storage/schema/main/delta/33/devices.sql +40 -0
  603. synapse/storage/schema/main/delta/33/devices_for_e2e_keys.sql +38 -0
  604. synapse/storage/schema/main/delta/33/devices_for_e2e_keys_clear_unknown_device.sql +39 -0
  605. synapse/storage/schema/main/delta/33/event_fields.py +61 -0
  606. synapse/storage/schema/main/delta/33/remote_media_ts.py +43 -0
  607. synapse/storage/schema/main/delta/33/user_ips_index.sql +36 -0
  608. synapse/storage/schema/main/delta/34/appservice_stream.sql +42 -0
  609. synapse/storage/schema/main/delta/34/cache_stream.py +50 -0
  610. synapse/storage/schema/main/delta/34/device_inbox.sql +43 -0
  611. synapse/storage/schema/main/delta/34/push_display_name_rename.sql +39 -0
  612. synapse/storage/schema/main/delta/34/received_txn_purge.py +36 -0
  613. synapse/storage/schema/main/delta/35/contains_url.sql +36 -0
  614. synapse/storage/schema/main/delta/35/device_outbox.sql +58 -0
  615. synapse/storage/schema/main/delta/35/device_stream_id.sql +40 -0
  616. synapse/storage/schema/main/delta/35/event_push_actions_index.sql +36 -0
  617. synapse/storage/schema/main/delta/35/public_room_list_change_stream.sql +52 -0
  618. synapse/storage/schema/main/delta/35/stream_order_to_extrem.sql +56 -0
  619. synapse/storage/schema/main/delta/36/readd_public_rooms.sql +45 -0
  620. synapse/storage/schema/main/delta/37/remove_auth_idx.py +89 -0
  621. synapse/storage/schema/main/delta/37/user_threepids.sql +71 -0
  622. synapse/storage/schema/main/delta/38/postgres_fts_gist.sql +38 -0
  623. synapse/storage/schema/main/delta/39/appservice_room_list.sql +48 -0
  624. synapse/storage/schema/main/delta/39/device_federation_stream_idx.sql +35 -0
  625. synapse/storage/schema/main/delta/39/event_push_index.sql +36 -0
  626. synapse/storage/schema/main/delta/39/federation_out_position.sql +41 -0
  627. synapse/storage/schema/main/delta/39/membership_profile.sql +39 -0
  628. synapse/storage/schema/main/delta/40/current_state_idx.sql +36 -0
  629. synapse/storage/schema/main/delta/40/device_inbox.sql +40 -0
  630. synapse/storage/schema/main/delta/40/device_list_streams.sql +79 -0
  631. synapse/storage/schema/main/delta/40/event_push_summary.sql +57 -0
  632. synapse/storage/schema/main/delta/40/pushers.sql +58 -0
  633. synapse/storage/schema/main/delta/41/device_list_stream_idx.sql +36 -0
  634. synapse/storage/schema/main/delta/41/device_outbound_index.sql +35 -0
  635. synapse/storage/schema/main/delta/41/event_search_event_id_idx.sql +36 -0
  636. synapse/storage/schema/main/delta/41/ratelimit.sql +41 -0
  637. synapse/storage/schema/main/delta/42/current_state_delta.sql +48 -0
  638. synapse/storage/schema/main/delta/42/device_list_last_id.sql +52 -0
  639. synapse/storage/schema/main/delta/42/event_auth_state_only.sql +36 -0
  640. synapse/storage/schema/main/delta/42/user_dir.py +88 -0
  641. synapse/storage/schema/main/delta/43/blocked_rooms.sql +40 -0
  642. synapse/storage/schema/main/delta/43/quarantine_media.sql +36 -0
  643. synapse/storage/schema/main/delta/43/url_cache.sql +35 -0
  644. synapse/storage/schema/main/delta/43/user_share.sql +52 -0
  645. synapse/storage/schema/main/delta/44/expire_url_cache.sql +60 -0
  646. synapse/storage/schema/main/delta/45/group_server.sql +186 -0
  647. synapse/storage/schema/main/delta/45/profile_cache.sql +47 -0
  648. synapse/storage/schema/main/delta/46/drop_refresh_tokens.sql +36 -0
  649. synapse/storage/schema/main/delta/46/drop_unique_deleted_pushers.sql +54 -0
  650. synapse/storage/schema/main/delta/46/group_server.sql +51 -0
  651. synapse/storage/schema/main/delta/46/local_media_repository_url_idx.sql +43 -0
  652. synapse/storage/schema/main/delta/46/user_dir_null_room_ids.sql +54 -0
  653. synapse/storage/schema/main/delta/46/user_dir_typos.sql +43 -0
  654. synapse/storage/schema/main/delta/47/last_access_media.sql +35 -0
  655. synapse/storage/schema/main/delta/47/postgres_fts_gin.sql +36 -0
  656. synapse/storage/schema/main/delta/47/push_actions_staging.sql +47 -0
  657. synapse/storage/schema/main/delta/48/add_user_consent.sql +37 -0
  658. synapse/storage/schema/main/delta/48/add_user_ips_last_seen_index.sql +36 -0
  659. synapse/storage/schema/main/delta/48/deactivated_users.sql +44 -0
  660. synapse/storage/schema/main/delta/48/group_unique_indexes.py +67 -0
  661. synapse/storage/schema/main/delta/48/groups_joinable.sql +41 -0
  662. synapse/storage/schema/main/delta/49/add_user_consent_server_notice_sent.sql +39 -0
  663. synapse/storage/schema/main/delta/49/add_user_daily_visits.sql +40 -0
  664. synapse/storage/schema/main/delta/49/add_user_ips_last_seen_only_index.sql +36 -0
  665. synapse/storage/schema/main/delta/50/add_creation_ts_users_index.sql +38 -0
  666. synapse/storage/schema/main/delta/50/erasure_store.sql +40 -0
  667. synapse/storage/schema/main/delta/50/make_event_content_nullable.py +102 -0
  668. synapse/storage/schema/main/delta/51/e2e_room_keys.sql +58 -0
  669. synapse/storage/schema/main/delta/51/monthly_active_users.sql +46 -0
  670. synapse/storage/schema/main/delta/52/add_event_to_state_group_index.sql +38 -0
  671. synapse/storage/schema/main/delta/52/device_list_streams_unique_idx.sql +55 -0
  672. synapse/storage/schema/main/delta/52/e2e_room_keys.sql +72 -0
  673. synapse/storage/schema/main/delta/53/add_user_type_to_users.sql +38 -0
  674. synapse/storage/schema/main/delta/53/drop_sent_transactions.sql +35 -0
  675. synapse/storage/schema/main/delta/53/event_format_version.sql +35 -0
  676. synapse/storage/schema/main/delta/53/user_dir_populate.sql +49 -0
  677. synapse/storage/schema/main/delta/53/user_ips_index.sql +49 -0
  678. synapse/storage/schema/main/delta/53/user_share.sql +63 -0
  679. synapse/storage/schema/main/delta/53/user_threepid_id.sql +48 -0
  680. synapse/storage/schema/main/delta/53/users_in_public_rooms.sql +47 -0
  681. synapse/storage/schema/main/delta/54/account_validity_with_renewal.sql +49 -0
  682. synapse/storage/schema/main/delta/54/add_validity_to_server_keys.sql +42 -0
  683. synapse/storage/schema/main/delta/54/delete_forward_extremities.sql +42 -0
  684. synapse/storage/schema/main/delta/54/drop_legacy_tables.sql +49 -0
  685. synapse/storage/schema/main/delta/54/drop_presence_list.sql +35 -0
  686. synapse/storage/schema/main/delta/54/relations.sql +46 -0
  687. synapse/storage/schema/main/delta/54/stats.sql +99 -0
  688. synapse/storage/schema/main/delta/54/stats2.sql +47 -0
  689. synapse/storage/schema/main/delta/55/access_token_expiry.sql +37 -0
  690. synapse/storage/schema/main/delta/55/track_threepid_validations.sql +50 -0
  691. synapse/storage/schema/main/delta/55/users_alter_deactivated.sql +38 -0
  692. synapse/storage/schema/main/delta/56/add_spans_to_device_lists.sql +39 -0
  693. synapse/storage/schema/main/delta/56/current_state_events_membership.sql +41 -0
  694. synapse/storage/schema/main/delta/56/current_state_events_membership_mk2.sql +43 -0
  695. synapse/storage/schema/main/delta/56/delete_keys_from_deleted_backups.sql +44 -0
  696. synapse/storage/schema/main/delta/56/destinations_failure_ts.sql +44 -0
  697. synapse/storage/schema/main/delta/56/destinations_retry_interval_type.sql.postgres +18 -0
  698. synapse/storage/schema/main/delta/56/device_stream_id_insert.sql +39 -0
  699. synapse/storage/schema/main/delta/56/devices_last_seen.sql +43 -0
  700. synapse/storage/schema/main/delta/56/drop_unused_event_tables.sql +39 -0
  701. synapse/storage/schema/main/delta/56/event_expiry.sql +40 -0
  702. synapse/storage/schema/main/delta/56/event_labels.sql +49 -0
  703. synapse/storage/schema/main/delta/56/event_labels_background_update.sql +36 -0
  704. synapse/storage/schema/main/delta/56/fix_room_keys_index.sql +37 -0
  705. synapse/storage/schema/main/delta/56/hidden_devices.sql +37 -0
  706. synapse/storage/schema/main/delta/56/hidden_devices_fix.sql.sqlite +42 -0
  707. synapse/storage/schema/main/delta/56/nuke_empty_communities_from_db.sql +48 -0
  708. synapse/storage/schema/main/delta/56/public_room_list_idx.sql +35 -0
  709. synapse/storage/schema/main/delta/56/redaction_censor.sql +35 -0
  710. synapse/storage/schema/main/delta/56/redaction_censor2.sql +41 -0
  711. synapse/storage/schema/main/delta/56/redaction_censor3_fix_update.sql.postgres +25 -0
  712. synapse/storage/schema/main/delta/56/redaction_censor4.sql +35 -0
  713. synapse/storage/schema/main/delta/56/remove_tombstoned_rooms_from_directory.sql +38 -0
  714. synapse/storage/schema/main/delta/56/room_key_etag.sql +36 -0
  715. synapse/storage/schema/main/delta/56/room_membership_idx.sql +37 -0
  716. synapse/storage/schema/main/delta/56/room_retention.sql +52 -0
  717. synapse/storage/schema/main/delta/56/signing_keys.sql +75 -0
  718. synapse/storage/schema/main/delta/56/signing_keys_nonunique_signatures.sql +41 -0
  719. synapse/storage/schema/main/delta/56/stats_separated.sql +175 -0
  720. synapse/storage/schema/main/delta/56/unique_user_filter_index.py +46 -0
  721. synapse/storage/schema/main/delta/56/user_external_ids.sql +43 -0
  722. synapse/storage/schema/main/delta/56/users_in_public_rooms_idx.sql +36 -0
  723. synapse/storage/schema/main/delta/57/delete_old_current_state_events.sql +41 -0
  724. synapse/storage/schema/main/delta/57/device_list_remote_cache_stale.sql +44 -0
  725. synapse/storage/schema/main/delta/57/local_current_membership.py +111 -0
  726. synapse/storage/schema/main/delta/57/remove_sent_outbound_pokes.sql +40 -0
  727. synapse/storage/schema/main/delta/57/rooms_version_column.sql +43 -0
  728. synapse/storage/schema/main/delta/57/rooms_version_column_2.sql.postgres +35 -0
  729. synapse/storage/schema/main/delta/57/rooms_version_column_2.sql.sqlite +22 -0
  730. synapse/storage/schema/main/delta/57/rooms_version_column_3.sql.postgres +39 -0
  731. synapse/storage/schema/main/delta/57/rooms_version_column_3.sql.sqlite +23 -0
  732. synapse/storage/schema/main/delta/58/02remove_dup_outbound_pokes.sql +41 -0
  733. synapse/storage/schema/main/delta/58/03persist_ui_auth.sql +55 -0
  734. synapse/storage/schema/main/delta/58/05cache_instance.sql.postgres +30 -0
  735. synapse/storage/schema/main/delta/58/06dlols_unique_idx.py +83 -0
  736. synapse/storage/schema/main/delta/58/07add_method_to_thumbnail_constraint.sql.postgres +33 -0
  737. synapse/storage/schema/main/delta/58/07add_method_to_thumbnail_constraint.sql.sqlite +44 -0
  738. synapse/storage/schema/main/delta/58/07persist_ui_auth_ips.sql +44 -0
  739. synapse/storage/schema/main/delta/58/08_media_safe_from_quarantine.sql.postgres +18 -0
  740. synapse/storage/schema/main/delta/58/08_media_safe_from_quarantine.sql.sqlite +18 -0
  741. synapse/storage/schema/main/delta/58/09shadow_ban.sql +37 -0
  742. synapse/storage/schema/main/delta/58/10_pushrules_enabled_delete_obsolete.sql +47 -0
  743. synapse/storage/schema/main/delta/58/10drop_local_rejections_stream.sql +41 -0
  744. synapse/storage/schema/main/delta/58/10federation_pos_instance_name.sql +41 -0
  745. synapse/storage/schema/main/delta/58/11dehydration.sql +39 -0
  746. synapse/storage/schema/main/delta/58/11fallback.sql +43 -0
  747. synapse/storage/schema/main/delta/58/11user_id_seq.py +38 -0
  748. synapse/storage/schema/main/delta/58/12room_stats.sql +51 -0
  749. synapse/storage/schema/main/delta/58/13remove_presence_allow_inbound.sql +36 -0
  750. synapse/storage/schema/main/delta/58/14events_instance_name.sql +35 -0
  751. synapse/storage/schema/main/delta/58/14events_instance_name.sql.postgres +28 -0
  752. synapse/storage/schema/main/delta/58/15_catchup_destination_rooms.sql +61 -0
  753. synapse/storage/schema/main/delta/58/15unread_count.sql +45 -0
  754. synapse/storage/schema/main/delta/58/16populate_stats_process_rooms_fix.sql +41 -0
  755. synapse/storage/schema/main/delta/58/17_catchup_last_successful.sql +40 -0
  756. synapse/storage/schema/main/delta/58/18stream_positions.sql +41 -0
  757. synapse/storage/schema/main/delta/58/19instance_map.sql.postgres +25 -0
  758. synapse/storage/schema/main/delta/58/19txn_id.sql +59 -0
  759. synapse/storage/schema/main/delta/58/20instance_name_event_tables.sql +36 -0
  760. synapse/storage/schema/main/delta/58/20user_daily_visits.sql +37 -0
  761. synapse/storage/schema/main/delta/58/21as_device_stream.sql +36 -0
  762. synapse/storage/schema/main/delta/58/21drop_device_max_stream_id.sql +1 -0
  763. synapse/storage/schema/main/delta/58/22puppet_token.sql +36 -0
  764. synapse/storage/schema/main/delta/58/22users_have_local_media.sql +2 -0
  765. synapse/storage/schema/main/delta/58/23e2e_cross_signing_keys_idx.sql +36 -0
  766. synapse/storage/schema/main/delta/58/24drop_event_json_index.sql +38 -0
  767. synapse/storage/schema/main/delta/58/25user_external_ids_user_id_idx.sql +36 -0
  768. synapse/storage/schema/main/delta/58/26access_token_last_validated.sql +37 -0
  769. synapse/storage/schema/main/delta/58/27local_invites.sql +37 -0
  770. synapse/storage/schema/main/delta/58/28drop_last_used_column.sql.postgres +16 -0
  771. synapse/storage/schema/main/delta/58/28drop_last_used_column.sql.sqlite +62 -0
  772. synapse/storage/schema/main/delta/59/01ignored_user.py +85 -0
  773. synapse/storage/schema/main/delta/59/02shard_send_to_device.sql +37 -0
  774. synapse/storage/schema/main/delta/59/03shard_send_to_device_sequence.sql.postgres +25 -0
  775. synapse/storage/schema/main/delta/59/04_event_auth_chains.sql +71 -0
  776. synapse/storage/schema/main/delta/59/04_event_auth_chains.sql.postgres +16 -0
  777. synapse/storage/schema/main/delta/59/04drop_account_data.sql +36 -0
  778. synapse/storage/schema/main/delta/59/05cache_invalidation.sql +36 -0
  779. synapse/storage/schema/main/delta/59/06chain_cover_index.sql +36 -0
  780. synapse/storage/schema/main/delta/59/06shard_account_data.sql +39 -0
  781. synapse/storage/schema/main/delta/59/06shard_account_data.sql.postgres +32 -0
  782. synapse/storage/schema/main/delta/59/07shard_account_data_fix.sql +37 -0
  783. synapse/storage/schema/main/delta/59/08delete_pushers_for_deactivated_accounts.sql +39 -0
  784. synapse/storage/schema/main/delta/59/08delete_stale_pushers.sql +39 -0
  785. synapse/storage/schema/main/delta/59/09rejected_events_metadata.sql +45 -0
  786. synapse/storage/schema/main/delta/59/10delete_purged_chain_cover.sql +36 -0
  787. synapse/storage/schema/main/delta/59/11add_knock_members_to_stats.sql +39 -0
  788. synapse/storage/schema/main/delta/59/11drop_thumbnail_constraint.sql.postgres +22 -0
  789. synapse/storage/schema/main/delta/59/12account_validity_token_used_ts_ms.sql +37 -0
  790. synapse/storage/schema/main/delta/59/12presence_stream_instance.sql +37 -0
  791. synapse/storage/schema/main/delta/59/12presence_stream_instance_seq.sql.postgres +20 -0
  792. synapse/storage/schema/main/delta/59/13users_to_send_full_presence_to.sql +53 -0
  793. synapse/storage/schema/main/delta/59/14refresh_tokens.sql +53 -0
  794. synapse/storage/schema/main/delta/59/15locks.sql +56 -0
  795. synapse/storage/schema/main/delta/59/16federation_inbound_staging.sql +51 -0
  796. synapse/storage/schema/main/delta/60/01recreate_stream_ordering.sql.postgres +45 -0
  797. synapse/storage/schema/main/delta/60/02change_stream_ordering_columns.sql.postgres +30 -0
  798. synapse/storage/schema/main/delta/61/01change_appservices_txns.sql.postgres +23 -0
  799. synapse/storage/schema/main/delta/61/01insertion_event_lookups.sql +68 -0
  800. synapse/storage/schema/main/delta/61/02drop_redundant_room_depth_index.sql +37 -0
  801. synapse/storage/schema/main/delta/61/03recreate_min_depth.py +74 -0
  802. synapse/storage/schema/main/delta/62/01insertion_event_extremities.sql +43 -0
  803. synapse/storage/schema/main/delta/63/01create_registration_tokens.sql +42 -0
  804. synapse/storage/schema/main/delta/63/02delete_unlinked_email_pushers.sql +39 -0
  805. synapse/storage/schema/main/delta/63/02populate-rooms-creator.sql +36 -0
  806. synapse/storage/schema/main/delta/63/03session_store.sql +42 -0
  807. synapse/storage/schema/main/delta/63/04add_presence_stream_not_offline_index.sql +37 -0
  808. synapse/storage/schema/main/delta/64/01msc2716_chunk_to_batch_rename.sql.postgres +23 -0
  809. synapse/storage/schema/main/delta/64/01msc2716_chunk_to_batch_rename.sql.sqlite +37 -0
  810. synapse/storage/schema/main/delta/65/01msc2716_insertion_event_edges.sql +38 -0
  811. synapse/storage/schema/main/delta/65/03remove_hidden_devices_from_device_inbox.sql +41 -0
  812. synapse/storage/schema/main/delta/65/04_local_group_updates.sql +37 -0
  813. synapse/storage/schema/main/delta/65/05_remove_room_stats_historical_and_user_stats_historical.sql +38 -0
  814. synapse/storage/schema/main/delta/65/06remove_deleted_devices_from_device_inbox.sql +53 -0
  815. synapse/storage/schema/main/delta/65/07_arbitrary_relations.sql +37 -0
  816. synapse/storage/schema/main/delta/65/08_device_inbox_background_updates.sql +37 -0
  817. synapse/storage/schema/main/delta/65/10_expirable_refresh_tokens.sql +47 -0
  818. synapse/storage/schema/main/delta/65/11_devices_auth_provider_session.sql +46 -0
  819. synapse/storage/schema/main/delta/67/01drop_public_room_list_stream.sql +37 -0
  820. synapse/storage/schema/main/delta/68/01event_columns.sql +45 -0
  821. synapse/storage/schema/main/delta/68/02_msc2409_add_device_id_appservice_stream_type.sql +40 -0
  822. synapse/storage/schema/main/delta/68/03_delete_account_data_for_deactivated_accounts.sql +39 -0
  823. synapse/storage/schema/main/delta/68/04_refresh_tokens_index_next_token_id.sql +47 -0
  824. synapse/storage/schema/main/delta/68/04partial_state_rooms.sql +60 -0
  825. synapse/storage/schema/main/delta/68/05_delete_non_strings_from_event_search.sql.sqlite +22 -0
  826. synapse/storage/schema/main/delta/68/05partial_state_rooms_triggers.py +80 -0
  827. synapse/storage/schema/main/delta/68/06_msc3202_add_device_list_appservice_stream_type.sql +42 -0
  828. synapse/storage/schema/main/delta/69/01as_txn_seq.py +54 -0
  829. synapse/storage/schema/main/delta/69/01device_list_oubound_by_room.sql +57 -0
  830. synapse/storage/schema/main/delta/69/02cache_invalidation_index.sql +37 -0
  831. synapse/storage/schema/main/delta/70/01clean_table_purged_rooms.sql +39 -0
  832. synapse/storage/schema/main/delta/71/01rebuild_event_edges.sql.postgres +43 -0
  833. synapse/storage/schema/main/delta/71/01rebuild_event_edges.sql.sqlite +47 -0
  834. synapse/storage/schema/main/delta/71/01remove_noop_background_updates.sql +80 -0
  835. synapse/storage/schema/main/delta/71/02event_push_summary_unique.sql +37 -0
  836. synapse/storage/schema/main/delta/72/01add_room_type_to_state_stats.sql +38 -0
  837. synapse/storage/schema/main/delta/72/01event_push_summary_receipt.sql +54 -0
  838. synapse/storage/schema/main/delta/72/02event_push_actions_index.sql +38 -0
  839. synapse/storage/schema/main/delta/72/03bg_populate_events_columns.py +57 -0
  840. synapse/storage/schema/main/delta/72/03drop_event_reference_hashes.sql +36 -0
  841. synapse/storage/schema/main/delta/72/03remove_groups.sql +50 -0
  842. synapse/storage/schema/main/delta/72/04drop_column_application_services_state_last_txn.sql.postgres +17 -0
  843. synapse/storage/schema/main/delta/72/04drop_column_application_services_state_last_txn.sql.sqlite +40 -0
  844. synapse/storage/schema/main/delta/72/05receipts_event_stream_ordering.sql +38 -0
  845. synapse/storage/schema/main/delta/72/05remove_unstable_private_read_receipts.sql +38 -0
  846. synapse/storage/schema/main/delta/72/06add_consent_ts_to_users.sql +35 -0
  847. synapse/storage/schema/main/delta/72/06thread_notifications.sql +49 -0
  848. synapse/storage/schema/main/delta/72/07force_update_current_state_events_membership.py +67 -0
  849. synapse/storage/schema/main/delta/72/07thread_receipts.sql.postgres +30 -0
  850. synapse/storage/schema/main/delta/72/07thread_receipts.sql.sqlite +70 -0
  851. synapse/storage/schema/main/delta/72/08begin_cache_invalidation_seq_at_2.sql.postgres +23 -0
  852. synapse/storage/schema/main/delta/72/08thread_receipts.sql +39 -0
  853. synapse/storage/schema/main/delta/72/09partial_indices.sql.sqlite +56 -0
  854. synapse/storage/schema/main/delta/73/01event_failed_pull_attempts.sql +48 -0
  855. synapse/storage/schema/main/delta/73/02add_pusher_enabled.sql +35 -0
  856. synapse/storage/schema/main/delta/73/02room_id_indexes_for_purging.sql +41 -0
  857. synapse/storage/schema/main/delta/73/03pusher_device_id.sql +39 -0
  858. synapse/storage/schema/main/delta/73/03users_approved_column.sql +39 -0
  859. synapse/storage/schema/main/delta/73/04partial_join_details.sql +42 -0
  860. synapse/storage/schema/main/delta/73/04pending_device_list_updates.sql +47 -0
  861. synapse/storage/schema/main/delta/73/05old_push_actions.sql.postgres +22 -0
  862. synapse/storage/schema/main/delta/73/05old_push_actions.sql.sqlite +24 -0
  863. synapse/storage/schema/main/delta/73/06thread_notifications_thread_id_idx.sql +42 -0
  864. synapse/storage/schema/main/delta/73/08thread_receipts_non_null.sql.postgres +23 -0
  865. synapse/storage/schema/main/delta/73/08thread_receipts_non_null.sql.sqlite +76 -0
  866. synapse/storage/schema/main/delta/73/09partial_joined_via_destination.sql +37 -0
  867. synapse/storage/schema/main/delta/73/09threads_table.sql +49 -0
  868. synapse/storage/schema/main/delta/73/10_update_sqlite_fts4_tokenizer.py +71 -0
  869. synapse/storage/schema/main/delta/73/10login_tokens.sql +54 -0
  870. synapse/storage/schema/main/delta/73/11event_search_room_id_n_distinct.sql.postgres +33 -0
  871. synapse/storage/schema/main/delta/73/12refactor_device_list_outbound_pokes.sql +72 -0
  872. synapse/storage/schema/main/delta/73/13add_device_lists_index.sql +39 -0
  873. synapse/storage/schema/main/delta/73/20_un_partial_stated_room_stream.sql +51 -0
  874. synapse/storage/schema/main/delta/73/21_un_partial_stated_room_stream_seq.sql.postgres +20 -0
  875. synapse/storage/schema/main/delta/73/22_rebuild_user_dir_stats.sql +48 -0
  876. synapse/storage/schema/main/delta/73/22_un_partial_stated_event_stream.sql +53 -0
  877. synapse/storage/schema/main/delta/73/23_fix_thread_index.sql +52 -0
  878. synapse/storage/schema/main/delta/73/23_un_partial_stated_room_stream_seq.sql.postgres +20 -0
  879. synapse/storage/schema/main/delta/73/24_events_jump_to_date_index.sql +36 -0
  880. synapse/storage/schema/main/delta/73/25drop_presence.sql +36 -0
  881. synapse/storage/schema/main/delta/74/01_user_directory_stale_remote_users.sql +58 -0
  882. synapse/storage/schema/main/delta/74/02_set_device_id_for_pushers_bg_update.sql +38 -0
  883. synapse/storage/schema/main/delta/74/03_membership_tables_event_stream_ordering.sql.postgres +29 -0
  884. synapse/storage/schema/main/delta/74/03_membership_tables_event_stream_ordering.sql.sqlite +23 -0
  885. synapse/storage/schema/main/delta/74/03_room_membership_index.sql +38 -0
  886. synapse/storage/schema/main/delta/74/04_delete_e2e_backup_keys_for_deactivated_users.sql +36 -0
  887. synapse/storage/schema/main/delta/74/04_membership_tables_event_stream_ordering_triggers.py +87 -0
  888. synapse/storage/schema/main/delta/74/05_events_txn_id_device_id.sql +72 -0
  889. synapse/storage/schema/main/delta/74/90COMMENTS_destinations.sql.postgres +52 -0
  890. synapse/storage/schema/main/delta/76/01_add_profiles_full_user_id_column.sql +39 -0
  891. synapse/storage/schema/main/delta/76/02_add_user_filters_full_user_id_column.sql +39 -0
  892. synapse/storage/schema/main/delta/76/03_per_user_experimental_features.sql +46 -0
  893. synapse/storage/schema/main/delta/76/04_add_room_forgetter.sql +43 -0
  894. synapse/storage/schema/main/delta/77/01_add_profiles_not_valid_check.sql.postgres +16 -0
  895. synapse/storage/schema/main/delta/77/02_add_user_filters_not_valid_check.sql.postgres +16 -0
  896. synapse/storage/schema/main/delta/77/03bg_populate_full_user_id_profiles.sql +35 -0
  897. synapse/storage/schema/main/delta/77/04bg_populate_full_user_id_user_filters.sql +35 -0
  898. synapse/storage/schema/main/delta/77/05thread_notifications_backfill.sql +67 -0
  899. synapse/storage/schema/main/delta/77/06thread_notifications_not_null.sql.sqlite +102 -0
  900. synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_actions.sql.postgres +27 -0
  901. synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_actions_staging.sql.postgres +27 -0
  902. synapse/storage/schema/main/delta/77/06thread_notifications_not_null_event_push_summary.sql.postgres +29 -0
  903. synapse/storage/schema/main/delta/77/14bg_indices_event_stream_ordering.sql +39 -0
  904. synapse/storage/schema/main/delta/78/01_validate_and_update_profiles.py +99 -0
  905. synapse/storage/schema/main/delta/78/02_validate_and_update_user_filters.py +100 -0
  906. synapse/storage/schema/main/delta/78/03_remove_unused_indexes_user_filters.py +72 -0
  907. synapse/storage/schema/main/delta/78/03event_extremities_constraints.py +65 -0
  908. synapse/storage/schema/main/delta/78/04_add_full_user_id_index_user_filters.py +32 -0
  909. synapse/storage/schema/main/delta/79/03_read_write_locks_triggers.sql.postgres +102 -0
  910. synapse/storage/schema/main/delta/79/03_read_write_locks_triggers.sql.sqlite +72 -0
  911. synapse/storage/schema/main/delta/79/04_mitigate_stream_ordering_update_race.py +70 -0
  912. synapse/storage/schema/main/delta/79/05_read_write_locks_triggers.sql.postgres +69 -0
  913. synapse/storage/schema/main/delta/79/05_read_write_locks_triggers.sql.sqlite +65 -0
  914. synapse/storage/schema/main/delta/80/01_users_alter_locked.sql +35 -0
  915. synapse/storage/schema/main/delta/80/02_read_write_locks_unlogged.sql.postgres +30 -0
  916. synapse/storage/schema/main/delta/80/02_scheduled_tasks.sql +47 -0
  917. synapse/storage/schema/main/delta/80/03_read_write_locks_triggers.sql.postgres +37 -0
  918. synapse/storage/schema/main/delta/80/04_read_write_locks_deadlock.sql.postgres +71 -0
  919. synapse/storage/schema/main/delta/82/02_scheduled_tasks_index.sql +35 -0
  920. synapse/storage/schema/main/delta/82/04_add_indices_for_purging_rooms.sql +39 -0
  921. synapse/storage/schema/main/delta/82/05gaps.sql +44 -0
  922. synapse/storage/schema/main/delta/83/01_drop_old_tables.sql +43 -0
  923. synapse/storage/schema/main/delta/83/03_instance_name_receipts.sql.sqlite +17 -0
  924. synapse/storage/schema/main/delta/83/05_cross_signing_key_update_grant.sql +34 -0
  925. synapse/storage/schema/main/delta/83/06_event_push_summary_room.sql +36 -0
  926. synapse/storage/schema/main/delta/84/01_auth_links_stats.sql.postgres +20 -0
  927. synapse/storage/schema/main/delta/84/02_auth_links_index.sql +16 -0
  928. synapse/storage/schema/main/delta/84/03_auth_links_analyze.sql.postgres +16 -0
  929. synapse/storage/schema/main/delta/84/04_access_token_index.sql +15 -0
  930. synapse/storage/schema/main/delta/85/01_add_suspended.sql +14 -0
  931. synapse/storage/schema/main/delta/85/02_add_instance_names.sql +27 -0
  932. synapse/storage/schema/main/delta/85/03_new_sequences.sql.postgres +54 -0
  933. synapse/storage/schema/main/delta/85/04_cleanup_device_federation_outbox.sql +15 -0
  934. synapse/storage/schema/main/delta/85/05_add_instance_names_converted_pos.sql +16 -0
  935. synapse/storage/schema/main/delta/85/06_add_room_reports.sql +20 -0
  936. synapse/storage/schema/main/delta/86/01_authenticate_media.sql +15 -0
  937. synapse/storage/schema/main/delta/86/02_receipts_event_id_index.sql +15 -0
  938. synapse/storage/schema/main/delta/87/01_sliding_sync_memberships.sql +169 -0
  939. synapse/storage/schema/main/delta/87/02_per_connection_state.sql +81 -0
  940. synapse/storage/schema/main/delta/87/03_current_state_index.sql +19 -0
  941. synapse/storage/schema/main/delta/88/01_add_delayed_events.sql +43 -0
  942. synapse/storage/schema/main/delta/88/01_custom_profile_fields.sql +15 -0
  943. synapse/storage/schema/main/delta/88/02_fix_sliding_sync_membership_snapshots_forgotten_column.sql +21 -0
  944. synapse/storage/schema/main/delta/88/03_add_otk_ts_added_index.sql +18 -0
  945. synapse/storage/schema/main/delta/88/04_current_state_delta_index.sql +18 -0
  946. synapse/storage/schema/main/delta/88/05_drop_old_otks.sql.postgres +19 -0
  947. synapse/storage/schema/main/delta/88/05_drop_old_otks.sql.sqlite +19 -0
  948. synapse/storage/schema/main/delta/88/05_sliding_sync_room_config_index.sql +20 -0
  949. synapse/storage/schema/main/delta/88/06_events_received_ts_index.sql +17 -0
  950. synapse/storage/schema/main/delta/89/01_sliding_sync_membership_snapshot_index.sql +15 -0
  951. synapse/storage/schema/main/delta/90/01_add_column_participant_room_memberships_table.sql +16 -0
  952. synapse/storage/schema/main/delta/91/01_media_hash.sql +28 -0
  953. synapse/storage/schema/main/delta/92/01_remove_trigger.sql.postgres +16 -0
  954. synapse/storage/schema/main/delta/92/01_remove_trigger.sql.sqlite +16 -0
  955. synapse/storage/schema/main/delta/92/02_remove_populate_participant_bg_update.sql +17 -0
  956. synapse/storage/schema/main/delta/92/04_ss_membership_snapshot_idx.sql +16 -0
  957. synapse/storage/schema/main/delta/92/04_thread_subscriptions.sql +59 -0
  958. synapse/storage/schema/main/delta/92/04_thread_subscriptions_seq.sql.postgres +19 -0
  959. synapse/storage/schema/main/delta/92/05_fixup_max_depth_cap.sql +17 -0
  960. synapse/storage/schema/main/delta/92/05_thread_subscriptions_comments.sql.postgres +18 -0
  961. synapse/storage/schema/main/delta/92/06_device_federation_inbox_index.sql +16 -0
  962. synapse/storage/schema/main/delta/92/06_threads_last_sent_stream_ordering_comments.sql.postgres +24 -0
  963. synapse/storage/schema/main/delta/92/07_add_user_reports.sql +22 -0
  964. synapse/storage/schema/main/delta/92/07_event_txn_id_device_id_txn_id2.sql +15 -0
  965. synapse/storage/schema/main/delta/92/08_room_ban_redactions.sql +21 -0
  966. synapse/storage/schema/main/delta/92/08_thread_subscriptions_seq_fixup.sql.postgres +19 -0
  967. synapse/storage/schema/main/delta/92/09_thread_subscriptions_update.sql +20 -0
  968. synapse/storage/schema/main/delta/92/09_thread_subscriptions_update.sql.postgres +18 -0
  969. synapse/storage/schema/main/full_schemas/72/full.sql.postgres +1344 -0
  970. synapse/storage/schema/main/full_schemas/72/full.sql.sqlite +646 -0
  971. synapse/storage/schema/state/delta/23/drop_state_index.sql +35 -0
  972. synapse/storage/schema/state/delta/32/remove_state_indices.sql +38 -0
  973. synapse/storage/schema/state/delta/35/add_state_index.sql +36 -0
  974. synapse/storage/schema/state/delta/35/state.sql +41 -0
  975. synapse/storage/schema/state/delta/35/state_dedupe.sql +36 -0
  976. synapse/storage/schema/state/delta/47/state_group_seq.py +38 -0
  977. synapse/storage/schema/state/delta/56/state_group_room_idx.sql +36 -0
  978. synapse/storage/schema/state/delta/61/02state_groups_state_n_distinct.sql.postgres +34 -0
  979. synapse/storage/schema/state/delta/70/08_state_group_edges_unique.sql +36 -0
  980. synapse/storage/schema/state/delta/89/01_state_groups_deletion.sql +39 -0
  981. synapse/storage/schema/state/delta/90/02_delete_unreferenced_state_groups.sql +16 -0
  982. synapse/storage/schema/state/delta/90/03_remove_old_deletion_bg_update.sql +15 -0
  983. synapse/storage/schema/state/full_schemas/72/full.sql.postgres +30 -0
  984. synapse/storage/schema/state/full_schemas/72/full.sql.sqlite +20 -0
  985. synapse/storage/types.py +185 -0
  986. synapse/storage/util/__init__.py +20 -0
  987. synapse/storage/util/id_generators.py +909 -0
  988. synapse/storage/util/partial_state_events_tracker.py +194 -0
  989. synapse/storage/util/sequence.py +315 -0
  990. synapse/streams/__init__.py +43 -0
  991. synapse/streams/config.py +92 -0
  992. synapse/streams/events.py +203 -0
  993. synapse/synapse_rust/__init__.pyi +3 -0
  994. synapse/synapse_rust/acl.pyi +20 -0
  995. synapse/synapse_rust/events.pyi +136 -0
  996. synapse/synapse_rust/http_client.pyi +32 -0
  997. synapse/synapse_rust/push.pyi +86 -0
  998. synapse/synapse_rust/rendezvous.pyi +30 -0
  999. synapse/synapse_rust/segmenter.pyi +1 -0
  1000. synapse/synapse_rust.abi3.so +0 -0
  1001. synapse/types/__init__.py +1600 -0
  1002. synapse/types/handlers/__init__.py +93 -0
  1003. synapse/types/handlers/policy_server.py +16 -0
  1004. synapse/types/handlers/sliding_sync.py +909 -0
  1005. synapse/types/rest/__init__.py +25 -0
  1006. synapse/types/rest/client/__init__.py +415 -0
  1007. synapse/types/state.py +635 -0
  1008. synapse/types/storage/__init__.py +66 -0
  1009. synapse/util/__init__.py +170 -0
  1010. synapse/util/async_helpers.py +1067 -0
  1011. synapse/util/batching_queue.py +202 -0
  1012. synapse/util/caches/__init__.py +300 -0
  1013. synapse/util/caches/cached_call.py +143 -0
  1014. synapse/util/caches/deferred_cache.py +530 -0
  1015. synapse/util/caches/descriptors.py +694 -0
  1016. synapse/util/caches/dictionary_cache.py +350 -0
  1017. synapse/util/caches/expiringcache.py +251 -0
  1018. synapse/util/caches/lrucache.py +977 -0
  1019. synapse/util/caches/response_cache.py +323 -0
  1020. synapse/util/caches/stream_change_cache.py +370 -0
  1021. synapse/util/caches/treecache.py +189 -0
  1022. synapse/util/caches/ttlcache.py +197 -0
  1023. synapse/util/cancellation.py +63 -0
  1024. synapse/util/check_dependencies.py +335 -0
  1025. synapse/util/clock.py +500 -0
  1026. synapse/util/constants.py +22 -0
  1027. synapse/util/daemonize.py +165 -0
  1028. synapse/util/distributor.py +159 -0
  1029. synapse/util/events.py +134 -0
  1030. synapse/util/file_consumer.py +164 -0
  1031. synapse/util/frozenutils.py +57 -0
  1032. synapse/util/gai_resolver.py +180 -0
  1033. synapse/util/hash.py +38 -0
  1034. synapse/util/httpresourcetree.py +108 -0
  1035. synapse/util/iterutils.py +189 -0
  1036. synapse/util/json.py +56 -0
  1037. synapse/util/linked_list.py +156 -0
  1038. synapse/util/logcontext.py +46 -0
  1039. synapse/util/logformatter.py +28 -0
  1040. synapse/util/macaroons.py +325 -0
  1041. synapse/util/manhole.py +191 -0
  1042. synapse/util/metrics.py +340 -0
  1043. synapse/util/module_loader.py +116 -0
  1044. synapse/util/msisdn.py +51 -0
  1045. synapse/util/patch_inline_callbacks.py +250 -0
  1046. synapse/util/pydantic_models.py +56 -0
  1047. synapse/util/ratelimitutils.py +420 -0
  1048. synapse/util/retryutils.py +339 -0
  1049. synapse/util/rlimit.py +42 -0
  1050. synapse/util/rust.py +134 -0
  1051. synapse/util/sentinel.py +21 -0
  1052. synapse/util/stringutils.py +293 -0
  1053. synapse/util/task_scheduler.py +493 -0
  1054. synapse/util/templates.py +126 -0
  1055. synapse/util/threepids.py +123 -0
  1056. synapse/util/wheel_timer.py +112 -0
  1057. synapse/visibility.py +836 -0
@@ -0,0 +1,1580 @@
1
+ #
2
+ # This file is licensed under the Affero General Public License (AGPL) version 3.
3
+ #
4
+ # Copyright 2018-2021 The Matrix.org Foundation C.I.C.
5
+ # Copyright 2014-2016 OpenMarket Ltd
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
+ import errno
23
+ import logging
24
+ import os
25
+ import shutil
26
+ from io import BytesIO
27
+ from typing import IO, TYPE_CHECKING, Optional
28
+
29
+ import attr
30
+ from matrix_common.types.mxc_uri import MXCUri
31
+
32
+ import twisted.internet.error
33
+ import twisted.web.http
34
+ from twisted.internet.defer import Deferred
35
+
36
+ from synapse.api.errors import (
37
+ Codes,
38
+ FederationDeniedError,
39
+ HttpResponseException,
40
+ NotFoundError,
41
+ RequestSendFailed,
42
+ SynapseError,
43
+ cs_error,
44
+ )
45
+ from synapse.api.ratelimiting import Ratelimiter
46
+ from synapse.config.repository import ThumbnailRequirement
47
+ from synapse.http.server import respond_with_json
48
+ from synapse.http.site import SynapseRequest
49
+ from synapse.logging.context import defer_to_thread
50
+ from synapse.logging.opentracing import trace
51
+ from synapse.media._base import (
52
+ FileInfo,
53
+ Responder,
54
+ ThumbnailInfo,
55
+ check_for_cached_entry_and_respond,
56
+ get_filename_from_headers,
57
+ respond_404,
58
+ respond_with_multipart_responder,
59
+ respond_with_responder,
60
+ )
61
+ from synapse.media.filepath import MediaFilePaths
62
+ from synapse.media.media_storage import (
63
+ MediaStorage,
64
+ SHA256TransparentIOReader,
65
+ SHA256TransparentIOWriter,
66
+ )
67
+ from synapse.media.storage_provider import StorageProviderWrapper
68
+ from synapse.media.thumbnailer import Thumbnailer, ThumbnailError
69
+ from synapse.media.url_previewer import UrlPreviewer
70
+ from synapse.storage.databases.main.media_repository import LocalMedia, RemoteMedia
71
+ from synapse.types import UserID
72
+ from synapse.util.async_helpers import Linearizer
73
+ from synapse.util.retryutils import NotRetryingDestination
74
+ from synapse.util.stringutils import random_string
75
+
76
+ if TYPE_CHECKING:
77
+ from synapse.server import HomeServer
78
+
79
+ logger = logging.getLogger(__name__)
80
+
81
+ # How often to run the background job to update the "recently accessed"
82
+ # attribute of local and remote media.
83
+ UPDATE_RECENTLY_ACCESSED_TS = 60 * 1000 # 1 minute
84
+ # How often to run the background job to check for local and remote media
85
+ # that should be purged according to the configured media retention settings.
86
+ MEDIA_RETENTION_CHECK_PERIOD_MS = 60 * 60 * 1000 # 1 hour
87
+
88
+
89
+ class MediaRepository:
90
+ def __init__(self, hs: "HomeServer"):
91
+ self.hs = hs
92
+ self.auth = hs.get_auth()
93
+ self.client = hs.get_federation_client()
94
+ self.clock = hs.get_clock()
95
+ self.server_name = hs.hostname
96
+ self.store = hs.get_datastores().main
97
+ self.max_upload_size = hs.config.media.max_upload_size
98
+ self.max_image_pixels = hs.config.media.max_image_pixels
99
+ self.unused_expiration_time = hs.config.media.unused_expiration_time
100
+ self.max_pending_media_uploads = hs.config.media.max_pending_media_uploads
101
+
102
+ Thumbnailer.set_limits(self.max_image_pixels)
103
+
104
+ self.primary_base_path: str = hs.config.media.media_store_path
105
+ self.filepaths: MediaFilePaths = MediaFilePaths(self.primary_base_path)
106
+
107
+ self.dynamic_thumbnails = hs.config.media.dynamic_thumbnails
108
+ self.thumbnail_requirements = hs.config.media.thumbnail_requirements
109
+
110
+ self.remote_media_linearizer = Linearizer(name="media_remote", clock=self.clock)
111
+
112
+ self.recently_accessed_remotes: set[tuple[str, str]] = set()
113
+ self.recently_accessed_locals: set[str] = set()
114
+
115
+ self.federation_domain_whitelist = (
116
+ hs.config.federation.federation_domain_whitelist
117
+ )
118
+ self.prevent_media_downloads_from = hs.config.media.prevent_media_downloads_from
119
+
120
+ self.download_ratelimiter = Ratelimiter(
121
+ store=hs.get_storage_controllers().main,
122
+ clock=hs.get_clock(),
123
+ cfg=hs.config.ratelimiting.remote_media_downloads,
124
+ )
125
+
126
+ # List of StorageProviders where we should search for media and
127
+ # potentially upload to.
128
+ storage_providers = []
129
+
130
+ for (
131
+ clz,
132
+ provider_config,
133
+ wrapper_config,
134
+ ) in hs.config.media.media_storage_providers:
135
+ backend = clz(hs, provider_config)
136
+ provider = StorageProviderWrapper(
137
+ backend,
138
+ store_local=wrapper_config.store_local,
139
+ store_remote=wrapper_config.store_remote,
140
+ store_synchronous=wrapper_config.store_synchronous,
141
+ )
142
+ storage_providers.append(provider)
143
+
144
+ self.media_storage: MediaStorage = MediaStorage(
145
+ self.hs, self.primary_base_path, self.filepaths, storage_providers
146
+ )
147
+
148
+ self.clock.looping_call(
149
+ self._start_update_recently_accessed, UPDATE_RECENTLY_ACCESSED_TS
150
+ )
151
+
152
+ # Media retention configuration options
153
+ self._media_retention_local_media_lifetime_ms = (
154
+ hs.config.media.media_retention_local_media_lifetime_ms
155
+ )
156
+ self._media_retention_remote_media_lifetime_ms = (
157
+ hs.config.media.media_retention_remote_media_lifetime_ms
158
+ )
159
+
160
+ # Check whether local or remote media retention is configured
161
+ if (
162
+ hs.config.media.media_retention_local_media_lifetime_ms is not None
163
+ or hs.config.media.media_retention_remote_media_lifetime_ms is not None
164
+ ):
165
+ # Run the background job to apply media retention rules routinely,
166
+ # with the duration between runs dictated by the homeserver config.
167
+ self.clock.looping_call(
168
+ self._start_apply_media_retention_rules,
169
+ MEDIA_RETENTION_CHECK_PERIOD_MS,
170
+ )
171
+
172
+ if hs.config.media.url_preview_enabled:
173
+ self.url_previewer: Optional[UrlPreviewer] = UrlPreviewer(
174
+ hs, self, self.media_storage
175
+ )
176
+ else:
177
+ self.url_previewer = None
178
+
179
+ # We get the media upload limits and sort them in descending order of
180
+ # time period, so that we can apply some optimizations.
181
+ self.default_media_upload_limits = hs.config.media.media_upload_limits
182
+ self.default_media_upload_limits.sort(
183
+ key=lambda limit: limit.time_period_ms, reverse=True
184
+ )
185
+
186
+ self.media_repository_callbacks = hs.get_module_api_callbacks().media_repository
187
+
188
+ def _start_update_recently_accessed(self) -> Deferred:
189
+ return self.hs.run_as_background_process(
190
+ "update_recently_accessed_media",
191
+ self._update_recently_accessed,
192
+ )
193
+
194
+ def _start_apply_media_retention_rules(self) -> Deferred:
195
+ return self.hs.run_as_background_process(
196
+ "apply_media_retention_rules",
197
+ self._apply_media_retention_rules,
198
+ )
199
+
200
+ async def _update_recently_accessed(self) -> None:
201
+ remote_media = self.recently_accessed_remotes
202
+ self.recently_accessed_remotes = set()
203
+
204
+ local_media = self.recently_accessed_locals
205
+ self.recently_accessed_locals = set()
206
+
207
+ await self.store.update_cached_last_access_time(
208
+ local_media, remote_media, self.clock.time_msec()
209
+ )
210
+
211
+ def mark_recently_accessed(self, server_name: Optional[str], media_id: str) -> None:
212
+ """Mark the given media as recently accessed.
213
+
214
+ Args:
215
+ server_name: Origin server of media, or None if local
216
+ media_id: The media ID of the content
217
+ """
218
+ if server_name:
219
+ self.recently_accessed_remotes.add((server_name, media_id))
220
+ else:
221
+ self.recently_accessed_locals.add(media_id)
222
+
223
+ @trace
224
+ async def create_media_id(self, auth_user: UserID) -> tuple[str, int]:
225
+ """Create and store a media ID for a local user and return the MXC URI and its
226
+ expiration.
227
+
228
+ Args:
229
+ auth_user: The user_id of the uploader
230
+
231
+ Returns:
232
+ A tuple containing the MXC URI of the stored content and the timestamp at
233
+ which the MXC URI expires.
234
+ """
235
+ media_id = random_string(24)
236
+ now = self.clock.time_msec()
237
+ await self.store.store_local_media_id(
238
+ media_id=media_id,
239
+ time_now_ms=now,
240
+ user_id=auth_user,
241
+ )
242
+ return f"mxc://{self.server_name}/{media_id}", now + self.unused_expiration_time
243
+
244
+ @trace
245
+ async def reached_pending_media_limit(self, auth_user: UserID) -> tuple[bool, int]:
246
+ """Check if the user is over the limit for pending media uploads.
247
+
248
+ Args:
249
+ auth_user: The user_id of the uploader
250
+
251
+ Returns:
252
+ A tuple with a boolean and an integer indicating whether the user has too
253
+ many pending media uploads and the timestamp at which the first pending
254
+ media will expire, respectively.
255
+ """
256
+ pending, first_expiration_ts = await self.store.count_pending_media(
257
+ user_id=auth_user
258
+ )
259
+ return pending >= self.max_pending_media_uploads, first_expiration_ts
260
+
261
+ @trace
262
+ async def verify_can_upload(self, media_id: str, auth_user: UserID) -> None:
263
+ """Verify that the media ID can be uploaded to by the given user. This
264
+ function checks that:
265
+
266
+ * the media ID exists
267
+ * the media ID does not already have content
268
+ * the user uploading is the same as the one who created the media ID
269
+ * the media ID has not expired
270
+
271
+ Args:
272
+ media_id: The media ID to verify
273
+ auth_user: The user_id of the uploader
274
+ """
275
+ media = await self.store.get_local_media(media_id)
276
+ if media is None:
277
+ raise NotFoundError("Unknown media ID")
278
+
279
+ if media.user_id != auth_user.to_string():
280
+ raise SynapseError(
281
+ 403,
282
+ "Only the creator of the media ID can upload to it",
283
+ errcode=Codes.FORBIDDEN,
284
+ )
285
+
286
+ if media.media_length is not None:
287
+ raise SynapseError(
288
+ 409,
289
+ "Media ID already has content",
290
+ errcode=Codes.CANNOT_OVERWRITE_MEDIA,
291
+ )
292
+
293
+ expired_time_ms = self.clock.time_msec() - self.unused_expiration_time
294
+ if media.created_ts < expired_time_ms:
295
+ raise NotFoundError("Media ID has expired")
296
+
297
+ @trace
298
+ async def create_or_update_content(
299
+ self,
300
+ media_type: str,
301
+ upload_name: Optional[str],
302
+ content: IO,
303
+ content_length: int,
304
+ auth_user: UserID,
305
+ media_id: Optional[str] = None,
306
+ ) -> MXCUri:
307
+ """Create or update the content of the given media ID.
308
+
309
+ Args:
310
+ media_type: The content type of the file.
311
+ upload_name: The name of the file, if provided.
312
+ content: A file like object that is the content to store
313
+ content_length: The length of the content
314
+ auth_user: The user_id of the uploader
315
+ media_id: The media ID to update if provided, otherwise creates
316
+ new media ID.
317
+
318
+ Returns:
319
+ The mxc url of the stored content
320
+ """
321
+
322
+ is_new_media = media_id is None
323
+ if media_id is None:
324
+ media_id = random_string(24)
325
+
326
+ file_info = FileInfo(server_name=None, file_id=media_id)
327
+ sha256reader = SHA256TransparentIOReader(content)
328
+ # This implements all of IO as it has a passthrough
329
+ fname = await self.media_storage.store_file(sha256reader.wrap(), file_info)
330
+ sha256 = sha256reader.hexdigest()
331
+ should_quarantine = await self.store.get_is_hash_quarantined(sha256)
332
+
333
+ logger.info("Stored local media in file %r", fname)
334
+
335
+ if should_quarantine:
336
+ logger.warning(
337
+ "Media has been automatically quarantined as it matched existing quarantined media"
338
+ )
339
+
340
+ # Check that the user has not exceeded any of the media upload limits.
341
+
342
+ # Use limits from module API if provided
343
+ media_upload_limits = (
344
+ await self.media_repository_callbacks.get_media_upload_limits_for_user(
345
+ auth_user.to_string()
346
+ )
347
+ )
348
+
349
+ # Otherwise use the default limits from config
350
+ if media_upload_limits is None:
351
+ # Note: the media upload limits are sorted so larger time periods are
352
+ # first.
353
+ media_upload_limits = self.default_media_upload_limits
354
+
355
+ # This is the total size of media uploaded by the user in the last
356
+ # `time_period_ms` milliseconds, or None if we haven't checked yet.
357
+ uploaded_media_size: Optional[int] = None
358
+
359
+ for limit in media_upload_limits:
360
+ # We only need to check the amount of media uploaded by the user in
361
+ # this latest (smaller) time period if the amount of media uploaded
362
+ # in a previous (larger) time period is below the limit.
363
+ #
364
+ # This optimization means that in the common case where the user
365
+ # hasn't uploaded much media, we only need to query the database
366
+ # once.
367
+ if (
368
+ uploaded_media_size is None
369
+ or uploaded_media_size + content_length > limit.max_bytes
370
+ ):
371
+ uploaded_media_size = await self.store.get_media_uploaded_size_for_user(
372
+ user_id=auth_user.to_string(), time_period_ms=limit.time_period_ms
373
+ )
374
+
375
+ if uploaded_media_size + content_length > limit.max_bytes:
376
+ await self.media_repository_callbacks.on_media_upload_limit_exceeded(
377
+ user_id=auth_user.to_string(),
378
+ limit=limit,
379
+ sent_bytes=uploaded_media_size,
380
+ attempted_bytes=content_length,
381
+ )
382
+ raise SynapseError(
383
+ 400, "Media upload limit exceeded", Codes.RESOURCE_LIMIT_EXCEEDED
384
+ )
385
+
386
+ if is_new_media:
387
+ await self.store.store_local_media(
388
+ media_id=media_id,
389
+ media_type=media_type,
390
+ time_now_ms=self.clock.time_msec(),
391
+ upload_name=upload_name,
392
+ media_length=content_length,
393
+ user_id=auth_user,
394
+ sha256=sha256,
395
+ quarantined_by="system" if should_quarantine else None,
396
+ )
397
+ else:
398
+ await self.store.update_local_media(
399
+ media_id=media_id,
400
+ media_type=media_type,
401
+ upload_name=upload_name,
402
+ media_length=content_length,
403
+ user_id=auth_user,
404
+ sha256=sha256,
405
+ quarantined_by="system" if should_quarantine else None,
406
+ )
407
+
408
+ try:
409
+ await self._generate_thumbnails(None, media_id, media_id, media_type)
410
+ except Exception as e:
411
+ logger.info("Failed to generate thumbnails: %s", e)
412
+
413
+ return MXCUri(self.server_name, media_id)
414
+
415
+ def respond_not_yet_uploaded(self, request: SynapseRequest) -> None:
416
+ respond_with_json(
417
+ request,
418
+ 504,
419
+ cs_error("Media has not been uploaded yet", code=Codes.NOT_YET_UPLOADED),
420
+ send_cors=True,
421
+ )
422
+
423
+ async def get_cached_remote_media_info(
424
+ self, origin: str, media_id: str
425
+ ) -> Optional[RemoteMedia]:
426
+ """
427
+ Get cached remote media info for a given origin/media ID combo. If the requested
428
+ media is not found locally, it will not be requested over federation and the
429
+ call will return None.
430
+
431
+ Args:
432
+ origin: The origin of the remote media
433
+ media_id: The media ID of the requested content
434
+
435
+ Returns:
436
+ The info for the cached remote media or None if it was not found
437
+ """
438
+ return await self.store.get_cached_remote_media(origin, media_id)
439
+
440
+ async def get_local_media_info(
441
+ self, request: SynapseRequest, media_id: str, max_timeout_ms: int
442
+ ) -> Optional[LocalMedia]:
443
+ """Gets the info dictionary for given local media ID. If the media has
444
+ not been uploaded yet, this function will wait up to ``max_timeout_ms``
445
+ milliseconds for the media to be uploaded.
446
+
447
+ Args:
448
+ request: The incoming request.
449
+ media_id: The media ID of the content. (This is the same as
450
+ the file_id for local content.)
451
+ max_timeout_ms: the maximum number of milliseconds to wait for the
452
+ media to be uploaded.
453
+
454
+ Returns:
455
+ Either the info dictionary for the given local media ID or
456
+ ``None``. If ``None``, then no further processing is necessary as
457
+ this function will send the necessary JSON response.
458
+ """
459
+ wait_until = self.clock.time_msec() + max_timeout_ms
460
+ while True:
461
+ # Get the info for the media
462
+ media_info = await self.store.get_local_media(media_id)
463
+ if not media_info:
464
+ logger.info("Media %s is unknown", media_id)
465
+ respond_404(request)
466
+ return None
467
+
468
+ if media_info.quarantined_by:
469
+ logger.info("Media %s is quarantined", media_id)
470
+ respond_404(request)
471
+ return None
472
+
473
+ # The file has been uploaded, so stop looping
474
+ if media_info.media_length is not None:
475
+ return media_info
476
+
477
+ # Check if the media ID has expired and still hasn't been uploaded to.
478
+ now = self.clock.time_msec()
479
+ expired_time_ms = now - self.unused_expiration_time
480
+ if media_info.created_ts < expired_time_ms:
481
+ logger.info("Media %s has expired without being uploaded", media_id)
482
+ respond_404(request)
483
+ return None
484
+
485
+ if now >= wait_until:
486
+ break
487
+
488
+ await self.clock.sleep(0.5)
489
+
490
+ logger.info("Media %s has not yet been uploaded", media_id)
491
+ self.respond_not_yet_uploaded(request)
492
+ return None
493
+
494
+ async def get_local_media(
495
+ self,
496
+ request: SynapseRequest,
497
+ media_id: str,
498
+ name: Optional[str],
499
+ max_timeout_ms: int,
500
+ allow_authenticated: bool = True,
501
+ federation: bool = False,
502
+ ) -> None:
503
+ """Responds to requests for local media, if exists, or returns 404.
504
+
505
+ Args:
506
+ request: The incoming request.
507
+ media_id: The media ID of the content. (This is the same as
508
+ the file_id for local content.)
509
+ name: Optional name that, if specified, will be used as
510
+ the filename in the Content-Disposition header of the response.
511
+ max_timeout_ms: the maximum number of milliseconds to wait for the
512
+ media to be uploaded.
513
+ allow_authenticated: whether media marked as authenticated may be served to this request
514
+ federation: whether the local media being fetched is for a federation request
515
+
516
+ Returns:
517
+ Resolves once a response has successfully been written to request
518
+ """
519
+ media_info = await self.get_local_media_info(request, media_id, max_timeout_ms)
520
+ if not media_info:
521
+ return
522
+
523
+ if self.hs.config.media.enable_authenticated_media and not allow_authenticated:
524
+ if media_info.authenticated:
525
+ raise NotFoundError()
526
+
527
+ self.mark_recently_accessed(None, media_id)
528
+
529
+ # Once we've checked auth we can return early if the media is cached on
530
+ # the client
531
+ if check_for_cached_entry_and_respond(request):
532
+ return
533
+
534
+ media_type = media_info.media_type
535
+ if not media_type:
536
+ media_type = "application/octet-stream"
537
+ media_length = media_info.media_length
538
+ upload_name = name if name else media_info.upload_name
539
+ url_cache = media_info.url_cache
540
+
541
+ file_info = FileInfo(None, media_id, url_cache=bool(url_cache))
542
+
543
+ responder = await self.media_storage.fetch_media(file_info)
544
+ if federation:
545
+ await respond_with_multipart_responder(
546
+ self.clock, request, responder, media_type, media_length, upload_name
547
+ )
548
+ else:
549
+ await respond_with_responder(
550
+ request, responder, media_type, media_length, upload_name
551
+ )
552
+
553
+ async def get_remote_media(
554
+ self,
555
+ request: SynapseRequest,
556
+ server_name: str,
557
+ media_id: str,
558
+ name: Optional[str],
559
+ max_timeout_ms: int,
560
+ ip_address: str,
561
+ use_federation_endpoint: bool,
562
+ allow_authenticated: bool = True,
563
+ ) -> None:
564
+ """Respond to requests for remote media.
565
+
566
+ Args:
567
+ request: The incoming request.
568
+ server_name: Remote server_name where the media originated.
569
+ media_id: The media ID of the content (as defined by the remote server).
570
+ name: Optional name that, if specified, will be used as
571
+ the filename in the Content-Disposition header of the response.
572
+ max_timeout_ms: the maximum number of milliseconds to wait for the
573
+ media to be uploaded.
574
+ ip_address: the IP address of the requester
575
+ use_federation_endpoint: whether to request the remote media over the new
576
+ federation `/download` endpoint
577
+ allow_authenticated: whether media marked as authenticated may be served to this
578
+ request
579
+
580
+ Returns:
581
+ Resolves once a response has successfully been written to request
582
+ """
583
+ if (
584
+ self.federation_domain_whitelist is not None
585
+ and server_name not in self.federation_domain_whitelist
586
+ ):
587
+ raise FederationDeniedError(server_name)
588
+
589
+ # Don't let users download media from domains listed in the config, even
590
+ # if we might have the media to serve. This is Trust & Safety tooling to
591
+ # block some servers' media from being accessible to local users.
592
+ # See `prevent_media_downloads_from` config docs for more info.
593
+ if server_name in self.prevent_media_downloads_from:
594
+ respond_404(request)
595
+ return
596
+
597
+ self.mark_recently_accessed(server_name, media_id)
598
+
599
+ # We linearize here to ensure that we don't try and download remote
600
+ # media multiple times concurrently
601
+ key = (server_name, media_id)
602
+ async with self.remote_media_linearizer.queue(key):
603
+ responder, media_info = await self._get_remote_media_impl(
604
+ server_name,
605
+ media_id,
606
+ max_timeout_ms,
607
+ self.download_ratelimiter,
608
+ ip_address,
609
+ use_federation_endpoint,
610
+ allow_authenticated,
611
+ )
612
+
613
+ # Check if the media is cached on the client, if so return 304. We need
614
+ # to do this after we have fetched remote media, as we need it to do the
615
+ # auth.
616
+ if check_for_cached_entry_and_respond(request):
617
+ # We always need to use the responder.
618
+ if responder:
619
+ with responder:
620
+ pass
621
+
622
+ return
623
+
624
+ # We deliberately stream the file outside the lock
625
+ if responder and media_info:
626
+ upload_name = name if name else media_info.upload_name
627
+ await respond_with_responder(
628
+ request,
629
+ responder,
630
+ media_info.media_type,
631
+ media_info.media_length,
632
+ upload_name,
633
+ )
634
+ else:
635
+ respond_404(request)
636
+
637
+ async def get_remote_media_info(
638
+ self,
639
+ server_name: str,
640
+ media_id: str,
641
+ max_timeout_ms: int,
642
+ ip_address: str,
643
+ use_federation: bool,
644
+ allow_authenticated: bool,
645
+ ) -> RemoteMedia:
646
+ """Gets the media info associated with the remote file, downloading
647
+ if necessary.
648
+
649
+ Args:
650
+ server_name: Remote server_name where the media originated.
651
+ media_id: The media ID of the content (as defined by the remote server).
652
+ max_timeout_ms: the maximum number of milliseconds to wait for the
653
+ media to be uploaded.
654
+ ip_address: IP address of the requester
655
+ use_federation: if a download is necessary, whether to request the remote file
656
+ over the federation `/download` endpoint
657
+ allow_authenticated: whether media marked as authenticated may be served to this
658
+ request
659
+
660
+ Returns:
661
+ The media info of the file
662
+ """
663
+ if (
664
+ self.federation_domain_whitelist is not None
665
+ and server_name not in self.federation_domain_whitelist
666
+ ):
667
+ raise FederationDeniedError(server_name)
668
+
669
+ # We linearize here to ensure that we don't try and download remote
670
+ # media multiple times concurrently
671
+ key = (server_name, media_id)
672
+ async with self.remote_media_linearizer.queue(key):
673
+ responder, media_info = await self._get_remote_media_impl(
674
+ server_name,
675
+ media_id,
676
+ max_timeout_ms,
677
+ self.download_ratelimiter,
678
+ ip_address,
679
+ use_federation,
680
+ allow_authenticated,
681
+ )
682
+
683
+ # Ensure we actually use the responder so that it releases resources
684
+ if responder:
685
+ with responder:
686
+ pass
687
+
688
+ return media_info
689
+
690
+ async def _get_remote_media_impl(
691
+ self,
692
+ server_name: str,
693
+ media_id: str,
694
+ max_timeout_ms: int,
695
+ download_ratelimiter: Ratelimiter,
696
+ ip_address: str,
697
+ use_federation_endpoint: bool,
698
+ allow_authenticated: bool,
699
+ ) -> tuple[Optional[Responder], RemoteMedia]:
700
+ """Looks for media in local cache, if not there then attempt to
701
+ download from remote server.
702
+
703
+ Args:
704
+ server_name: Remote server_name where the media originated.
705
+ media_id: The media ID of the content (as defined by the
706
+ remote server).
707
+ max_timeout_ms: the maximum number of milliseconds to wait for the
708
+ media to be uploaded.
709
+ download_ratelimiter: a ratelimiter limiting remote media downloads, keyed to
710
+ requester IP.
711
+ ip_address: the IP address of the requester
712
+ use_federation_endpoint: whether to request the remote media over the new federation
713
+ /download endpoint
714
+
715
+ Returns:
716
+ A tuple of responder and the media info of the file.
717
+ """
718
+ media_info = await self.store.get_cached_remote_media(server_name, media_id)
719
+
720
+ if self.hs.config.media.enable_authenticated_media and not allow_authenticated:
721
+ # if it isn't cached then don't fetch it or if it's authenticated then don't serve it
722
+ if not media_info or media_info.authenticated:
723
+ raise NotFoundError()
724
+
725
+ # file_id is the ID we use to track the file locally. If we've already
726
+ # seen the file then reuse the existing ID, otherwise generate a new
727
+ # one.
728
+
729
+ # If we have an entry in the DB, try and look for it
730
+ if media_info:
731
+ file_id = media_info.filesystem_id
732
+ file_info = FileInfo(server_name, file_id)
733
+
734
+ if media_info.quarantined_by:
735
+ logger.info("Media is quarantined")
736
+ raise NotFoundError()
737
+
738
+ if not media_info.media_type:
739
+ media_info = attr.evolve(
740
+ media_info, media_type="application/octet-stream"
741
+ )
742
+
743
+ responder = await self.media_storage.fetch_media(file_info)
744
+ if responder:
745
+ return responder, media_info
746
+
747
+ # Failed to find the file anywhere, lets download it.
748
+
749
+ try:
750
+ if not use_federation_endpoint:
751
+ media_info = await self._download_remote_file(
752
+ server_name,
753
+ media_id,
754
+ max_timeout_ms,
755
+ download_ratelimiter,
756
+ ip_address,
757
+ )
758
+ else:
759
+ media_info = await self._federation_download_remote_file(
760
+ server_name,
761
+ media_id,
762
+ max_timeout_ms,
763
+ download_ratelimiter,
764
+ ip_address,
765
+ )
766
+
767
+ except SynapseError:
768
+ raise
769
+ except Exception as e:
770
+ # An exception may be because we downloaded media in another
771
+ # process, so let's check if we magically have the media.
772
+ media_info = await self.store.get_cached_remote_media(server_name, media_id)
773
+ if not media_info:
774
+ raise e
775
+
776
+ file_id = media_info.filesystem_id
777
+ if not media_info.media_type:
778
+ media_info = attr.evolve(media_info, media_type="application/octet-stream")
779
+ file_info = FileInfo(server_name, file_id)
780
+
781
+ # We generate thumbnails even if another process downloaded the media
782
+ # as a) it's conceivable that the other download request dies before it
783
+ # generates thumbnails, but mainly b) we want to be sure the thumbnails
784
+ # have finished being generated before responding to the client,
785
+ # otherwise they'll request thumbnails and get a 404 if they're not
786
+ # ready yet.
787
+ await self._generate_thumbnails(
788
+ server_name, media_id, file_id, media_info.media_type
789
+ )
790
+
791
+ responder = await self.media_storage.fetch_media(file_info)
792
+ return responder, media_info
793
+
794
+ async def _download_remote_file(
795
+ self,
796
+ server_name: str,
797
+ media_id: str,
798
+ max_timeout_ms: int,
799
+ download_ratelimiter: Ratelimiter,
800
+ ip_address: str,
801
+ ) -> RemoteMedia:
802
+ """Attempt to download the remote file from the given server name,
803
+ using the given file_id as the local id.
804
+
805
+ Args:
806
+ server_name: Originating server
807
+ media_id: The media ID of the content (as defined by the
808
+ remote server). This is different than the file_id, which is
809
+ locally generated.
810
+ max_timeout_ms: the maximum number of milliseconds to wait for the
811
+ media to be uploaded.
812
+ download_ratelimiter: a ratelimiter limiting remote media downloads, keyed to
813
+ requester IP
814
+ ip_address: the IP address of the requester
815
+
816
+ Returns:
817
+ The media info of the file.
818
+ """
819
+
820
+ file_id = random_string(24)
821
+
822
+ file_info = FileInfo(server_name=server_name, file_id=file_id)
823
+
824
+ async with self.media_storage.store_into_file(file_info) as (f, fname):
825
+ sha256writer = SHA256TransparentIOWriter(f)
826
+ try:
827
+ length, headers = await self.client.download_media(
828
+ server_name,
829
+ media_id,
830
+ # This implements all of BinaryIO as it has a passthrough
831
+ output_stream=sha256writer.wrap(),
832
+ max_size=self.max_upload_size,
833
+ max_timeout_ms=max_timeout_ms,
834
+ download_ratelimiter=download_ratelimiter,
835
+ ip_address=ip_address,
836
+ )
837
+ except RequestSendFailed as e:
838
+ logger.warning(
839
+ "Request failed fetching remote media %s/%s: %r",
840
+ server_name,
841
+ media_id,
842
+ e,
843
+ )
844
+ raise SynapseError(502, "Failed to fetch remote media")
845
+
846
+ except HttpResponseException as e:
847
+ logger.warning(
848
+ "HTTP error fetching remote media %s/%s: %s",
849
+ server_name,
850
+ media_id,
851
+ e.response,
852
+ )
853
+ if e.code == twisted.web.http.NOT_FOUND:
854
+ raise e.to_synapse_error()
855
+ raise SynapseError(502, "Failed to fetch remote media")
856
+
857
+ except SynapseError:
858
+ logger.warning(
859
+ "Failed to fetch remote media %s/%s", server_name, media_id
860
+ )
861
+ raise
862
+ except NotRetryingDestination:
863
+ logger.warning("Not retrying destination %r", server_name)
864
+ raise SynapseError(502, "Failed to fetch remote media")
865
+ except Exception:
866
+ logger.exception(
867
+ "Failed to fetch remote media %s/%s", server_name, media_id
868
+ )
869
+ raise SynapseError(502, "Failed to fetch remote media")
870
+
871
+ if b"Content-Type" in headers:
872
+ media_type = headers[b"Content-Type"][0].decode("ascii")
873
+ else:
874
+ media_type = "application/octet-stream"
875
+ upload_name = get_filename_from_headers(headers)
876
+ time_now_ms = self.clock.time_msec()
877
+
878
+ # Multiple remote media download requests can race (when using
879
+ # multiple media repos), so this may throw a violation constraint
880
+ # exception. If it does we'll delete the newly downloaded file from
881
+ # disk (as we're in the ctx manager).
882
+ #
883
+ # However: we've already called `finish()` so we may have also
884
+ # written to the storage providers. This is preferable to the
885
+ # alternative where we call `finish()` *after* this, where we could
886
+ # end up having an entry in the DB but fail to write the files to
887
+ # the storage providers.
888
+ await self.store.store_cached_remote_media(
889
+ origin=server_name,
890
+ media_id=media_id,
891
+ media_type=media_type,
892
+ time_now_ms=time_now_ms,
893
+ upload_name=upload_name,
894
+ media_length=length,
895
+ filesystem_id=file_id,
896
+ sha256=sha256writer.hexdigest(),
897
+ )
898
+
899
+ logger.info("Stored remote media in file %r", fname)
900
+
901
+ if self.hs.config.media.enable_authenticated_media:
902
+ authenticated = True
903
+ else:
904
+ authenticated = False
905
+
906
+ return RemoteMedia(
907
+ media_origin=server_name,
908
+ media_id=media_id,
909
+ media_type=media_type,
910
+ media_length=length,
911
+ upload_name=upload_name,
912
+ created_ts=time_now_ms,
913
+ filesystem_id=file_id,
914
+ last_access_ts=time_now_ms,
915
+ quarantined_by=None,
916
+ authenticated=authenticated,
917
+ sha256=sha256writer.hexdigest(),
918
+ )
919
+
920
+ async def _federation_download_remote_file(
921
+ self,
922
+ server_name: str,
923
+ media_id: str,
924
+ max_timeout_ms: int,
925
+ download_ratelimiter: Ratelimiter,
926
+ ip_address: str,
927
+ ) -> RemoteMedia:
928
+ """Attempt to download the remote file from the given server name.
929
+ Uses the given file_id as the local id and downloads the file over the federation
930
+ v1 download endpoint
931
+
932
+ Args:
933
+ server_name: Originating server
934
+ media_id: The media ID of the content (as defined by the
935
+ remote server). This is different than the file_id, which is
936
+ locally generated.
937
+ max_timeout_ms: the maximum number of milliseconds to wait for the
938
+ media to be uploaded.
939
+ download_ratelimiter: a ratelimiter limiting remote media downloads, keyed to
940
+ requester IP
941
+ ip_address: the IP address of the requester
942
+
943
+ Returns:
944
+ The media info of the file.
945
+ """
946
+
947
+ file_id = random_string(24)
948
+
949
+ file_info = FileInfo(server_name=server_name, file_id=file_id)
950
+
951
+ async with self.media_storage.store_into_file(file_info) as (f, fname):
952
+ sha256writer = SHA256TransparentIOWriter(f)
953
+ try:
954
+ res = await self.client.federation_download_media(
955
+ server_name,
956
+ media_id,
957
+ # This implements all of BinaryIO as it has a passthrough
958
+ output_stream=sha256writer.wrap(),
959
+ max_size=self.max_upload_size,
960
+ max_timeout_ms=max_timeout_ms,
961
+ download_ratelimiter=download_ratelimiter,
962
+ ip_address=ip_address,
963
+ )
964
+ # if we had to fall back to the _matrix/media endpoint it will only return
965
+ # the headers and length, check the length of the tuple before unpacking
966
+ if len(res) == 3:
967
+ length, headers, json = res
968
+ else:
969
+ length, headers = res
970
+ except RequestSendFailed as e:
971
+ logger.warning(
972
+ "Request failed fetching remote media %s/%s: %r",
973
+ server_name,
974
+ media_id,
975
+ e,
976
+ )
977
+ raise SynapseError(502, "Failed to fetch remote media")
978
+
979
+ except HttpResponseException as e:
980
+ logger.warning(
981
+ "HTTP error fetching remote media %s/%s: %s",
982
+ server_name,
983
+ media_id,
984
+ e.response,
985
+ )
986
+ if e.code == twisted.web.http.NOT_FOUND:
987
+ raise e.to_synapse_error()
988
+ raise SynapseError(502, "Failed to fetch remote media")
989
+
990
+ except SynapseError:
991
+ logger.warning(
992
+ "Failed to fetch remote media %s/%s", server_name, media_id
993
+ )
994
+ raise
995
+ except NotRetryingDestination:
996
+ logger.warning("Not retrying destination %r", server_name)
997
+ raise SynapseError(502, "Failed to fetch remote media")
998
+ except Exception:
999
+ logger.exception(
1000
+ "Failed to fetch remote media %s/%s", server_name, media_id
1001
+ )
1002
+ raise SynapseError(502, "Failed to fetch remote media")
1003
+
1004
+ if b"Content-Type" in headers:
1005
+ media_type = headers[b"Content-Type"][0].decode("ascii")
1006
+ else:
1007
+ media_type = "application/octet-stream"
1008
+ upload_name = get_filename_from_headers(headers)
1009
+ time_now_ms = self.clock.time_msec()
1010
+
1011
+ # Multiple remote media download requests can race (when using
1012
+ # multiple media repos), so this may throw a violation constraint
1013
+ # exception. If it does we'll delete the newly downloaded file from
1014
+ # disk (as we're in the ctx manager).
1015
+ #
1016
+ # However: we've already called `finish()` so we may have also
1017
+ # written to the storage providers. This is preferable to the
1018
+ # alternative where we call `finish()` *after* this, where we could
1019
+ # end up having an entry in the DB but fail to write the files to
1020
+ # the storage providers.
1021
+ await self.store.store_cached_remote_media(
1022
+ origin=server_name,
1023
+ media_id=media_id,
1024
+ media_type=media_type,
1025
+ time_now_ms=time_now_ms,
1026
+ upload_name=upload_name,
1027
+ media_length=length,
1028
+ filesystem_id=file_id,
1029
+ sha256=sha256writer.hexdigest(),
1030
+ )
1031
+
1032
+ logger.debug("Stored remote media in file %r", fname)
1033
+
1034
+ if self.hs.config.media.enable_authenticated_media:
1035
+ authenticated = True
1036
+ else:
1037
+ authenticated = False
1038
+
1039
+ return RemoteMedia(
1040
+ media_origin=server_name,
1041
+ media_id=media_id,
1042
+ media_type=media_type,
1043
+ media_length=length,
1044
+ upload_name=upload_name,
1045
+ created_ts=time_now_ms,
1046
+ filesystem_id=file_id,
1047
+ last_access_ts=time_now_ms,
1048
+ quarantined_by=None,
1049
+ authenticated=authenticated,
1050
+ sha256=sha256writer.hexdigest(),
1051
+ )
1052
+
1053
+ def _get_thumbnail_requirements(
1054
+ self, media_type: str
1055
+ ) -> tuple[ThumbnailRequirement, ...]:
1056
+ scpos = media_type.find(";")
1057
+ if scpos > 0:
1058
+ media_type = media_type[:scpos]
1059
+ return self.thumbnail_requirements.get(media_type, ())
1060
+
1061
+ def _generate_thumbnail(
1062
+ self,
1063
+ thumbnailer: Thumbnailer,
1064
+ t_width: int,
1065
+ t_height: int,
1066
+ t_method: str,
1067
+ t_type: str,
1068
+ ) -> Optional[BytesIO]:
1069
+ m_width = thumbnailer.width
1070
+ m_height = thumbnailer.height
1071
+
1072
+ if m_width * m_height >= self.max_image_pixels:
1073
+ logger.info(
1074
+ "Image too large to thumbnail %r x %r > %r",
1075
+ m_width,
1076
+ m_height,
1077
+ self.max_image_pixels,
1078
+ )
1079
+ return None
1080
+
1081
+ if thumbnailer.transpose_method is not None:
1082
+ m_width, m_height = thumbnailer.transpose()
1083
+
1084
+ if t_method == "crop":
1085
+ return thumbnailer.crop(t_width, t_height, t_type)
1086
+ elif t_method == "scale":
1087
+ t_width, t_height = thumbnailer.aspect(t_width, t_height)
1088
+ t_width = min(m_width, t_width)
1089
+ t_height = min(m_height, t_height)
1090
+ return thumbnailer.scale(t_width, t_height, t_type)
1091
+
1092
+ return None
1093
+
1094
+ async def generate_local_exact_thumbnail(
1095
+ self,
1096
+ media_id: str,
1097
+ t_width: int,
1098
+ t_height: int,
1099
+ t_method: str,
1100
+ t_type: str,
1101
+ url_cache: bool,
1102
+ ) -> Optional[tuple[str, FileInfo]]:
1103
+ input_path = await self.media_storage.ensure_media_is_in_local_cache(
1104
+ FileInfo(None, media_id, url_cache=url_cache)
1105
+ )
1106
+
1107
+ try:
1108
+ thumbnailer = Thumbnailer(input_path)
1109
+ except ThumbnailError as e:
1110
+ logger.warning(
1111
+ "Unable to generate a thumbnail for local media %s using a method of %s and type of %s: %s",
1112
+ media_id,
1113
+ t_method,
1114
+ t_type,
1115
+ e,
1116
+ )
1117
+ return None
1118
+
1119
+ with thumbnailer:
1120
+ t_byte_source = await defer_to_thread(
1121
+ self.hs.get_reactor(),
1122
+ self._generate_thumbnail,
1123
+ thumbnailer,
1124
+ t_width,
1125
+ t_height,
1126
+ t_method,
1127
+ t_type,
1128
+ )
1129
+
1130
+ if t_byte_source:
1131
+ try:
1132
+ file_info = FileInfo(
1133
+ server_name=None,
1134
+ file_id=media_id,
1135
+ url_cache=url_cache,
1136
+ thumbnail=ThumbnailInfo(
1137
+ width=t_width,
1138
+ height=t_height,
1139
+ method=t_method,
1140
+ type=t_type,
1141
+ length=t_byte_source.tell(),
1142
+ ),
1143
+ )
1144
+
1145
+ output_path = await self.media_storage.store_file(
1146
+ t_byte_source, file_info
1147
+ )
1148
+ finally:
1149
+ t_byte_source.close()
1150
+
1151
+ logger.info("Stored thumbnail in file %r", output_path)
1152
+
1153
+ t_len = os.path.getsize(output_path)
1154
+
1155
+ await self.store.store_local_thumbnail(
1156
+ media_id,
1157
+ t_width,
1158
+ t_height,
1159
+ t_type,
1160
+ t_method,
1161
+ t_len,
1162
+ )
1163
+
1164
+ return output_path, file_info
1165
+
1166
+ # Could not generate thumbnail.
1167
+ return None
1168
+
1169
+ async def generate_remote_exact_thumbnail(
1170
+ self,
1171
+ server_name: str,
1172
+ file_id: str,
1173
+ media_id: str,
1174
+ t_width: int,
1175
+ t_height: int,
1176
+ t_method: str,
1177
+ t_type: str,
1178
+ ) -> Optional[str]:
1179
+ input_path = await self.media_storage.ensure_media_is_in_local_cache(
1180
+ FileInfo(server_name, file_id)
1181
+ )
1182
+
1183
+ try:
1184
+ thumbnailer = Thumbnailer(input_path)
1185
+ except ThumbnailError as e:
1186
+ logger.warning(
1187
+ "Unable to generate a thumbnail for remote media %s from %s using a method of %s and type of %s: %s",
1188
+ media_id,
1189
+ server_name,
1190
+ t_method,
1191
+ t_type,
1192
+ e,
1193
+ )
1194
+ return None
1195
+
1196
+ with thumbnailer:
1197
+ t_byte_source = await defer_to_thread(
1198
+ self.hs.get_reactor(),
1199
+ self._generate_thumbnail,
1200
+ thumbnailer,
1201
+ t_width,
1202
+ t_height,
1203
+ t_method,
1204
+ t_type,
1205
+ )
1206
+
1207
+ if t_byte_source:
1208
+ try:
1209
+ file_info = FileInfo(
1210
+ server_name=server_name,
1211
+ file_id=file_id,
1212
+ thumbnail=ThumbnailInfo(
1213
+ width=t_width,
1214
+ height=t_height,
1215
+ method=t_method,
1216
+ type=t_type,
1217
+ length=t_byte_source.tell(),
1218
+ ),
1219
+ )
1220
+
1221
+ output_path = await self.media_storage.store_file(
1222
+ t_byte_source, file_info
1223
+ )
1224
+ finally:
1225
+ t_byte_source.close()
1226
+
1227
+ logger.info("Stored thumbnail in file %r", output_path)
1228
+
1229
+ t_len = os.path.getsize(output_path)
1230
+
1231
+ await self.store.store_remote_media_thumbnail(
1232
+ server_name,
1233
+ media_id,
1234
+ file_id,
1235
+ t_width,
1236
+ t_height,
1237
+ t_type,
1238
+ t_method,
1239
+ t_len,
1240
+ )
1241
+
1242
+ return output_path
1243
+
1244
+ # Could not generate thumbnail.
1245
+ return None
1246
+
1247
+ @trace
1248
+ async def _generate_thumbnails(
1249
+ self,
1250
+ server_name: Optional[str],
1251
+ media_id: str,
1252
+ file_id: str,
1253
+ media_type: str,
1254
+ url_cache: bool = False,
1255
+ ) -> Optional[dict]:
1256
+ """Generate and store thumbnails for an image.
1257
+
1258
+ Args:
1259
+ server_name: The server name if remote media, else None if local
1260
+ media_id: The media ID of the content. (This is the same as
1261
+ the file_id for local content)
1262
+ file_id: Local file ID
1263
+ media_type: The content type of the file
1264
+ url_cache: If we are thumbnailing images downloaded for the URL cache,
1265
+ used exclusively by the url previewer
1266
+
1267
+ Returns:
1268
+ Dict with "width" and "height" keys of original image or None if the
1269
+ media cannot be thumbnailed.
1270
+ """
1271
+ requirements = self._get_thumbnail_requirements(media_type)
1272
+ if not requirements:
1273
+ return None
1274
+
1275
+ input_path = await self.media_storage.ensure_media_is_in_local_cache(
1276
+ FileInfo(server_name, file_id, url_cache=url_cache)
1277
+ )
1278
+
1279
+ try:
1280
+ thumbnailer = Thumbnailer(input_path)
1281
+ except ThumbnailError as e:
1282
+ logger.warning(
1283
+ "Unable to generate thumbnails for remote media %s from %s of type %s: %s",
1284
+ media_id,
1285
+ server_name,
1286
+ media_type,
1287
+ e,
1288
+ )
1289
+ return None
1290
+
1291
+ with thumbnailer:
1292
+ m_width = thumbnailer.width
1293
+ m_height = thumbnailer.height
1294
+
1295
+ if m_width * m_height >= self.max_image_pixels:
1296
+ logger.info(
1297
+ "Image too large to thumbnail %r x %r > %r",
1298
+ m_width,
1299
+ m_height,
1300
+ self.max_image_pixels,
1301
+ )
1302
+ return None
1303
+
1304
+ if thumbnailer.transpose_method is not None:
1305
+ m_width, m_height = await defer_to_thread(
1306
+ self.hs.get_reactor(), thumbnailer.transpose
1307
+ )
1308
+
1309
+ # We deduplicate the thumbnail sizes by ignoring the cropped versions if
1310
+ # they have the same dimensions of a scaled one.
1311
+ thumbnails: dict[tuple[int, int, str], str] = {}
1312
+ for requirement in requirements:
1313
+ if requirement.method == "crop":
1314
+ thumbnails.setdefault(
1315
+ (requirement.width, requirement.height, requirement.media_type),
1316
+ requirement.method,
1317
+ )
1318
+ elif requirement.method == "scale":
1319
+ t_width, t_height = thumbnailer.aspect(
1320
+ requirement.width, requirement.height
1321
+ )
1322
+ t_width = min(m_width, t_width)
1323
+ t_height = min(m_height, t_height)
1324
+ thumbnails[(t_width, t_height, requirement.media_type)] = (
1325
+ requirement.method
1326
+ )
1327
+
1328
+ # Now we generate the thumbnails for each dimension, store it
1329
+ for (t_width, t_height, t_type), t_method in thumbnails.items():
1330
+ # Generate the thumbnail
1331
+ if t_method == "crop":
1332
+ t_byte_source = await defer_to_thread(
1333
+ self.hs.get_reactor(),
1334
+ thumbnailer.crop,
1335
+ t_width,
1336
+ t_height,
1337
+ t_type,
1338
+ )
1339
+ elif t_method == "scale":
1340
+ t_byte_source = await defer_to_thread(
1341
+ self.hs.get_reactor(),
1342
+ thumbnailer.scale,
1343
+ t_width,
1344
+ t_height,
1345
+ t_type,
1346
+ )
1347
+ else:
1348
+ logger.error("Unrecognized method: %r", t_method)
1349
+ continue
1350
+
1351
+ if not t_byte_source:
1352
+ continue
1353
+
1354
+ file_info = FileInfo(
1355
+ server_name=server_name,
1356
+ file_id=file_id,
1357
+ url_cache=url_cache,
1358
+ thumbnail=ThumbnailInfo(
1359
+ width=t_width,
1360
+ height=t_height,
1361
+ method=t_method,
1362
+ type=t_type,
1363
+ length=t_byte_source.tell(),
1364
+ ),
1365
+ )
1366
+
1367
+ async with self.media_storage.store_into_file(file_info) as (f, fname):
1368
+ try:
1369
+ await self.media_storage.write_to_file(t_byte_source, f)
1370
+ finally:
1371
+ t_byte_source.close()
1372
+
1373
+ # We flush and close the file to ensure that the bytes have
1374
+ # been written before getting the size.
1375
+ f.flush()
1376
+ f.close()
1377
+
1378
+ t_len = os.path.getsize(fname)
1379
+
1380
+ # Write to database
1381
+ if server_name:
1382
+ # Multiple remote media download requests can race (when
1383
+ # using multiple media repos), so this may throw a violation
1384
+ # constraint exception. If it does we'll delete the newly
1385
+ # generated thumbnail from disk (as we're in the ctx
1386
+ # manager).
1387
+ #
1388
+ # However: we've already called `finish()` so we may have
1389
+ # also written to the storage providers. This is preferable
1390
+ # to the alternative where we call `finish()` *after* this,
1391
+ # where we could end up having an entry in the DB but fail
1392
+ # to write the files to the storage providers.
1393
+ try:
1394
+ await self.store.store_remote_media_thumbnail(
1395
+ server_name,
1396
+ media_id,
1397
+ file_id,
1398
+ t_width,
1399
+ t_height,
1400
+ t_type,
1401
+ t_method,
1402
+ t_len,
1403
+ )
1404
+ except Exception as e:
1405
+ thumbnail_exists = (
1406
+ await self.store.get_remote_media_thumbnail(
1407
+ server_name,
1408
+ media_id,
1409
+ t_width,
1410
+ t_height,
1411
+ t_type,
1412
+ )
1413
+ )
1414
+ if not thumbnail_exists:
1415
+ raise e
1416
+ else:
1417
+ await self.store.store_local_thumbnail(
1418
+ media_id, t_width, t_height, t_type, t_method, t_len
1419
+ )
1420
+
1421
+ return {"width": m_width, "height": m_height}
1422
+
1423
+ async def _apply_media_retention_rules(self) -> None:
1424
+ """
1425
+ Purge old local and remote media according to the media retention rules
1426
+ defined in the homeserver config.
1427
+ """
1428
+ # Purge remote media
1429
+ if self._media_retention_remote_media_lifetime_ms is not None:
1430
+ # Calculate a threshold timestamp derived from the configured lifetime. Any
1431
+ # media that has not been accessed since this timestamp will be removed.
1432
+ remote_media_threshold_timestamp_ms = (
1433
+ self.clock.time_msec() - self._media_retention_remote_media_lifetime_ms
1434
+ )
1435
+
1436
+ logger.info(
1437
+ "Purging remote media last accessed before %s",
1438
+ remote_media_threshold_timestamp_ms,
1439
+ )
1440
+
1441
+ await self.delete_old_remote_media(
1442
+ before_ts=remote_media_threshold_timestamp_ms
1443
+ )
1444
+
1445
+ # And now do the same for local media
1446
+ if self._media_retention_local_media_lifetime_ms is not None:
1447
+ # This works the same as the remote media threshold
1448
+ local_media_threshold_timestamp_ms = (
1449
+ self.clock.time_msec() - self._media_retention_local_media_lifetime_ms
1450
+ )
1451
+
1452
+ logger.info(
1453
+ "Purging local media last accessed before %s",
1454
+ local_media_threshold_timestamp_ms,
1455
+ )
1456
+
1457
+ await self.delete_old_local_media(
1458
+ before_ts=local_media_threshold_timestamp_ms,
1459
+ keep_profiles=True,
1460
+ delete_quarantined_media=False,
1461
+ delete_protected_media=False,
1462
+ )
1463
+
1464
+ async def delete_old_remote_media(self, before_ts: int) -> dict[str, int]:
1465
+ old_media = await self.store.get_remote_media_ids(
1466
+ before_ts, include_quarantined_media=False
1467
+ )
1468
+
1469
+ deleted = 0
1470
+
1471
+ for origin, media_id, file_id in old_media:
1472
+ key = (origin, media_id)
1473
+
1474
+ logger.info("Deleting: %r", key)
1475
+
1476
+ # TODO: Should we delete from the backup store
1477
+
1478
+ async with self.remote_media_linearizer.queue(key):
1479
+ full_path = self.filepaths.remote_media_filepath(origin, file_id)
1480
+ try:
1481
+ os.remove(full_path)
1482
+ except OSError as e:
1483
+ logger.warning("Failed to remove file: %r", full_path)
1484
+ if e.errno == errno.ENOENT:
1485
+ pass
1486
+ else:
1487
+ continue
1488
+
1489
+ thumbnail_dir = self.filepaths.remote_media_thumbnail_dir(
1490
+ origin, file_id
1491
+ )
1492
+ shutil.rmtree(thumbnail_dir, ignore_errors=True)
1493
+
1494
+ await self.store.delete_remote_media(origin, media_id)
1495
+ deleted += 1
1496
+
1497
+ return {"deleted": deleted}
1498
+
1499
+ async def delete_local_media_ids(
1500
+ self, media_ids: list[str]
1501
+ ) -> tuple[list[str], int]:
1502
+ """
1503
+ Delete the given local or remote media ID from this server
1504
+
1505
+ Args:
1506
+ media_id: The media ID to delete.
1507
+ Returns:
1508
+ A tuple of (list of deleted media IDs, total deleted media IDs).
1509
+ """
1510
+ return await self._remove_local_media_from_disk(media_ids)
1511
+
1512
+ async def delete_old_local_media(
1513
+ self,
1514
+ before_ts: int,
1515
+ size_gt: int = 0,
1516
+ keep_profiles: bool = True,
1517
+ delete_quarantined_media: bool = False,
1518
+ delete_protected_media: bool = False,
1519
+ ) -> tuple[list[str], int]:
1520
+ """
1521
+ Delete local or remote media from this server by size and timestamp. Removes
1522
+ media files, any thumbnails and cached URLs.
1523
+
1524
+ Args:
1525
+ before_ts: Unix timestamp in ms.
1526
+ Files that were last used before this timestamp will be deleted.
1527
+ size_gt: Size of the media in bytes. Files that are larger will be deleted.
1528
+ keep_profiles: Switch to delete also files that are still used in image data
1529
+ (e.g user profile, room avatar). If false these files will be deleted.
1530
+ delete_quarantined_media: If True, media marked as quarantined will be deleted.
1531
+ delete_protected_media: If True, media marked as protected will be deleted.
1532
+
1533
+ Returns:
1534
+ A tuple of (list of deleted media IDs, total deleted media IDs).
1535
+ """
1536
+ old_media = await self.store.get_local_media_ids(
1537
+ before_ts,
1538
+ size_gt,
1539
+ keep_profiles,
1540
+ include_quarantined_media=delete_quarantined_media,
1541
+ include_protected_media=delete_protected_media,
1542
+ )
1543
+ return await self._remove_local_media_from_disk(old_media)
1544
+
1545
+ async def _remove_local_media_from_disk(
1546
+ self, media_ids: list[str]
1547
+ ) -> tuple[list[str], int]:
1548
+ """
1549
+ Delete local or remote media from this server. Removes media files,
1550
+ any thumbnails and cached URLs.
1551
+
1552
+ Args:
1553
+ media_ids: List of media_id to delete
1554
+ Returns:
1555
+ A tuple of (list of deleted media IDs, total deleted media IDs).
1556
+ """
1557
+ removed_media = []
1558
+ for media_id in media_ids:
1559
+ logger.info("Deleting media with ID '%s'", media_id)
1560
+ full_path = self.filepaths.local_media_filepath(media_id)
1561
+ try:
1562
+ os.remove(full_path)
1563
+ except OSError as e:
1564
+ logger.warning("Failed to remove file: %r: %s", full_path, e)
1565
+ if e.errno == errno.ENOENT:
1566
+ pass
1567
+ else:
1568
+ continue
1569
+
1570
+ thumbnail_dir = self.filepaths.local_media_thumbnail_dir(media_id)
1571
+ shutil.rmtree(thumbnail_dir, ignore_errors=True)
1572
+
1573
+ await self.store.delete_remote_media(self.server_name, media_id)
1574
+
1575
+ await self.store.delete_url_cache((media_id,))
1576
+ await self.store.delete_url_cache_media((media_id,))
1577
+
1578
+ removed_media.append(media_id)
1579
+
1580
+ return removed_media, len(removed_media)