From 4917e01ffba633253e1dd85898ead4ff2c8e487d Mon Sep 17 00:00:00 2001 From: Mateusz Mandera Date: Thu, 13 Jun 2024 14:38:58 +0200 Subject: [PATCH] push_notifications: Migrate to FCM HTTP v1 API. The legacy API we use via python-gcm is deprecated and about to be disabled. Fixes #29768. --- pyproject.toml | 1 + requirements/common.in | 7 +- requirements/dev.txt | 304 ++++++++++++++++++++++- requirements/prod.txt | 307 +++++++++++++++++++++++- version.py | 2 +- zerver/lib/push_notifications.py | 141 ++++++----- zerver/tests/test_push_notifications.py | 113 ++++++--- zilencer/views.py | 3 + zproject/computed_settings.py | 5 - zproject/default_settings.py | 1 + 10 files changed, 757 insertions(+), 127 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2b5906ee77..a9316b6721 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,6 +66,7 @@ module = [ "django_scim.*", "DNS.*", "fakeldap.*", + "firebase_admin.*", "gcm.*", "gitlint.*", "jsonref.*", diff --git a/requirements/common.in b/requirements/common.in index 9c13878993..6a4a3fdc64 100644 --- a/requirements/common.in +++ b/requirements/common.in @@ -52,7 +52,12 @@ django-auth-ldap django-bitfield # Needed for Android push notifications -python-gcm +# grpcio-status needs to be pinned to 1.62.* because higher +# versions demand protobuf>=5.26.1, which conflicts with various +# other big dependencies of firebase-admin. pip fails to +# find this resolution by itself. +grpcio-status==1.62.* +firebase-admin # Needed for the email mirror html2text diff --git a/requirements/dev.txt b/requirements/dev.txt index 59aa984cda..ca3565b8ab 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -248,6 +248,14 @@ bracex==2.4 \ --hash=sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb \ --hash=sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418 # via wcmatch +cachecontrol==0.14.0 \ + --hash=sha256:7db1195b41c81f8274a7bbd97c956f44e8348265a1bc7641c37dfebc39f0c938 \ + --hash=sha256:f5bf3f0620c38db2e5122c0726bdebb0d16869de966ea6a2befe92470b740ea0 + # via firebase-admin +cachetools==5.3.3 \ + --hash=sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945 \ + --hash=sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105 + # via google-auth cairocffi==1.7.0 \ --hash=sha256:1f29a8d41dbda4090c0aa33bcdea64f3b493e95f74a43ea107c4a8a7b7f632ef \ --hash=sha256:7761863603894305f3160eca68452f373433ca8745ab7dd445bd2c6ce50dcab7 @@ -536,6 +544,7 @@ cryptography==42.0.7 \ # via # -r requirements/common.in # moto + # pyjwt # pyopenssl # scrapy # service-identity @@ -699,6 +708,10 @@ filelock==3.14.0 \ --hash=sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f \ --hash=sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a # via tldextract +firebase-admin==6.5.0 \ + --hash=sha256:e716dde1447f0a1cd1523be76ff872df33c4e1a3c079564ace033b2ad60bcc4f \ + --hash=sha256:fe34ee3ca0e625c5156b3931ca4b4b69b5fc344dbe51bba9706ff674ce277898 + # via -r requirements/common.in frozenlist==1.4.1 \ --hash=sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7 \ --hash=sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98 \ @@ -792,6 +805,119 @@ glom==22.1.0 \ --hash=sha256:1510c6587a8f9c64a246641b70033cbc5ebde99f02ad245693678038e821aeb5 \ --hash=sha256:5339da206bf3532e01a83a35aca202960ea885156986d190574b779598e9e772 # via semgrep +google-api-core[grpc]==2.19.0 \ + --hash=sha256:8661eec4078c35428fd3f69a2c7ee29e342896b70f01d1a1cbcb334372dd6251 \ + --hash=sha256:cf1b7c2694047886d2af1128a03ae99e391108a08804f87cfd35970e49c9cd10 + # via + # firebase-admin + # google-api-python-client + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-api-python-client==2.133.0 \ + --hash=sha256:293092905b66a046d3187a99ac454e12b00cc2c70444f26eb2f1f9c1a82720b4 \ + --hash=sha256:396fe676ea0dfed066654dcf9f8dea77a1342f9d9bb23bb88e45b7b81e773926 + # via firebase-admin +google-auth==2.30.0 \ + --hash=sha256:8df7da660f62757388b8a7f249df13549b3373f24388cb5d2f1dd91cc18180b5 \ + --hash=sha256:ab630a1320f6720909ad76a7dbdb6841cdf5c66b328d690027e4867bdfb16688 + # via + # google-api-core + # google-api-python-client + # google-auth-httplib2 + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-auth-httplib2==0.2.0 \ + --hash=sha256:38aa7badf48f974f1eb9861794e9c0cb2a0511a4ec0679b1f886d108f5640e05 \ + --hash=sha256:b65a0a2123300dd71281a7bf6e64d65a0759287df52729bdd1ae2e47dc311a3d + # via google-api-python-client +google-cloud-core==2.4.1 \ + --hash=sha256:9b7749272a812bde58fff28868d0c5e2f585b82f37e09a1f6ed2d4d10f134073 \ + --hash=sha256:a9e6a4422b9ac5c29f79a0ede9485473338e2ce78d91f2370c01e730eab22e61 + # via + # google-cloud-firestore + # google-cloud-storage +google-cloud-firestore==2.16.0 \ + --hash=sha256:3347ac38346c2702134d4c81f652a5e3451c840a6237f28b844501bd528e5fd8 \ + --hash=sha256:e61ae70229a6e532e439c8d16447a32024447f2ee4a2303fc4d054c258d6877f + # via firebase-admin +google-cloud-storage==2.17.0 \ + --hash=sha256:49378abff54ef656b52dca5ef0f2eba9aa83dc2b2c72c78714b03a1a95fe9388 \ + --hash=sha256:5b393bc766b7a3bc6f5407b9e665b2450d36282614b7945e570b3480a456d1e1 + # via firebase-admin +google-crc32c==1.5.0 \ + --hash=sha256:024894d9d3cfbc5943f8f230e23950cd4906b2fe004c72e29b209420a1e6b05a \ + --hash=sha256:02c65b9817512edc6a4ae7c7e987fea799d2e0ee40c53ec573a692bee24de876 \ + --hash=sha256:02ebb8bf46c13e36998aeaad1de9b48f4caf545e91d14041270d9dca767b780c \ + --hash=sha256:07eb3c611ce363c51a933bf6bd7f8e3878a51d124acfc89452a75120bc436289 \ + --hash=sha256:1034d91442ead5a95b5aaef90dbfaca8633b0247d1e41621d1e9f9db88c36298 \ + --hash=sha256:116a7c3c616dd14a3de8c64a965828b197e5f2d121fedd2f8c5585c547e87b02 \ + --hash=sha256:19e0a019d2c4dcc5e598cd4a4bc7b008546b0358bd322537c74ad47a5386884f \ + --hash=sha256:1c7abdac90433b09bad6c43a43af253e688c9cfc1c86d332aed13f9a7c7f65e2 \ + --hash=sha256:1e986b206dae4476f41bcec1faa057851f3889503a70e1bdb2378d406223994a \ + --hash=sha256:272d3892a1e1a2dbc39cc5cde96834c236d5327e2122d3aaa19f6614531bb6eb \ + --hash=sha256:278d2ed7c16cfc075c91378c4f47924c0625f5fc84b2d50d921b18b7975bd210 \ + --hash=sha256:2ad40e31093a4af319dadf503b2467ccdc8f67c72e4bcba97f8c10cb078207b5 \ + --hash=sha256:2e920d506ec85eb4ba50cd4228c2bec05642894d4c73c59b3a2fe20346bd00ee \ + --hash=sha256:3359fc442a743e870f4588fcf5dcbc1bf929df1fad8fb9905cd94e5edb02e84c \ + --hash=sha256:37933ec6e693e51a5b07505bd05de57eee12f3e8c32b07da7e73669398e6630a \ + --hash=sha256:398af5e3ba9cf768787eef45c803ff9614cc3e22a5b2f7d7ae116df8b11e3314 \ + --hash=sha256:3b747a674c20a67343cb61d43fdd9207ce5da6a99f629c6e2541aa0e89215bcd \ + --hash=sha256:461665ff58895f508e2866824a47bdee72497b091c730071f2b7575d5762ab65 \ + --hash=sha256:4c6fdd4fccbec90cc8a01fc00773fcd5fa28db683c116ee3cb35cd5da9ef6c37 \ + --hash=sha256:5829b792bf5822fd0a6f6eb34c5f81dd074f01d570ed7f36aa101d6fc7a0a6e4 \ + --hash=sha256:596d1f98fc70232fcb6590c439f43b350cb762fb5d61ce7b0e9db4539654cc13 \ + --hash=sha256:5ae44e10a8e3407dbe138984f21e536583f2bba1be9491239f942c2464ac0894 \ + --hash=sha256:635f5d4dd18758a1fbd1049a8e8d2fee4ffed124462d837d1a02a0e009c3ab31 \ + --hash=sha256:64e52e2b3970bd891309c113b54cf0e4384762c934d5ae56e283f9a0afcd953e \ + --hash=sha256:66741ef4ee08ea0b2cc3c86916ab66b6aef03768525627fd6a1b34968b4e3709 \ + --hash=sha256:67b741654b851abafb7bc625b6d1cdd520a379074e64b6a128e3b688c3c04740 \ + --hash=sha256:6ac08d24c1f16bd2bf5eca8eaf8304812f44af5cfe5062006ec676e7e1d50afc \ + --hash=sha256:6f998db4e71b645350b9ac28a2167e6632c239963ca9da411523bb439c5c514d \ + --hash=sha256:72218785ce41b9cfd2fc1d6a017dc1ff7acfc4c17d01053265c41a2c0cc39b8c \ + --hash=sha256:74dea7751d98034887dbd821b7aae3e1d36eda111d6ca36c206c44478035709c \ + --hash=sha256:759ce4851a4bb15ecabae28f4d2e18983c244eddd767f560165563bf9aefbc8d \ + --hash=sha256:77e2fd3057c9d78e225fa0a2160f96b64a824de17840351b26825b0848022906 \ + --hash=sha256:7c074fece789b5034b9b1404a1f8208fc2d4c6ce9decdd16e8220c5a793e6f61 \ + --hash=sha256:7c42c70cd1d362284289c6273adda4c6af8039a8ae12dc451dcd61cdabb8ab57 \ + --hash=sha256:7f57f14606cd1dd0f0de396e1e53824c371e9544a822648cd76c034d209b559c \ + --hash=sha256:83c681c526a3439b5cf94f7420471705bbf96262f49a6fe546a6db5f687a3d4a \ + --hash=sha256:8485b340a6a9e76c62a7dce3c98e5f102c9219f4cfbf896a00cf48caf078d438 \ + --hash=sha256:84e6e8cd997930fc66d5bb4fde61e2b62ba19d62b7abd7a69920406f9ecca946 \ + --hash=sha256:89284716bc6a5a415d4eaa11b1726d2d60a0cd12aadf5439828353662ede9dd7 \ + --hash=sha256:8b87e1a59c38f275c0e3676fc2ab6d59eccecfd460be267ac360cc31f7bcde96 \ + --hash=sha256:8f24ed114432de109aa9fd317278518a5af2d31ac2ea6b952b2f7782b43da091 \ + --hash=sha256:98cb4d057f285bd80d8778ebc4fde6b4d509ac3f331758fb1528b733215443ae \ + --hash=sha256:998679bf62b7fb599d2878aa3ed06b9ce688b8974893e7223c60db155f26bd8d \ + --hash=sha256:9ba053c5f50430a3fcfd36f75aff9caeba0440b2d076afdb79a318d6ca245f88 \ + --hash=sha256:9c99616c853bb585301df6de07ca2cadad344fd1ada6d62bb30aec05219c45d2 \ + --hash=sha256:a1fd716e7a01f8e717490fbe2e431d2905ab8aa598b9b12f8d10abebb36b04dd \ + --hash=sha256:a2355cba1f4ad8b6988a4ca3feed5bff33f6af2d7f134852cf279c2aebfde541 \ + --hash=sha256:b1f8133c9a275df5613a451e73f36c2aea4fe13c5c8997e22cf355ebd7bd0728 \ + --hash=sha256:b8667b48e7a7ef66afba2c81e1094ef526388d35b873966d8a9a447974ed9178 \ + --hash=sha256:ba1eb1843304b1e5537e1fca632fa894d6f6deca8d6389636ee5b4797affb968 \ + --hash=sha256:be82c3c8cfb15b30f36768797a640e800513793d6ae1724aaaafe5bf86f8f346 \ + --hash=sha256:c02ec1c5856179f171e032a31d6f8bf84e5a75c45c33b2e20a3de353b266ebd8 \ + --hash=sha256:c672d99a345849301784604bfeaeba4db0c7aae50b95be04dd651fd2a7310b93 \ + --hash=sha256:c6c777a480337ac14f38564ac88ae82d4cd238bf293f0a22295b66eb89ffced7 \ + --hash=sha256:cae0274952c079886567f3f4f685bcaf5708f0a23a5f5216fdab71f81a6c0273 \ + --hash=sha256:cd67cf24a553339d5062eff51013780a00d6f97a39ca062781d06b3a73b15462 \ + --hash=sha256:d3515f198eaa2f0ed49f8819d5732d70698c3fa37384146079b3799b97667a94 \ + --hash=sha256:d5280312b9af0976231f9e317c20e4a61cd2f9629b7bfea6a693d1878a264ebd \ + --hash=sha256:de06adc872bcd8c2a4e0dc51250e9e65ef2ca91be023b9d13ebd67c2ba552e1e \ + --hash=sha256:e1674e4307fa3024fc897ca774e9c7562c957af85df55efe2988ed9056dc4e57 \ + --hash=sha256:e2096eddb4e7c7bdae4bd69ad364e55e07b8316653234a56552d9c988bd2d61b \ + --hash=sha256:e560628513ed34759456a416bf86b54b2476c59144a9138165c9a1575801d0d9 \ + --hash=sha256:edfedb64740750e1a3b16152620220f51d58ff1b4abceb339ca92e934775c27a \ + --hash=sha256:f13cae8cc389a440def0c8c52057f37359014ccbc9dc1f0827936bcd367c6100 \ + --hash=sha256:f314013e7dcd5cf45ab1945d92e713eec788166262ae8deb2cfacd53def27325 \ + --hash=sha256:f583edb943cf2e09c60441b910d6a20b4d9d626c75a36c8fcac01a6c96c01183 \ + --hash=sha256:fd8536e902db7e365f49e7d9029283403974ccf29b13fc7028b97e2295b33556 \ + --hash=sha256:fe70e325aa68fa4b5edf7d1a4b6f691eb04bbccac0ace68e34820d283b5f80d4 + # via + # google-cloud-storage + # google-resumable-media google-re2==1.1.20240601 \ --hash=sha256:0013ddbbae8d42bd8ab42213c5da3741630eae98b6eca816d72bc77fdda3d356 \ --hash=sha256:01297cbe44df033adec9d21a2241a7b50efb77bce625f196bf33bc0a87d6906d \ @@ -908,6 +1034,16 @@ google-re2==1.1.20240601 \ --hash=sha256:f9ed2a0e92ed79f944d836c533e69ca6e3e9dd85ac7af6f7adf715ee9793e28b \ --hash=sha256:fb495ac61628b0c8747cb3d4deb0d941f081bcf3d913083475fafd0a4d826582 # via -r requirements/common.in +google-resumable-media==2.7.1 \ + --hash=sha256:103ebc4ba331ab1bfdac0250f8033627a2cd7cde09e7ccff9181e31ba4315b2c \ + --hash=sha256:eae451a7b2e2cdbaaa0fd2eb00cc8a1ee5e95e16b55597359cbc3d27d7d90e33 + # via google-cloud-storage +googleapis-common-protos==1.63.1 \ + --hash=sha256:0e1c2cdfcbc354b76e4a211a35ea35d6926a835cba1377073c4861db904a1877 \ + --hash=sha256:c6442f7a0a6b2a80369457d79e6672bb7dcbaab88e0848302497e3ec80780a6a + # via + # google-api-core + # grpcio-status greenlet==3.0.3 \ --hash=sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67 \ --hash=sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6 \ @@ -970,6 +1106,62 @@ greenlet==3.0.3 \ # via # -r requirements/common.in # sqlalchemy +grpcio==1.64.1 \ + --hash=sha256:03b43d0ccf99c557ec671c7dede64f023c7da9bb632ac65dbc57f166e4970040 \ + --hash=sha256:0a12ddb1678ebc6a84ec6b0487feac020ee2b1659cbe69b80f06dbffdb249122 \ + --hash=sha256:0a2813093ddb27418a4c99f9b1c223fab0b053157176a64cc9db0f4557b69bd9 \ + --hash=sha256:0cc79c982ccb2feec8aad0e8fb0d168bcbca85bc77b080d0d3c5f2f15c24ea8f \ + --hash=sha256:1257b76748612aca0f89beec7fa0615727fd6f2a1ad580a9638816a4b2eb18fd \ + --hash=sha256:1262402af5a511c245c3ae918167eca57342c72320dffae5d9b51840c4b2f86d \ + --hash=sha256:19264fc964576ddb065368cae953f8d0514ecc6cb3da8903766d9fb9d4554c33 \ + --hash=sha256:198908f9b22e2672a998870355e226a725aeab327ac4e6ff3a1399792ece4762 \ + --hash=sha256:1de403fc1305fd96cfa75e83be3dee8538f2413a6b1685b8452301c7ba33c294 \ + --hash=sha256:20405cb8b13fd779135df23fabadc53b86522d0f1cba8cca0e87968587f50650 \ + --hash=sha256:2981c7365a9353f9b5c864595c510c983251b1ab403e05b1ccc70a3d9541a73b \ + --hash=sha256:2c3c1b90ab93fed424e454e93c0ed0b9d552bdf1b0929712b094f5ecfe7a23ad \ + --hash=sha256:39b9d0acaa8d835a6566c640f48b50054f422d03e77e49716d4c4e8e279665a1 \ + --hash=sha256:3b64ae304c175671efdaa7ec9ae2cc36996b681eb63ca39c464958396697daff \ + --hash=sha256:4657d24c8063e6095f850b68f2d1ba3b39f2b287a38242dcabc166453e950c59 \ + --hash=sha256:4d6dab6124225496010bd22690f2d9bd35c7cbb267b3f14e7a3eb05c911325d4 \ + --hash=sha256:55260032b95c49bee69a423c2f5365baa9369d2f7d233e933564d8a47b893027 \ + --hash=sha256:55697ecec192bc3f2f3cc13a295ab670f51de29884ca9ae6cd6247df55df2502 \ + --hash=sha256:5841dd1f284bd1b3d8a6eca3a7f062b06f1eec09b184397e1d1d43447e89a7ae \ + --hash=sha256:58b1041e7c870bb30ee41d3090cbd6f0851f30ae4eb68228955d973d3efa2e61 \ + --hash=sha256:5e42634a989c3aa6049f132266faf6b949ec2a6f7d302dbb5c15395b77d757eb \ + --hash=sha256:5e56462b05a6f860b72f0fa50dca06d5b26543a4e88d0396259a07dc30f4e5aa \ + --hash=sha256:5f8b75f64d5d324c565b263c67dbe4f0af595635bbdd93bb1a88189fc62ed2e5 \ + --hash=sha256:62b4e6eb7bf901719fce0ca83e3ed474ae5022bb3827b0a501e056458c51c0a1 \ + --hash=sha256:6503b64c8b2dfad299749cad1b595c650c91e5b2c8a1b775380fcf8d2cbba1e9 \ + --hash=sha256:6c024ffc22d6dc59000faf8ad781696d81e8e38f4078cb0f2630b4a3cf231a90 \ + --hash=sha256:73819689c169417a4f978e562d24f2def2be75739c4bed1992435d007819da1b \ + --hash=sha256:75dbbf415026d2862192fe1b28d71f209e2fd87079d98470db90bebe57b33179 \ + --hash=sha256:8caee47e970b92b3dd948371230fcceb80d3f2277b3bf7fbd7c0564e7d39068e \ + --hash=sha256:8d51dd1c59d5fa0f34266b80a3805ec29a1f26425c2a54736133f6d87fc4968a \ + --hash=sha256:940e3ec884520155f68a3b712d045e077d61c520a195d1a5932c531f11883489 \ + --hash=sha256:a011ac6c03cfe162ff2b727bcb530567826cec85eb8d4ad2bfb4bd023287a52d \ + --hash=sha256:a3a035c37ce7565b8f4f35ff683a4db34d24e53dc487e47438e434eb3f701b2a \ + --hash=sha256:a5e771d0252e871ce194d0fdcafd13971f1aae0ddacc5f25615030d5df55c3a2 \ + --hash=sha256:ac15b6c2c80a4d1338b04d42a02d376a53395ddf0ec9ab157cbaf44191f3ffdd \ + --hash=sha256:b1a82e0b9b3022799c336e1fc0f6210adc019ae84efb7321d668129d28ee1efb \ + --hash=sha256:bac71b4b28bc9af61efcdc7630b166440bbfbaa80940c9a697271b5e1dabbc61 \ + --hash=sha256:bbc5b1d78a7822b0a84c6f8917faa986c1a744e65d762ef6d8be9d75677af2ca \ + --hash=sha256:c1a786ac592b47573a5bb7e35665c08064a5d77ab88a076eec11f8ae86b3e3f6 \ + --hash=sha256:c84ad903d0d94311a2b7eea608da163dace97c5fe9412ea311e72c3684925602 \ + --hash=sha256:d4d29cc612e1332237877dfa7fe687157973aab1d63bd0f84cf06692f04c0367 \ + --hash=sha256:e3d9f8d1221baa0ced7ec7322a981e28deb23749c76eeeb3d33e18b72935ab62 \ + --hash=sha256:e7cd5c1325f6808b8ae31657d281aadb2a51ac11ab081ae335f4f7fc44c1721d \ + --hash=sha256:ed6091fa0adcc7e4ff944090cf203a52da35c37a130efa564ded02b7aff63bcd \ + --hash=sha256:ee73a2f5ca4ba44fa33b4d7d2c71e2c8a9e9f78d53f6507ad68e7d2ad5f64a22 \ + --hash=sha256:f10193c69fc9d3d726e83bbf0f3d316f1847c3071c8c93d8090cf5f326b14309 + # via + # google-api-core + # grpcio-status +grpcio-status==1.62.2 \ + --hash=sha256:206ddf0eb36bc99b033f03b2c8e95d319f0044defae9b41ae21408e7e0cda48f \ + --hash=sha256:62e1bfcb02025a1cd73732a2d33672d3e9d0df4d21c12c51e0bbcaf09bab742a + # via + # -r requirements/common.in + # google-api-core h2==4.1.0 \ --hash=sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d \ --hash=sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb @@ -987,6 +1179,12 @@ html5lib==1.1 \ --hash=sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d \ --hash=sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f # via talon-core +httplib2==0.22.0 \ + --hash=sha256:14ae0a53c1ba8f3d37e9e27cf37eabb0fb9980f435ba405d546948b009dd64dc \ + --hash=sha256:d7a10bc5ef5ab08322488bde8c726eeee5c8618723fdb399597ec58f3d82df81 + # via + # google-api-python-client + # google-auth-httplib2 hyperframe==6.0.1 \ --hash=sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15 \ --hash=sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914 @@ -1466,6 +1664,64 @@ moto[s3]==5.0.9 \ --hash=sha256:21a13e02f83d6a18cfcd99949c96abb2e889f4bd51c4c6a3ecc8b78765cb854e \ --hash=sha256:eb71f1cba01c70fff1f16086acb24d6d9aeb32830d646d8989f98a29aeae24ba # via -r requirements/dev.in +msgpack==1.0.8 \ + --hash=sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982 \ + --hash=sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3 \ + --hash=sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40 \ + --hash=sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee \ + --hash=sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693 \ + --hash=sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950 \ + --hash=sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151 \ + --hash=sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24 \ + --hash=sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305 \ + --hash=sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b \ + --hash=sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c \ + --hash=sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659 \ + --hash=sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d \ + --hash=sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18 \ + --hash=sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746 \ + --hash=sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868 \ + --hash=sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2 \ + --hash=sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba \ + --hash=sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228 \ + --hash=sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2 \ + --hash=sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273 \ + --hash=sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c \ + --hash=sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653 \ + --hash=sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a \ + --hash=sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596 \ + --hash=sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd \ + --hash=sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8 \ + --hash=sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa \ + --hash=sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85 \ + --hash=sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc \ + --hash=sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836 \ + --hash=sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3 \ + --hash=sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58 \ + --hash=sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128 \ + --hash=sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db \ + --hash=sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f \ + --hash=sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77 \ + --hash=sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad \ + --hash=sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13 \ + --hash=sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8 \ + --hash=sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b \ + --hash=sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a \ + --hash=sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543 \ + --hash=sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b \ + --hash=sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce \ + --hash=sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d \ + --hash=sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a \ + --hash=sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c \ + --hash=sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f \ + --hash=sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e \ + --hash=sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011 \ + --hash=sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04 \ + --hash=sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480 \ + --hash=sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a \ + --hash=sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d \ + --hash=sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d + # via cachecontrol multidict==6.0.5 \ --hash=sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556 \ --hash=sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c \ @@ -1846,6 +2102,30 @@ protego==0.3.1 \ --hash=sha256:2fbe8e9b7a7dbc5016a932b14c98d236aad4c29290bbe457b8d2779666ef7a41 \ --hash=sha256:e94430d0d25cbbf239bc849d86c5e544fbde531fcccfa059953c7da344a1712c # via scrapy +proto-plus==1.23.0 \ + --hash=sha256:89075171ef11988b3fa157f5dbd8b9cf09d65fffee97e29ce403cd8defba19d2 \ + --hash=sha256:a829c79e619e1cf632de091013a4173deed13a55f326ef84f05af6f50ff4c82c + # via + # google-api-core + # google-cloud-firestore +protobuf==4.25.3 \ + --hash=sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4 \ + --hash=sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8 \ + --hash=sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c \ + --hash=sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d \ + --hash=sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4 \ + --hash=sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa \ + --hash=sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c \ + --hash=sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019 \ + --hash=sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9 \ + --hash=sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c \ + --hash=sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2 + # via + # google-api-core + # google-cloud-firestore + # googleapis-common-protos + # grpcio-status + # proto-plus psutil==5.9.8 \ --hash=sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d \ --hash=sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73 \ @@ -1931,11 +2211,13 @@ pyasn1==0.6.0 \ # via # pyasn1-modules # python-ldap + # rsa # service-identity pyasn1-modules==0.4.0 \ --hash=sha256:831dbcea1b177b28c9baddf4c6d1013c24c3accd14a1873fffaa6a2e905f17b6 \ --hash=sha256:be04f15b66c206eed667e0bb5ab27e2b1855ea54a842e5037738099e8ca4ae0b # via + # google-auth # python-ldap # service-identity pyasyncore==1.0.4 \ @@ -2048,12 +2330,13 @@ pygments==2.18.0 \ pyinotify==0.9.6 \ --hash=sha256:9c998a5d7606ca835065cdabc013ae6c66eb9ea76a00a1e3bc6e0cfe2b4f71f4 # via -r requirements/dev.in -pyjwt==2.8.0 \ +pyjwt[crypto]==2.8.0 \ --hash=sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de \ --hash=sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320 # via # -r requirements/common.in # aioapns + # firebase-admin # social-auth-core # twilio pymongo==4.7.2 \ @@ -2127,6 +2410,10 @@ pyopenssl==24.1.0 \ # via # aioapns # scrapy +pyparsing==3.1.2 \ + --hash=sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad \ + --hash=sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742 + # via httplib2 pypng==0.20220715.0 \ --hash=sha256:4a43e969b8f5aaafb2a415536c1a8ec7e341cd6a3f957fd5b5f32a4cfeed902c \ --hash=sha256:739c433ba96f078315de54c0db975aee537cbc3e1d0ae4ed9aab0ca1e427e2c1 @@ -2163,9 +2450,6 @@ python-digitalocean==1.17.0 \ --hash=sha256:0032168e022e85fca314eb3f8dfaabf82087f2ed40839eb28f1eeeeca5afb1fa \ --hash=sha256:107854fde1aafa21774e8053cf253b04173613c94531f75d5a039ad770562b24 # via -r requirements/dev.in -python-gcm==0.4 \ - --hash=sha256:511c35fc5ae829f7fc3cbdb45c4ec3fda02f85e4fae039864efe82682ccb9c18 - # via -r requirements/common.in python-ldap==3.4.4 \ --hash=sha256:7edb0accec4e037797705f3a05cbf36a9fde50d08c8f67f2aef99a2628fab828 # via @@ -2361,11 +2645,13 @@ requests[security]==2.32.3 \ --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 # via # -r requirements/common.in + # cachecontrol + # google-api-core + # google-cloud-storage # jsonschema-path # moto # pyoembed # python-digitalocean - # python-gcm # python-twitter # requests-file # requests-oauthlib @@ -2505,6 +2791,10 @@ rpds-py==0.18.1 \ # via # jsonschema # referencing +rsa==4.9 \ + --hash=sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7 \ + --hash=sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21 + # via google-auth ruamel.yaml==0.17.40 \ --hash=sha256:6024b986f06765d482b5b07e086cc4b4cd05dd22ddcbc758fa23d54873cf313d \ --hash=sha256:b16b6c3816dff0a93dca12acf5e70afd089fa5acb80604afd1ffa8b465b7722c @@ -3046,6 +3336,10 @@ uri-template==1.3.0 \ --hash=sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7 \ --hash=sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363 # via -r requirements/common.in +uritemplate==4.1.1 \ + --hash=sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0 \ + --hash=sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e + # via google-api-python-client urllib3==2.2.1 \ --hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \ --hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19 diff --git a/requirements/prod.txt b/requirements/prod.txt index 786ce8d274..4ccb545507 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -179,6 +179,14 @@ botocore==1.34.116 \ # via # boto3 # s3transfer +cachecontrol==0.14.0 \ + --hash=sha256:7db1195b41c81f8274a7bbd97c956f44e8348265a1bc7641c37dfebc39f0c938 \ + --hash=sha256:f5bf3f0620c38db2e5122c0726bdebb0d16869de966ea6a2befe92470b740ea0 + # via firebase-admin +cachetools==5.3.3 \ + --hash=sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945 \ + --hash=sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105 + # via google-auth certifi==2024.2.2 \ --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \ --hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1 @@ -376,6 +384,7 @@ cryptography==42.0.7 \ --hash=sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9 # via # -r requirements/common.in + # pyjwt # pyopenssl # social-auth-core css-inline==0.14.1 \ @@ -493,6 +502,10 @@ executing==2.0.1 \ --hash=sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147 \ --hash=sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc # via stack-data +firebase-admin==6.5.0 \ + --hash=sha256:e716dde1447f0a1cd1523be76ff872df33c4e1a3c079564ace033b2ad60bcc4f \ + --hash=sha256:fe34ee3ca0e625c5156b3931ca4b4b69b5fc344dbe51bba9706ff674ce277898 + # via -r requirements/common.in frozenlist==1.4.1 \ --hash=sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7 \ --hash=sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98 \ @@ -578,6 +591,119 @@ future==1.0.0 \ --hash=sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216 \ --hash=sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05 # via python-twitter +google-api-core[grpc]==2.19.0 \ + --hash=sha256:8661eec4078c35428fd3f69a2c7ee29e342896b70f01d1a1cbcb334372dd6251 \ + --hash=sha256:cf1b7c2694047886d2af1128a03ae99e391108a08804f87cfd35970e49c9cd10 + # via + # firebase-admin + # google-api-python-client + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-api-python-client==2.133.0 \ + --hash=sha256:293092905b66a046d3187a99ac454e12b00cc2c70444f26eb2f1f9c1a82720b4 \ + --hash=sha256:396fe676ea0dfed066654dcf9f8dea77a1342f9d9bb23bb88e45b7b81e773926 + # via firebase-admin +google-auth==2.30.0 \ + --hash=sha256:8df7da660f62757388b8a7f249df13549b3373f24388cb5d2f1dd91cc18180b5 \ + --hash=sha256:ab630a1320f6720909ad76a7dbdb6841cdf5c66b328d690027e4867bdfb16688 + # via + # google-api-core + # google-api-python-client + # google-auth-httplib2 + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-auth-httplib2==0.2.0 \ + --hash=sha256:38aa7badf48f974f1eb9861794e9c0cb2a0511a4ec0679b1f886d108f5640e05 \ + --hash=sha256:b65a0a2123300dd71281a7bf6e64d65a0759287df52729bdd1ae2e47dc311a3d + # via google-api-python-client +google-cloud-core==2.4.1 \ + --hash=sha256:9b7749272a812bde58fff28868d0c5e2f585b82f37e09a1f6ed2d4d10f134073 \ + --hash=sha256:a9e6a4422b9ac5c29f79a0ede9485473338e2ce78d91f2370c01e730eab22e61 + # via + # google-cloud-firestore + # google-cloud-storage +google-cloud-firestore==2.16.0 \ + --hash=sha256:3347ac38346c2702134d4c81f652a5e3451c840a6237f28b844501bd528e5fd8 \ + --hash=sha256:e61ae70229a6e532e439c8d16447a32024447f2ee4a2303fc4d054c258d6877f + # via firebase-admin +google-cloud-storage==2.17.0 \ + --hash=sha256:49378abff54ef656b52dca5ef0f2eba9aa83dc2b2c72c78714b03a1a95fe9388 \ + --hash=sha256:5b393bc766b7a3bc6f5407b9e665b2450d36282614b7945e570b3480a456d1e1 + # via firebase-admin +google-crc32c==1.5.0 \ + --hash=sha256:024894d9d3cfbc5943f8f230e23950cd4906b2fe004c72e29b209420a1e6b05a \ + --hash=sha256:02c65b9817512edc6a4ae7c7e987fea799d2e0ee40c53ec573a692bee24de876 \ + --hash=sha256:02ebb8bf46c13e36998aeaad1de9b48f4caf545e91d14041270d9dca767b780c \ + --hash=sha256:07eb3c611ce363c51a933bf6bd7f8e3878a51d124acfc89452a75120bc436289 \ + --hash=sha256:1034d91442ead5a95b5aaef90dbfaca8633b0247d1e41621d1e9f9db88c36298 \ + --hash=sha256:116a7c3c616dd14a3de8c64a965828b197e5f2d121fedd2f8c5585c547e87b02 \ + --hash=sha256:19e0a019d2c4dcc5e598cd4a4bc7b008546b0358bd322537c74ad47a5386884f \ + --hash=sha256:1c7abdac90433b09bad6c43a43af253e688c9cfc1c86d332aed13f9a7c7f65e2 \ + --hash=sha256:1e986b206dae4476f41bcec1faa057851f3889503a70e1bdb2378d406223994a \ + --hash=sha256:272d3892a1e1a2dbc39cc5cde96834c236d5327e2122d3aaa19f6614531bb6eb \ + --hash=sha256:278d2ed7c16cfc075c91378c4f47924c0625f5fc84b2d50d921b18b7975bd210 \ + --hash=sha256:2ad40e31093a4af319dadf503b2467ccdc8f67c72e4bcba97f8c10cb078207b5 \ + --hash=sha256:2e920d506ec85eb4ba50cd4228c2bec05642894d4c73c59b3a2fe20346bd00ee \ + --hash=sha256:3359fc442a743e870f4588fcf5dcbc1bf929df1fad8fb9905cd94e5edb02e84c \ + --hash=sha256:37933ec6e693e51a5b07505bd05de57eee12f3e8c32b07da7e73669398e6630a \ + --hash=sha256:398af5e3ba9cf768787eef45c803ff9614cc3e22a5b2f7d7ae116df8b11e3314 \ + --hash=sha256:3b747a674c20a67343cb61d43fdd9207ce5da6a99f629c6e2541aa0e89215bcd \ + --hash=sha256:461665ff58895f508e2866824a47bdee72497b091c730071f2b7575d5762ab65 \ + --hash=sha256:4c6fdd4fccbec90cc8a01fc00773fcd5fa28db683c116ee3cb35cd5da9ef6c37 \ + --hash=sha256:5829b792bf5822fd0a6f6eb34c5f81dd074f01d570ed7f36aa101d6fc7a0a6e4 \ + --hash=sha256:596d1f98fc70232fcb6590c439f43b350cb762fb5d61ce7b0e9db4539654cc13 \ + --hash=sha256:5ae44e10a8e3407dbe138984f21e536583f2bba1be9491239f942c2464ac0894 \ + --hash=sha256:635f5d4dd18758a1fbd1049a8e8d2fee4ffed124462d837d1a02a0e009c3ab31 \ + --hash=sha256:64e52e2b3970bd891309c113b54cf0e4384762c934d5ae56e283f9a0afcd953e \ + --hash=sha256:66741ef4ee08ea0b2cc3c86916ab66b6aef03768525627fd6a1b34968b4e3709 \ + --hash=sha256:67b741654b851abafb7bc625b6d1cdd520a379074e64b6a128e3b688c3c04740 \ + --hash=sha256:6ac08d24c1f16bd2bf5eca8eaf8304812f44af5cfe5062006ec676e7e1d50afc \ + --hash=sha256:6f998db4e71b645350b9ac28a2167e6632c239963ca9da411523bb439c5c514d \ + --hash=sha256:72218785ce41b9cfd2fc1d6a017dc1ff7acfc4c17d01053265c41a2c0cc39b8c \ + --hash=sha256:74dea7751d98034887dbd821b7aae3e1d36eda111d6ca36c206c44478035709c \ + --hash=sha256:759ce4851a4bb15ecabae28f4d2e18983c244eddd767f560165563bf9aefbc8d \ + --hash=sha256:77e2fd3057c9d78e225fa0a2160f96b64a824de17840351b26825b0848022906 \ + --hash=sha256:7c074fece789b5034b9b1404a1f8208fc2d4c6ce9decdd16e8220c5a793e6f61 \ + --hash=sha256:7c42c70cd1d362284289c6273adda4c6af8039a8ae12dc451dcd61cdabb8ab57 \ + --hash=sha256:7f57f14606cd1dd0f0de396e1e53824c371e9544a822648cd76c034d209b559c \ + --hash=sha256:83c681c526a3439b5cf94f7420471705bbf96262f49a6fe546a6db5f687a3d4a \ + --hash=sha256:8485b340a6a9e76c62a7dce3c98e5f102c9219f4cfbf896a00cf48caf078d438 \ + --hash=sha256:84e6e8cd997930fc66d5bb4fde61e2b62ba19d62b7abd7a69920406f9ecca946 \ + --hash=sha256:89284716bc6a5a415d4eaa11b1726d2d60a0cd12aadf5439828353662ede9dd7 \ + --hash=sha256:8b87e1a59c38f275c0e3676fc2ab6d59eccecfd460be267ac360cc31f7bcde96 \ + --hash=sha256:8f24ed114432de109aa9fd317278518a5af2d31ac2ea6b952b2f7782b43da091 \ + --hash=sha256:98cb4d057f285bd80d8778ebc4fde6b4d509ac3f331758fb1528b733215443ae \ + --hash=sha256:998679bf62b7fb599d2878aa3ed06b9ce688b8974893e7223c60db155f26bd8d \ + --hash=sha256:9ba053c5f50430a3fcfd36f75aff9caeba0440b2d076afdb79a318d6ca245f88 \ + --hash=sha256:9c99616c853bb585301df6de07ca2cadad344fd1ada6d62bb30aec05219c45d2 \ + --hash=sha256:a1fd716e7a01f8e717490fbe2e431d2905ab8aa598b9b12f8d10abebb36b04dd \ + --hash=sha256:a2355cba1f4ad8b6988a4ca3feed5bff33f6af2d7f134852cf279c2aebfde541 \ + --hash=sha256:b1f8133c9a275df5613a451e73f36c2aea4fe13c5c8997e22cf355ebd7bd0728 \ + --hash=sha256:b8667b48e7a7ef66afba2c81e1094ef526388d35b873966d8a9a447974ed9178 \ + --hash=sha256:ba1eb1843304b1e5537e1fca632fa894d6f6deca8d6389636ee5b4797affb968 \ + --hash=sha256:be82c3c8cfb15b30f36768797a640e800513793d6ae1724aaaafe5bf86f8f346 \ + --hash=sha256:c02ec1c5856179f171e032a31d6f8bf84e5a75c45c33b2e20a3de353b266ebd8 \ + --hash=sha256:c672d99a345849301784604bfeaeba4db0c7aae50b95be04dd651fd2a7310b93 \ + --hash=sha256:c6c777a480337ac14f38564ac88ae82d4cd238bf293f0a22295b66eb89ffced7 \ + --hash=sha256:cae0274952c079886567f3f4f685bcaf5708f0a23a5f5216fdab71f81a6c0273 \ + --hash=sha256:cd67cf24a553339d5062eff51013780a00d6f97a39ca062781d06b3a73b15462 \ + --hash=sha256:d3515f198eaa2f0ed49f8819d5732d70698c3fa37384146079b3799b97667a94 \ + --hash=sha256:d5280312b9af0976231f9e317c20e4a61cd2f9629b7bfea6a693d1878a264ebd \ + --hash=sha256:de06adc872bcd8c2a4e0dc51250e9e65ef2ca91be023b9d13ebd67c2ba552e1e \ + --hash=sha256:e1674e4307fa3024fc897ca774e9c7562c957af85df55efe2988ed9056dc4e57 \ + --hash=sha256:e2096eddb4e7c7bdae4bd69ad364e55e07b8316653234a56552d9c988bd2d61b \ + --hash=sha256:e560628513ed34759456a416bf86b54b2476c59144a9138165c9a1575801d0d9 \ + --hash=sha256:edfedb64740750e1a3b16152620220f51d58ff1b4abceb339ca92e934775c27a \ + --hash=sha256:f13cae8cc389a440def0c8c52057f37359014ccbc9dc1f0827936bcd367c6100 \ + --hash=sha256:f314013e7dcd5cf45ab1945d92e713eec788166262ae8deb2cfacd53def27325 \ + --hash=sha256:f583edb943cf2e09c60441b910d6a20b4d9d626c75a36c8fcac01a6c96c01183 \ + --hash=sha256:fd8536e902db7e365f49e7d9029283403974ccf29b13fc7028b97e2295b33556 \ + --hash=sha256:fe70e325aa68fa4b5edf7d1a4b6f691eb04bbccac0ace68e34820d283b5f80d4 + # via + # google-cloud-storage + # google-resumable-media google-re2==1.1.20240601 \ --hash=sha256:0013ddbbae8d42bd8ab42213c5da3741630eae98b6eca816d72bc77fdda3d356 \ --hash=sha256:01297cbe44df033adec9d21a2241a7b50efb77bce625f196bf33bc0a87d6906d \ @@ -694,6 +820,16 @@ google-re2==1.1.20240601 \ --hash=sha256:f9ed2a0e92ed79f944d836c533e69ca6e3e9dd85ac7af6f7adf715ee9793e28b \ --hash=sha256:fb495ac61628b0c8747cb3d4deb0d941f081bcf3d913083475fafd0a4d826582 # via -r requirements/common.in +google-resumable-media==2.7.1 \ + --hash=sha256:103ebc4ba331ab1bfdac0250f8033627a2cd7cde09e7ccff9181e31ba4315b2c \ + --hash=sha256:eae451a7b2e2cdbaaa0fd2eb00cc8a1ee5e95e16b55597359cbc3d27d7d90e33 + # via google-cloud-storage +googleapis-common-protos==1.63.1 \ + --hash=sha256:0e1c2cdfcbc354b76e4a211a35ea35d6926a835cba1377073c4861db904a1877 \ + --hash=sha256:c6442f7a0a6b2a80369457d79e6672bb7dcbaab88e0848302497e3ec80780a6a + # via + # google-api-core + # grpcio-status greenlet==3.0.3 \ --hash=sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67 \ --hash=sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6 \ @@ -756,6 +892,62 @@ greenlet==3.0.3 \ # via # -r requirements/common.in # sqlalchemy +grpcio==1.64.1 \ + --hash=sha256:03b43d0ccf99c557ec671c7dede64f023c7da9bb632ac65dbc57f166e4970040 \ + --hash=sha256:0a12ddb1678ebc6a84ec6b0487feac020ee2b1659cbe69b80f06dbffdb249122 \ + --hash=sha256:0a2813093ddb27418a4c99f9b1c223fab0b053157176a64cc9db0f4557b69bd9 \ + --hash=sha256:0cc79c982ccb2feec8aad0e8fb0d168bcbca85bc77b080d0d3c5f2f15c24ea8f \ + --hash=sha256:1257b76748612aca0f89beec7fa0615727fd6f2a1ad580a9638816a4b2eb18fd \ + --hash=sha256:1262402af5a511c245c3ae918167eca57342c72320dffae5d9b51840c4b2f86d \ + --hash=sha256:19264fc964576ddb065368cae953f8d0514ecc6cb3da8903766d9fb9d4554c33 \ + --hash=sha256:198908f9b22e2672a998870355e226a725aeab327ac4e6ff3a1399792ece4762 \ + --hash=sha256:1de403fc1305fd96cfa75e83be3dee8538f2413a6b1685b8452301c7ba33c294 \ + --hash=sha256:20405cb8b13fd779135df23fabadc53b86522d0f1cba8cca0e87968587f50650 \ + --hash=sha256:2981c7365a9353f9b5c864595c510c983251b1ab403e05b1ccc70a3d9541a73b \ + --hash=sha256:2c3c1b90ab93fed424e454e93c0ed0b9d552bdf1b0929712b094f5ecfe7a23ad \ + --hash=sha256:39b9d0acaa8d835a6566c640f48b50054f422d03e77e49716d4c4e8e279665a1 \ + --hash=sha256:3b64ae304c175671efdaa7ec9ae2cc36996b681eb63ca39c464958396697daff \ + --hash=sha256:4657d24c8063e6095f850b68f2d1ba3b39f2b287a38242dcabc166453e950c59 \ + --hash=sha256:4d6dab6124225496010bd22690f2d9bd35c7cbb267b3f14e7a3eb05c911325d4 \ + --hash=sha256:55260032b95c49bee69a423c2f5365baa9369d2f7d233e933564d8a47b893027 \ + --hash=sha256:55697ecec192bc3f2f3cc13a295ab670f51de29884ca9ae6cd6247df55df2502 \ + --hash=sha256:5841dd1f284bd1b3d8a6eca3a7f062b06f1eec09b184397e1d1d43447e89a7ae \ + --hash=sha256:58b1041e7c870bb30ee41d3090cbd6f0851f30ae4eb68228955d973d3efa2e61 \ + --hash=sha256:5e42634a989c3aa6049f132266faf6b949ec2a6f7d302dbb5c15395b77d757eb \ + --hash=sha256:5e56462b05a6f860b72f0fa50dca06d5b26543a4e88d0396259a07dc30f4e5aa \ + --hash=sha256:5f8b75f64d5d324c565b263c67dbe4f0af595635bbdd93bb1a88189fc62ed2e5 \ + --hash=sha256:62b4e6eb7bf901719fce0ca83e3ed474ae5022bb3827b0a501e056458c51c0a1 \ + --hash=sha256:6503b64c8b2dfad299749cad1b595c650c91e5b2c8a1b775380fcf8d2cbba1e9 \ + --hash=sha256:6c024ffc22d6dc59000faf8ad781696d81e8e38f4078cb0f2630b4a3cf231a90 \ + --hash=sha256:73819689c169417a4f978e562d24f2def2be75739c4bed1992435d007819da1b \ + --hash=sha256:75dbbf415026d2862192fe1b28d71f209e2fd87079d98470db90bebe57b33179 \ + --hash=sha256:8caee47e970b92b3dd948371230fcceb80d3f2277b3bf7fbd7c0564e7d39068e \ + --hash=sha256:8d51dd1c59d5fa0f34266b80a3805ec29a1f26425c2a54736133f6d87fc4968a \ + --hash=sha256:940e3ec884520155f68a3b712d045e077d61c520a195d1a5932c531f11883489 \ + --hash=sha256:a011ac6c03cfe162ff2b727bcb530567826cec85eb8d4ad2bfb4bd023287a52d \ + --hash=sha256:a3a035c37ce7565b8f4f35ff683a4db34d24e53dc487e47438e434eb3f701b2a \ + --hash=sha256:a5e771d0252e871ce194d0fdcafd13971f1aae0ddacc5f25615030d5df55c3a2 \ + --hash=sha256:ac15b6c2c80a4d1338b04d42a02d376a53395ddf0ec9ab157cbaf44191f3ffdd \ + --hash=sha256:b1a82e0b9b3022799c336e1fc0f6210adc019ae84efb7321d668129d28ee1efb \ + --hash=sha256:bac71b4b28bc9af61efcdc7630b166440bbfbaa80940c9a697271b5e1dabbc61 \ + --hash=sha256:bbc5b1d78a7822b0a84c6f8917faa986c1a744e65d762ef6d8be9d75677af2ca \ + --hash=sha256:c1a786ac592b47573a5bb7e35665c08064a5d77ab88a076eec11f8ae86b3e3f6 \ + --hash=sha256:c84ad903d0d94311a2b7eea608da163dace97c5fe9412ea311e72c3684925602 \ + --hash=sha256:d4d29cc612e1332237877dfa7fe687157973aab1d63bd0f84cf06692f04c0367 \ + --hash=sha256:e3d9f8d1221baa0ced7ec7322a981e28deb23749c76eeeb3d33e18b72935ab62 \ + --hash=sha256:e7cd5c1325f6808b8ae31657d281aadb2a51ac11ab081ae335f4f7fc44c1721d \ + --hash=sha256:ed6091fa0adcc7e4ff944090cf203a52da35c37a130efa564ded02b7aff63bcd \ + --hash=sha256:ee73a2f5ca4ba44fa33b4d7d2c71e2c8a9e9f78d53f6507ad68e7d2ad5f64a22 \ + --hash=sha256:f10193c69fc9d3d726e83bbf0f3d316f1847c3071c8c93d8090cf5f326b14309 + # via + # google-api-core + # grpcio-status +grpcio-status==1.62.2 \ + --hash=sha256:206ddf0eb36bc99b033f03b2c8e95d319f0044defae9b41ae21408e7e0cda48f \ + --hash=sha256:62e1bfcb02025a1cd73732a2d33672d3e9d0df4d21c12c51e0bbcaf09bab742a + # via + # -r requirements/common.in + # google-api-core h2==4.1.0 \ --hash=sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d \ --hash=sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb @@ -773,6 +965,12 @@ html5lib==1.1 \ --hash=sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d \ --hash=sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f # via talon-core +httplib2==0.22.0 \ + --hash=sha256:14ae0a53c1ba8f3d37e9e27cf37eabb0fb9980f435ba405d546948b009dd64dc \ + --hash=sha256:d7a10bc5ef5ab08322488bde8c726eeee5c8618723fdb399597ec58f3d82df81 + # via + # google-api-python-client + # google-auth-httplib2 hyperframe==6.0.1 \ --hash=sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15 \ --hash=sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914 @@ -1103,6 +1301,64 @@ more-itertools==10.2.0 \ --hash=sha256:686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684 \ --hash=sha256:8fccb480c43d3e99a00087634c06dd02b0d50fbf088b380de5a41a015ec239e1 # via openapi-core +msgpack==1.0.8 \ + --hash=sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982 \ + --hash=sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3 \ + --hash=sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40 \ + --hash=sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee \ + --hash=sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693 \ + --hash=sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950 \ + --hash=sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151 \ + --hash=sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24 \ + --hash=sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305 \ + --hash=sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b \ + --hash=sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c \ + --hash=sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659 \ + --hash=sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d \ + --hash=sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18 \ + --hash=sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746 \ + --hash=sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868 \ + --hash=sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2 \ + --hash=sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba \ + --hash=sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228 \ + --hash=sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2 \ + --hash=sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273 \ + --hash=sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c \ + --hash=sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653 \ + --hash=sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a \ + --hash=sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596 \ + --hash=sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd \ + --hash=sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8 \ + --hash=sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa \ + --hash=sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85 \ + --hash=sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc \ + --hash=sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836 \ + --hash=sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3 \ + --hash=sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58 \ + --hash=sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128 \ + --hash=sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db \ + --hash=sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f \ + --hash=sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77 \ + --hash=sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad \ + --hash=sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13 \ + --hash=sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8 \ + --hash=sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b \ + --hash=sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a \ + --hash=sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543 \ + --hash=sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b \ + --hash=sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce \ + --hash=sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d \ + --hash=sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a \ + --hash=sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c \ + --hash=sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f \ + --hash=sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e \ + --hash=sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011 \ + --hash=sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04 \ + --hash=sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480 \ + --hash=sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a \ + --hash=sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d \ + --hash=sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d + # via cachecontrol multidict==6.0.5 \ --hash=sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556 \ --hash=sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c \ @@ -1388,6 +1644,30 @@ prompt-toolkit==3.0.45 \ --hash=sha256:07c60ee4ab7b7e90824b61afa840c8f5aad2d46b3e2e10acc33d8ecc94a49089 \ --hash=sha256:a29b89160e494e3ea8622b09fa5897610b437884dcdcd054fdc1308883326c2a # via ipython +proto-plus==1.23.0 \ + --hash=sha256:89075171ef11988b3fa157f5dbd8b9cf09d65fffee97e29ce403cd8defba19d2 \ + --hash=sha256:a829c79e619e1cf632de091013a4173deed13a55f326ef84f05af6f50ff4c82c + # via + # google-api-core + # google-cloud-firestore +protobuf==4.25.3 \ + --hash=sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4 \ + --hash=sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8 \ + --hash=sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c \ + --hash=sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d \ + --hash=sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4 \ + --hash=sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa \ + --hash=sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c \ + --hash=sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019 \ + --hash=sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9 \ + --hash=sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c \ + --hash=sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2 + # via + # google-api-core + # google-cloud-firestore + # googleapis-common-protos + # grpcio-status + # proto-plus psycopg2==2.9.9 \ --hash=sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981 \ --hash=sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516 \ @@ -1449,10 +1729,13 @@ pyasn1==0.6.0 \ # via # pyasn1-modules # python-ldap + # rsa pyasn1-modules==0.4.0 \ --hash=sha256:831dbcea1b177b28c9baddf4c6d1013c24c3accd14a1873fffaa6a2e905f17b6 \ --hash=sha256:be04f15b66c206eed667e0bb5ab27e2b1855ea54a842e5037738099e8ca4ae0b - # via python-ldap + # via + # google-auth + # python-ldap pycparser==2.22 \ --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \ --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc @@ -1549,12 +1832,13 @@ pygments==2.18.0 \ # -r requirements/common.in # ipython # jsx-lexer -pyjwt==2.8.0 \ +pyjwt[crypto]==2.8.0 \ --hash=sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de \ --hash=sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320 # via # -r requirements/common.in # aioapns + # firebase-admin # social-auth-core # twilio pymongo==4.7.2 \ @@ -1626,6 +1910,10 @@ pyopenssl==24.1.0 \ --hash=sha256:17ed5be5936449c5418d1cd269a1a9e9081bc54c17aed272b45856a3d3dc86ad \ --hash=sha256:cabed4bfaa5df9f1a16c0ef64a0cb65318b5cd077a7eda7d6970131ca2f41a6f # via aioapns +pyparsing==3.1.2 \ + --hash=sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad \ + --hash=sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742 + # via httplib2 pypng==0.20220715.0 \ --hash=sha256:4a43e969b8f5aaafb2a415536c1a8ec7e341cd6a3f957fd5b5f32a4cfeed902c \ --hash=sha256:739c433ba96f078315de54c0db975aee537cbc3e1d0ae4ed9aab0ca1e427e2c1 @@ -1642,9 +1930,6 @@ python-dateutil==2.9.0.post0 \ # via # -r requirements/common.in # botocore -python-gcm==0.4 \ - --hash=sha256:511c35fc5ae829f7fc3cbdb45c4ec3fda02f85e4fae039864efe82682ccb9c18 - # via -r requirements/common.in python-ldap==3.4.4 \ --hash=sha256:7edb0accec4e037797705f3a05cbf36a9fde50d08c8f67f2aef99a2628fab828 # via @@ -1829,9 +2114,11 @@ requests[security]==2.32.3 \ --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 # via # -r requirements/common.in + # cachecontrol + # google-api-core + # google-cloud-storage # jsonschema-path # pyoembed - # python-gcm # python-twitter # requests-oauthlib # social-auth-core @@ -1952,6 +2239,10 @@ rpds-py==0.18.1 \ # via # jsonschema # referencing +rsa==4.9 \ + --hash=sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7 \ + --hash=sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21 + # via google-auth s3transfer==0.10.1 \ --hash=sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19 \ --hash=sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d @@ -2110,6 +2401,10 @@ uri-template==1.3.0 \ --hash=sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7 \ --hash=sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363 # via -r requirements/common.in +uritemplate==4.1.1 \ + --hash=sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0 \ + --hash=sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e + # via google-api-python-client urllib3==2.2.1 \ --hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \ --hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19 diff --git a/version.py b/version.py index 8e259142b8..32010719b3 100644 --- a/version.py +++ b/version.py @@ -48,4 +48,4 @@ API_FEATURE_LEVEL = 265 # historical commits sharing the same major version, in which case a # minor version bump suffices. -PROVISION_VERSION = (280, 2) # bumped 2024-06-03 for adding confusing-browser-globals +PROVISION_VERSION = (281, 0) # bumped 2024-06-12 for adding firebase-admin diff --git a/zerver/lib/push_notifications.py b/zerver/lib/push_notifications.py index 6a821e1e26..a7ed15b469 100644 --- a/zerver/lib/push_notifications.py +++ b/zerver/lib/push_notifications.py @@ -22,7 +22,6 @@ from typing import ( Union, ) -import gcm import lxml.html import orjson from django.conf import settings @@ -31,6 +30,12 @@ from django.db.models import F, Q from django.utils.timezone import now as timezone_now from django.utils.translation import gettext as _ from django.utils.translation import override as override_language +from firebase_admin import App as FCMApp +from firebase_admin import credentials as firebase_credentials +from firebase_admin import exceptions as firebase_exceptions +from firebase_admin import initialize_app as firebase_initialize_app +from firebase_admin import messaging as firebase_messaging +from firebase_admin.messaging import UnregisteredError as FCMUnregisteredError from typing_extensions import TypeAlias, override from analytics.lib.counts import COUNT_STATS, do_increment_logging_stat @@ -44,7 +49,6 @@ from zerver.lib.emoji_utils import hex_codepoint_to_emoji from zerver.lib.exceptions import ErrorCode, JsonableError from zerver.lib.message import access_message_and_usermessage, huddle_users from zerver.lib.notification_data import get_mentioned_user_group -from zerver.lib.outgoing_http import OutgoingSession from zerver.lib.remote_server import ( record_push_notifications_recently_working, send_json_to_push_bouncer, @@ -358,38 +362,30 @@ def send_apple_push_notification( # -class FCMSession(OutgoingSession): - def __init__(self) -> None: - # We don't set up retries, since the gcm package does that for us. - super().__init__(role="fcm", timeout=5) +# Note: This is a timeout value per retry, not a total timeout. +FCM_REQUEST_TIMEOUT = 5 -def make_gcm_client() -> gcm.GCM: # nocoverage - # From GCM upstream's doc for migrating to FCM: - # - # FCM supports HTTP and XMPP protocols that are virtually - # identical to the GCM server protocols, so you don't need to - # update your sending logic for the migration. - # - # https://developers.google.com/cloud-messaging/android/android-migrate-fcm - # - # The one thing we're required to change on the server is the URL of - # the endpoint. So we get to keep using the GCM client library we've - # been using (as long as we're happy with it) -- just monkey-patch in - # that one change, because the library's API doesn't anticipate that - # as a customization point. - gcm.gcm.GCM_URL = "https://fcm.googleapis.com/fcm/send" - return gcm.GCM(settings.ANDROID_GCM_API_KEY) +def make_fcm_app() -> FCMApp: # nocoverage + if settings.ANDROID_FCM_CREDENTIALS_PATH is None: + return None + + fcm_credentials = firebase_credentials.Certificate(settings.ANDROID_FCM_CREDENTIALS_PATH) + fcm_app = firebase_initialize_app( + fcm_credentials, options=dict(httpTimeout=FCM_REQUEST_TIMEOUT) + ) + + return fcm_app -if settings.ANDROID_GCM_API_KEY: # nocoverage - gcm_client = make_gcm_client() +if settings.ANDROID_FCM_CREDENTIALS_PATH: # nocoverage + fcm_app = make_fcm_app() else: - gcm_client = None + fcm_app = None def has_fcm_credentials() -> bool: # nocoverage - return gcm_client is not None + return fcm_app is not None # This is purely used in testing @@ -416,7 +412,7 @@ def parse_fcm_options(options: Dict[str, Any], data: Dict[str, Any]) -> str: Including unrecognized options is an error. For details on options' semantics, see this FCM upstream doc: - https://firebase.google.com/docs/cloud-messaging/http-server-ref + https://firebase.google.com/docs/cloud-messaging/android/message-priority Returns `priority`. """ @@ -467,51 +463,44 @@ def send_android_push_notification( """ if not devices: return 0 - if not gcm_client: + if not fcm_app: logger.debug( - "Skipping sending a GCM push notification since " - "PUSH_NOTIFICATION_BOUNCER_URL and ANDROID_GCM_API_KEY are both unset" + "Skipping sending a FCM push notification since " + "PUSH_NOTIFICATION_BOUNCER_URL and ANDROID_FCM_CREDENTIALS_PATH are both unset" ) return 0 if remote: logger.info( - "GCM: Sending notification for remote user %s:%s to %d devices", + "FCM: Sending notification for remote user %s:%s to %d devices", remote.uuid, user_identity, len(devices), ) else: logger.info( - "GCM: Sending notification for local user %s to %d devices", user_identity, len(devices) + "FCM: Sending notification for local user %s to %d devices", user_identity, len(devices) ) - reg_ids = [device.token for device in devices] - priority = parse_fcm_options(options, data) - try: - # See https://firebase.google.com/docs/cloud-messaging/http-server-ref . - # Two kwargs `retries` and `session` get eaten by `json_request`; - # the rest pass through to the FCM server. - # - # One initial request plus 2 retries, with 5-second timeouts, - # and expected 1 + 2 seconds (the gcm module jitters its - # backoff by ±50%, so worst case * 1.5) between them, totals - # 18s expected, up to 19.5s worst case. - res = gcm_client.json_request( - registration_ids=reg_ids, - priority=priority, - data=data, - retries=2, - session=FCMSession(), - ) - except OSError: - logger.warning("Error while pushing to GCM", exc_info=True) - return 0 - successfully_sent_count = 0 - if res and "success" in res: - for reg_id, msg_id in res["success"].items(): - logger.info("GCM: Sent %s as %s", reg_id, msg_id) - successfully_sent_count = len(res["success"].keys()) + token_list = [device.token for device in devices] + priority = parse_fcm_options(options, data) + + # The API requires all values to be strings. Our data dict is going to have + # things like an integer realm and user ids etc., so just convert everything + # like that. + data = {k: str(v) if not isinstance(v, str) else v for k, v in data.items()} + messages = [ + firebase_messaging.Message( + data=data, token=token, android=firebase_messaging.AndroidConfig(priority=priority) + ) + for token in token_list + ] + + try: + batch_response = firebase_messaging.send_each(messages, app=fcm_app) + except firebase_exceptions.FirebaseError: + logger.warning("Error while pushing to FCM", exc_info=True) + return 0 if remote: assert settings.ZILENCER_ENABLED @@ -519,25 +508,31 @@ def send_android_push_notification( else: DeviceTokenClass = PushDeviceToken - if "errors" in res: - for error, reg_ids in res["errors"].items(): - if error in ["NotRegistered", "InvalidRegistration"]: - for reg_id in reg_ids: - logger.info("GCM: Removing %s", reg_id) - # We remove all entries for this token (There - # could be multiple for different Zulip servers). - DeviceTokenClass._default_manager.filter( - token=reg_id, kind=DeviceTokenClass.FCM - ).delete() + successfully_sent_count = 0 + for idx, response in enumerate(batch_response.responses): + # We enumerate to have idx to track which token the response + # corresponds to. send_each() preserves the order of the messages, + # so this works. + + token = token_list[idx] + if response.success: + successfully_sent_count += 1 + logger.info("FCM: Sent message with ID: %s to %s", response.message_id, token) + else: + error = response.exception + if isinstance(error, FCMUnregisteredError): + logger.info("FCM: Removing %s due to %s", token, error.code) + + # We remove all entries for this token (There + # could be multiple for different Zulip servers). + DeviceTokenClass._default_manager.filter( + token=token, kind=DeviceTokenClass.FCM + ).delete() else: - for reg_id in reg_ids: - logger.warning("GCM: Delivery to %s failed: %s", reg_id, error) + logger.warning("FCM: Delivery failed for %s: %s:%s", token, error.__class__, error) return successfully_sent_count - # python-gcm handles retrying of the unsent messages. - # Ref: https://github.com/geeknam/python-gcm/blob/master/gcm/gcm.py#L497 - # # Sending to a bouncer diff --git a/zerver/tests/test_push_notifications.py b/zerver/tests/test_push_notifications.py index bc1813f066..0e1da4ada7 100644 --- a/zerver/tests/test_push_notifications.py +++ b/zerver/tests/test_push_notifications.py @@ -8,6 +8,7 @@ from typing import Any, Dict, Iterator, List, Mapping, Optional, Tuple, Union from unittest import mock, skipUnless import aioapns +import firebase_admin.messaging as firebase_messaging import orjson import responses import time_machine @@ -19,6 +20,7 @@ from django.test import override_settings from django.utils.crypto import get_random_string from django.utils.timezone import now from dns.resolver import NoAnswer as DNSNoAnswer +from firebase_admin import exceptions as firebase_exceptions from requests.exceptions import ConnectionError from requests.models import PreparedRequest from typing_extensions import override @@ -2753,6 +2755,13 @@ class PushNotificationTest(BouncerTestCase): server=self.server, ) + @contextmanager + def mock_fcm(self) -> Iterator[Tuple[mock.MagicMock, mock.MagicMock]]: + with mock.patch("zerver.lib.push_notifications.fcm_app") as mock_fcm_app, mock.patch( + "zerver.lib.push_notifications.firebase_messaging" + ) as mock_fcm_messaging: + yield mock_fcm_app, mock_fcm_messaging + def setup_fcm_tokens(self) -> None: self.fcm_tokens = ["1111", "2222"] for token in self.fcm_tokens: @@ -2778,6 +2787,19 @@ class PushNotificationTest(BouncerTestCase): server=self.server, ) + def make_fcm_success_response(self, tokens: List[str]) -> firebase_messaging.BatchResponse: + responses = [ + firebase_messaging.SendResponse(exception=None, resp=dict(name=str(idx))) + for idx, _ in enumerate(tokens) + ] + return firebase_messaging.BatchResponse(responses) + + def make_fcm_error_response( + self, token: str, exception: firebase_exceptions.FirebaseError + ) -> firebase_messaging.BatchResponse: + error_response = firebase_messaging.SendResponse(exception=exception, resp=None) + return firebase_messaging.BatchResponse([error_response]) + class HandlePushNotificationTest(PushNotificationTest): DEFAULT_SUBDOMAIN = "" @@ -2821,9 +2843,10 @@ class HandlePushNotificationTest(PushNotificationTest): "message_id": message.id, "trigger": NotificationTriggers.DIRECT_MESSAGE, } - with time_machine.travel(time_received, tick=False), mock.patch( - "zerver.lib.push_notifications.gcm_client" - ) as mock_gcm, self.mock_apns() as (apns_context, send_notification), mock.patch( + with time_machine.travel(time_received, tick=False), self.mock_fcm() as ( + mock_fcm_app, + mock_fcm_messaging, + ), self.mock_apns() as (apns_context, send_notification), mock.patch( "corporate.lib.stripe.RemoteRealmBillingSession.current_count_for_billed_licenses", return_value=10, ), self.assertLogs( @@ -2837,9 +2860,9 @@ class HandlePushNotificationTest(PushNotificationTest): (b64_to_hex(device.token), device.ios_app_id, device.token) for device in RemotePushDeviceToken.objects.filter(kind=PushDeviceToken.FCM) ] - mock_gcm.json_request.return_value = { - "success": {device[2]: message.id for device in gcm_devices} - } + mock_fcm_messaging.send_each.return_value = self.make_fcm_success_response( + [device[2] for device in gcm_devices] + ) send_notification.return_value.is_successful = True handle_push_notification(self.user_profile.id, missed_message) self.assertEqual( @@ -2869,9 +2892,9 @@ class HandlePushNotificationTest(PushNotificationTest): f"APNs: Success sending for user to device {token}", pn_logger.output, ) - for _, _, token in gcm_devices: + for idx, (_, _, token) in enumerate(gcm_devices): self.assertIn( - f"INFO:zerver.lib.push_notifications:GCM: Sent {token} as {message.id}", + f"INFO:zerver.lib.push_notifications:FCM: Sent message with ID: {idx} to {token}", pn_logger.output, ) @@ -2981,9 +3004,10 @@ class HandlePushNotificationTest(PushNotificationTest): "message_id": message.id, "trigger": NotificationTriggers.DIRECT_MESSAGE, } - with time_machine.travel(time_received, tick=False), mock.patch( - "zerver.lib.push_notifications.gcm_client" - ) as mock_gcm, self.mock_apns() as (apns_context, send_notification), mock.patch( + with time_machine.travel(time_received, tick=False), self.mock_fcm() as ( + mock_fcm_app, + mock_fcm_messaging, + ), self.mock_apns() as (apns_context, send_notification), mock.patch( "corporate.lib.stripe.RemoteRealmBillingSession.current_count_for_billed_licenses", return_value=10, ), self.assertLogs( @@ -3021,7 +3045,9 @@ class HandlePushNotificationTest(PushNotificationTest): for device in RemotePushDeviceToken.objects.filter(kind=PushDeviceToken.FCM) ] - mock_gcm.json_request.return_value = {"success": {gcm_devices[0][2]: message.id}} + mock_fcm_messaging.send_each.return_value = self.make_fcm_success_response( + [gcm_devices[0][2]] + ) send_notification.return_value.is_successful = False send_notification.return_value.description = "Unregistered" @@ -4783,7 +4809,8 @@ class GCMParseOptionsTest(ZulipTestCase): self.assertEqual("high", parse_fcm_options({"priority": "high"}, {})) -@mock.patch("zerver.lib.push_notifications.gcm_client") +@mock.patch("zerver.lib.push_notifications.fcm_app") +@mock.patch("zerver.lib.push_notifications.firebase_messaging") class FCMSendTest(PushNotificationTest): @override def setUp(self) -> None: @@ -4798,47 +4825,61 @@ class FCMSendTest(PushNotificationTest): data.update(kwargs) return data - def test_gcm_is_none(self, mock_gcm: mock.MagicMock) -> None: - mock_gcm.__bool__.return_value = False + def test_fcm_is_none(self, mock_fcm_messaging: mock.MagicMock, fcm_app: mock.MagicMock) -> None: + fcm_app.__bool__.return_value = False with self.assertLogs("zerver.lib.push_notifications", level="DEBUG") as logger: send_android_push_notification_to_user(self.user_profile, {}, {}) self.assertEqual( "DEBUG:zerver.lib.push_notifications:" - "Skipping sending a GCM push notification since PUSH_NOTIFICATION_BOUNCER_URL " - "and ANDROID_GCM_API_KEY are both unset", + "Skipping sending a FCM push notification since PUSH_NOTIFICATION_BOUNCER_URL " + "and ANDROID_FCM_CREDENTIALS_PATH are both unset", logger.output[0], ) - def test_json_request_raises_ioerror(self, mock_gcm: mock.MagicMock) -> None: - mock_gcm.json_request.side_effect = OSError("error") + def test_send_raises_error( + self, mock_fcm_messaging: mock.MagicMock, fcm_app: mock.MagicMock + ) -> None: + mock_fcm_messaging.send_each.side_effect = firebase_exceptions.FirebaseError( + firebase_exceptions.UNKNOWN, "error" + ) with self.assertLogs("zerver.lib.push_notifications", level="WARNING") as logger: send_android_push_notification_to_user(self.user_profile, {}, {}) self.assertIn( - "WARNING:zerver.lib.push_notifications:Error while pushing to GCM\nTraceback ", + "WARNING:zerver.lib.push_notifications:Error while pushing to FCM\nTraceback ", logger.output[0], ) @mock.patch("zerver.lib.push_notifications.logger.warning") - def test_success(self, mock_warning: mock.MagicMock, mock_gcm: mock.MagicMock) -> None: + def test_success( + self, + mock_warning: mock.MagicMock, + mock_fcm_messaging: mock.MagicMock, + fcm_app: mock.MagicMock, + ) -> None: res = {} res["success"] = {token: ind for ind, token in enumerate(self.fcm_tokens)} - mock_gcm.json_request.return_value = res + response = self.make_fcm_success_response(self.fcm_tokens) + mock_fcm_messaging.send_each.return_value = response data = self.get_fcm_data() with self.assertLogs("zerver.lib.push_notifications", level="INFO") as logger: send_android_push_notification_to_user(self.user_profile, data, {}) self.assert_length(logger.output, 3) - log_msg1 = f"INFO:zerver.lib.push_notifications:GCM: Sending notification for local user to 2 devices" - log_msg2 = f"INFO:zerver.lib.push_notifications:GCM: Sent {1111} as {0}" - log_msg3 = f"INFO:zerver.lib.push_notifications:GCM: Sent {2222} as {1}" + log_msg1 = f"INFO:zerver.lib.push_notifications:FCM: Sending notification for local user to 2 devices" + log_msg2 = f"INFO:zerver.lib.push_notifications:FCM: Sent message with ID: {response.responses[0].message_id} to {hex_to_b64(self.fcm_tokens[0])}" + log_msg3 = f"INFO:zerver.lib.push_notifications:FCM: Sent message with ID: {response.responses[1].message_id} to {hex_to_b64(self.fcm_tokens[1])}" + self.assertEqual([log_msg1, log_msg2, log_msg3], logger.output) mock_warning.assert_not_called() - def test_not_registered(self, mock_gcm: mock.MagicMock) -> None: - res = {} + def test_not_registered( + self, mock_fcm_messaging: mock.MagicMock, fcm_app: mock.MagicMock + ) -> None: token = hex_to_b64("1111") - res["errors"] = {"NotRegistered": [token]} - mock_gcm.json_request.return_value = res + response = self.make_fcm_error_response( + token, firebase_messaging.UnregisteredError("Requested entity was not found.") + ) + mock_fcm_messaging.send_each.return_value = response def get_count(hex_token: str) -> int: token = hex_to_b64(hex_token) @@ -4850,25 +4891,25 @@ class FCMSendTest(PushNotificationTest): with self.assertLogs("zerver.lib.push_notifications", level="INFO") as logger: send_android_push_notification_to_user(self.user_profile, data, {}) self.assertEqual( - f"INFO:zerver.lib.push_notifications:GCM: Sending notification for local user to 2 devices", + f"INFO:zerver.lib.push_notifications:FCM: Sending notification for local user to 2 devices", logger.output[0], ) self.assertEqual( - f"INFO:zerver.lib.push_notifications:GCM: Removing {token}", + f"INFO:zerver.lib.push_notifications:FCM: Removing {token} due to NOT_FOUND", logger.output[1], ) self.assertEqual(get_count("1111"), 0) - def test_failure(self, mock_gcm: mock.MagicMock) -> None: - res = {} + def test_failure(self, mock_fcm_messaging: mock.MagicMock, fcm_app: mock.MagicMock) -> None: token = hex_to_b64("1111") - res["errors"] = {"Failed": [token]} - mock_gcm.json_request.return_value = res + response = self.make_fcm_error_response(token, firebase_exceptions.UnknownError("Failed")) + mock_fcm_messaging.send_each.return_value = response data = self.get_fcm_data() with self.assertLogs("zerver.lib.push_notifications", level="WARNING") as logger: send_android_push_notification_to_user(self.user_profile, data, {}) - msg = f"WARNING:zerver.lib.push_notifications:GCM: Delivery to {token} failed: Failed" + msg = f"WARNING:zerver.lib.push_notifications:FCM: Delivery failed for {token}: :Failed" + self.assertEqual(msg, logger.output[0]) diff --git a/zilencer/views.py b/zilencer/views.py index c97753c08d..0193e0efc4 100644 --- a/zilencer/views.py +++ b/zilencer/views.py @@ -655,6 +655,9 @@ def remote_server_notify_push( # PushBouncerSession). The timeouts in the FCM and APNS codepaths # must be set accordingly; see send_android_push_notification and # send_apple_push_notification. + # TODO: This limit can be slightly exceeded now after changing the library + # used for sending FCM notifications. This is pending adjustment after + # getting some data on the behavior of the new API. gcm_payload = truncate_payload(gcm_payload) android_successfully_delivered = send_android_push_notification( diff --git a/zproject/computed_settings.py b/zproject/computed_settings.py index af3f13e922..5d91651417 100644 --- a/zproject/computed_settings.py +++ b/zproject/computed_settings.py @@ -442,11 +442,6 @@ ROOT_DOMAIN_URI = EXTERNAL_URI_SCHEME + EXTERNAL_HOST S3_KEY = get_secret("s3_key") S3_SECRET_KEY = get_secret("s3_secret_key") -# GCM tokens are IP-whitelisted; if we deploy to additional -# servers you will need to explicitly add their IPs here: -# https://cloud.google.com/console/project/apps~zulip-android/apiui/credential -ANDROID_GCM_API_KEY = get_secret("android_gcm_api_key") - DROPBOX_APP_KEY = get_secret("dropbox_app_key") BIG_BLUE_BUTTON_SECRET = get_secret("big_blue_button_secret") diff --git a/zproject/default_settings.py b/zproject/default_settings.py index c0109c7014..45f8195dc3 100644 --- a/zproject/default_settings.py +++ b/zproject/default_settings.py @@ -424,6 +424,7 @@ APNS_TEAM_ID = get_secret("apns_team_id", development_only=True) APNS_SANDBOX = True # APNS_TOPIC is obsolete. Clients now pass the APNs topic to use. # ZULIP_IOS_APP_ID is obsolete. Clients now pass the iOS app ID to use for APNs. +ANDROID_FCM_CREDENTIALS_PATH: Optional[str] = None # Limits related to the size of file uploads; last few in MB. DATA_UPLOAD_MAX_MEMORY_SIZE = 25 * 1024 * 1024