From 74688d229aae29ccd0835fe69120c142a467005c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Bertin?= Date: Fri, 13 Feb 2026 16:26:17 +0100 Subject: [PATCH 1/8] chore(dependencies): Upgrade requirements - aiohappyeyeballs 2.4.4 -> 2.6.1 - aiohttp 3.10.5 -> 3.13.3 - aiosignal 1.3.1 -> 1.4.0 - botocore 1.34.55 -> 1.34.162 - cryptography 44.0.2 -> 44.0.3 - django 4.2.26 -> 4.2.28 - pillow 10.3.0 -> 12.1.1 - propcache (added) 0.4.1 - pyasn1 0.5.1 -> 0.6.2 - pyasn1-modules 0.3.0 -> 0.4.2 - sqlparse 0.5.3 -> 0.5.5 - urllib3 2.0.7 -> 2.6.3 - yarl 1.9.4 -> 1.22.0 - python-ldap 3.4.4 -> 3.4.5 - werkzeug 3.1.3 -> 3.1.5 --- CHANGELOG | 17 + requirements.txt | 866 +++++++++++++++++++++++++++++------------------ 2 files changed, 558 insertions(+), 325 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d10b76e8c..ca9b10370 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- [DEPENDENCIES] + - aiohappyeyeballs 2.4.4 -> 2.6.1 + - aiohttp 3.10.5 -> 3.13.3 + - aiosignal 1.3.1 -> 1.4.0 + - botocore 1.34.55 -> 1.34.162 + - cryptography 44.0.2 -> 44.0.3 + - django 4.2.26 -> 4.2.28 + - pillow 10.3.0 -> 12.1.1 + - propcache (added) 0.4.1 + - pyasn1 0.5.1 -> 0.6.2 + - pyasn1-modules 0.3.0 -> 0.4.2 + - sqlparse 0.5.3 -> 0.5.5 + - urllib3 2.0.7 -> 2.6.3 + - yarl 1.9.4 -> 1.22.0 + - python-ldap 3.4.4 -> 3.4.5 + - werkzeug 3.1.3 -> 3.1.5 ## [2.35.0] - 2026-02-06 diff --git a/requirements.txt b/requirements.txt index 98d00f332..6f73502d5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,109 +1,134 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile --allow-unsafe --cert=None --client-cert=None --generate-hashes --index-url=None --output-file=requirements.txt --pip-args=None --strip-extras requirements.in -# -aiohappyeyeballs==2.4.4 \ - --hash=sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745 \ - --hash=sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8 +# This file was autogenerated by uv via the following command: +# uv pip compile --generate-hashes --strip-extras requirements.in -o requirements.txt +aiohappyeyeballs==2.6.1 \ + --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ + --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 # via aiohttp -aiohttp==3.10.5 \ - --hash=sha256:02594361128f780eecc2a29939d9dfc870e17b45178a867bf61a11b2a4367277 \ - --hash=sha256:03f2645adbe17f274444953bdea69f8327e9d278d961d85657cb0d06864814c1 \ - --hash=sha256:074d1bff0163e107e97bd48cad9f928fa5a3eb4b9d33366137ffce08a63e37fe \ - --hash=sha256:0912b8a8fadeb32ff67a3ed44249448c20148397c1ed905d5dac185b4ca547bb \ - --hash=sha256:0d277cfb304118079e7044aad0b76685d30ecb86f83a0711fc5fb257ffe832ca \ - --hash=sha256:0d93400c18596b7dc4794d48a63fb361b01a0d8eb39f28800dc900c8fbdaca91 \ - --hash=sha256:123dd5b16b75b2962d0fff566effb7a065e33cd4538c1692fb31c3bda2bfb972 \ - --hash=sha256:17e997105bd1a260850272bfb50e2a328e029c941c2708170d9d978d5a30ad9a \ - --hash=sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3 \ - --hash=sha256:1923a5c44061bffd5eebeef58cecf68096e35003907d8201a4d0d6f6e387ccaa \ - --hash=sha256:1942244f00baaacaa8155eca94dbd9e8cc7017deb69b75ef67c78e89fdad3c77 \ - --hash=sha256:1b2c16a919d936ca87a3c5f0e43af12a89a3ce7ccbce59a2d6784caba945b68b \ - --hash=sha256:1c19de68896747a2aa6257ae4cf6ef59d73917a36a35ee9d0a6f48cff0f94db8 \ - --hash=sha256:1e72589da4c90337837fdfe2026ae1952c0f4a6e793adbbfbdd40efed7c63599 \ - --hash=sha256:22c0a23a3b3138a6bf76fc553789cb1a703836da86b0f306b6f0dc1617398abc \ - --hash=sha256:2c634a3207a5445be65536d38c13791904fda0748b9eabf908d3fe86a52941cf \ - --hash=sha256:2d21ac12dc943c68135ff858c3a989f2194a709e6e10b4c8977d7fcd67dfd511 \ - --hash=sha256:2f1f1c75c395991ce9c94d3e4aa96e5c59c8356a15b1c9231e783865e2772699 \ - --hash=sha256:305be5ff2081fa1d283a76113b8df7a14c10d75602a38d9f012935df20731487 \ - --hash=sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987 \ - --hash=sha256:349ef8a73a7c5665cca65c88ab24abe75447e28aa3bc4c93ea5093474dfdf0ff \ - --hash=sha256:380f926b51b92d02a34119d072f178d80bbda334d1a7e10fa22d467a66e494db \ - --hash=sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022 \ - --hash=sha256:391cc3a9c1527e424c6865e087897e766a917f15dddb360174a70467572ac6ce \ - --hash=sha256:3a1c32a19ee6bbde02f1cb189e13a71b321256cc1d431196a9f824050b160d5a \ - --hash=sha256:4120d7fefa1e2d8fb6f650b11489710091788de554e2b6f8347c7a20ceb003f5 \ - --hash=sha256:424ae21498790e12eb759040bbb504e5e280cab64693d14775c54269fd1d2bb7 \ - --hash=sha256:44b324a6b8376a23e6ba25d368726ee3bc281e6ab306db80b5819999c737d820 \ - --hash=sha256:4790f0e15f00058f7599dab2b206d3049d7ac464dc2e5eae0e93fa18aee9e7bf \ - --hash=sha256:4aff049b5e629ef9b3e9e617fa6e2dfeda1bf87e01bcfecaf3949af9e210105e \ - --hash=sha256:4b38b1570242fbab8d86a84128fb5b5234a2f70c2e32f3070143a6d94bc854cf \ - --hash=sha256:4d46c7b4173415d8e583045fbc4daa48b40e31b19ce595b8d92cf639396c15d5 \ - --hash=sha256:4f1c9866ccf48a6df2b06823e6ae80573529f2af3a0992ec4fe75b1a510df8a6 \ - --hash=sha256:4f7acae3cf1a2a2361ec4c8e787eaaa86a94171d2417aae53c0cca6ca3118ff6 \ - --hash=sha256:54d9ddea424cd19d3ff6128601a4a4d23d54a421f9b4c0fff740505813739a91 \ - --hash=sha256:58718e181c56a3c02d25b09d4115eb02aafe1a732ce5714ab70326d9776457c3 \ - --hash=sha256:5ede29d91a40ba22ac1b922ef510aab871652f6c88ef60b9dcdf773c6d32ad7a \ - --hash=sha256:61645818edd40cc6f455b851277a21bf420ce347baa0b86eaa41d51ef58ba23d \ - --hash=sha256:66bf9234e08fe561dccd62083bf67400bdbf1c67ba9efdc3dac03650e97c6088 \ - --hash=sha256:673f988370f5954df96cc31fd99c7312a3af0a97f09e407399f61583f30da9bc \ - --hash=sha256:676f94c5480d8eefd97c0c7e3953315e4d8c2b71f3b49539beb2aa676c58272f \ - --hash=sha256:6c225286f2b13bab5987425558baa5cbdb2bc925b2998038fa028245ef421e75 \ - --hash=sha256:7384d0b87d4635ec38db9263e6a3f1eb609e2e06087f0aa7f63b76833737b471 \ - --hash=sha256:7e2fe37ac654032db1f3499fe56e77190282534810e2a8e833141a021faaab0e \ - --hash=sha256:7f2bfc0032a00405d4af2ba27f3c429e851d04fad1e5ceee4080a1c570476697 \ - --hash=sha256:7f6b639c36734eaa80a6c152a238242bedcee9b953f23bb887e9102976343092 \ - --hash=sha256:814375093edae5f1cb31e3407997cf3eacefb9010f96df10d64829362ae2df69 \ - --hash=sha256:8224f98be68a84b19f48e0bdc14224b5a71339aff3a27df69989fa47d01296f3 \ - --hash=sha256:898715cf566ec2869d5cb4d5fb4be408964704c46c96b4be267442d265390f32 \ - --hash=sha256:8989f46f3d7ef79585e98fa991e6ded55d2f48ae56d2c9fa5e491a6e4effb589 \ - --hash=sha256:8ba01ebc6175e1e6b7275c907a3a36be48a2d487549b656aa90c8a910d9f3178 \ - --hash=sha256:8c5c6fa16412b35999320f5c9690c0f554392dc222c04e559217e0f9ae244b92 \ - --hash=sha256:8c6a4e5e40156d72a40241a25cc226051c0a8d816610097a8e8f517aeacd59a2 \ - --hash=sha256:8eaf44ccbc4e35762683078b72bf293f476561d8b68ec8a64f98cf32811c323e \ - --hash=sha256:8fb4fc029e135859f533025bc82047334e24b0d489e75513144f25408ecaf058 \ - --hash=sha256:9093a81e18c45227eebe4c16124ebf3e0d893830c6aca7cc310bfca8fe59d857 \ - --hash=sha256:94c4381ffba9cc508b37d2e536b418d5ea9cfdc2848b9a7fea6aebad4ec6aac1 \ - --hash=sha256:94fac7c6e77ccb1ca91e9eb4cb0ac0270b9fb9b289738654120ba8cebb1189c6 \ - --hash=sha256:95c4dc6f61d610bc0ee1edc6f29d993f10febfe5b76bb470b486d90bbece6b22 \ - --hash=sha256:975218eee0e6d24eb336d0328c768ebc5d617609affaca5dbbd6dd1984f16ed0 \ - --hash=sha256:ad146dae5977c4dd435eb31373b3fe9b0b1bf26858c6fc452bf6af394067e10b \ - --hash=sha256:afe16a84498441d05e9189a15900640a2d2b5e76cf4efe8cbb088ab4f112ee57 \ - --hash=sha256:b1c43eb1ab7cbf411b8e387dc169acb31f0ca0d8c09ba63f9eac67829585b44f \ - --hash=sha256:b90078989ef3fc45cf9221d3859acd1108af7560c52397ff4ace8ad7052a132e \ - --hash=sha256:b98e698dc34966e5976e10bbca6d26d6724e6bdea853c7c10162a3235aba6e16 \ - --hash=sha256:ba5a8b74c2a8af7d862399cdedce1533642fa727def0b8c3e3e02fcb52dca1b1 \ - --hash=sha256:c31ad0c0c507894e3eaa843415841995bf8de4d6b2d24c6e33099f4bc9fc0d4f \ - --hash=sha256:c3b9162bab7e42f21243effc822652dc5bb5e8ff42a4eb62fe7782bcbcdfacf6 \ - --hash=sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04 \ - --hash=sha256:c83f7a107abb89a227d6c454c613e7606c12a42b9a4ca9c5d7dad25d47c776ae \ - --hash=sha256:cde98f323d6bf161041e7627a5fd763f9fd829bcfcd089804a5fdce7bb6e1b7d \ - --hash=sha256:ce91db90dbf37bb6fa0997f26574107e1b9d5ff939315247b7e615baa8ec313b \ - --hash=sha256:d00f3c5e0d764a5c9aa5a62d99728c56d455310bcc288a79cab10157b3af426f \ - --hash=sha256:d17920f18e6ee090bdd3d0bfffd769d9f2cb4c8ffde3eb203777a3895c128862 \ - --hash=sha256:d55f011da0a843c3d3df2c2cf4e537b8070a419f891c930245f05d329c4b0689 \ - --hash=sha256:d742c36ed44f2798c8d3f4bc511f479b9ceef2b93f348671184139e7d708042c \ - --hash=sha256:d9a487ef090aea982d748b1b0d74fe7c3950b109df967630a20584f9a99c0683 \ - --hash=sha256:d9ef084e3dc690ad50137cc05831c52b6ca428096e6deb3c43e95827f531d5ef \ - --hash=sha256:da452c2c322e9ce0cfef392e469a26d63d42860f829026a63374fde6b5c5876f \ - --hash=sha256:dc4826823121783dccc0871e3f405417ac116055bf184ac04c36f98b75aacd12 \ - --hash=sha256:de7a5299827253023c55ea549444e058c0eb496931fa05d693b95140a947cb73 \ - --hash=sha256:e04a1f2a65ad2f93aa20f9ff9f1b672bf912413e5547f60749fa2ef8a644e061 \ - --hash=sha256:e1ca1ef5ba129718a8fc827b0867f6aa4e893c56eb00003b7367f8a733a9b072 \ - --hash=sha256:ee40b40aa753d844162dcc80d0fe256b87cba48ca0054f64e68000453caead11 \ - --hash=sha256:f071854b47d39591ce9a17981c46790acb30518e2f83dfca8db2dfa091178691 \ - --hash=sha256:f29930bc2921cef955ba39a3ff87d2c4398a0394ae217f41cb02d5c26c8b1b77 \ - --hash=sha256:f489a2c9e6455d87eabf907ac0b7d230a9786be43fbe884ad184ddf9e9c1e385 \ - --hash=sha256:f5bf3ead3cb66ab990ee2561373b009db5bc0e857549b6c9ba84b20bc462e172 \ - --hash=sha256:f6f18898ace4bcd2d41a122916475344a87f1dfdec626ecde9ee802a711bc569 \ - --hash=sha256:f8112fb501b1e0567a1251a2fd0747baae60a4ab325a871e975b7bb67e59221f \ - --hash=sha256:fd31f176429cecbc1ba499d4aba31aaccfea488f418d60376b911269d3b883c5 +aiohttp==3.13.3 \ + --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ + --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ + --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ + --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ + --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ + --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ + --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ + --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ + --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ + --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ + --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ + --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ + --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ + --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ + --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ + --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ + --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ + --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ + --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ + --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ + --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ + --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ + --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ + --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ + --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ + --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ + --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ + --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ + --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ + --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ + --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ + --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ + --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ + --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ + --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ + --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ + --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ + --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ + --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ + --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ + --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ + --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ + --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ + --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ + --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ + --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ + --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ + --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ + --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ + --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ + --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ + --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ + --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ + --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ + --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ + --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ + --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ + --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ + --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ + --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ + --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ + --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ + --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ + --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ + --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ + --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ + --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ + --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ + --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ + --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ + --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ + --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ + --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ + --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ + --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ + --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ + --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ + --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ + --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ + --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ + --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ + --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ + --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ + --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ + --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ + --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ + --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ + --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ + --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ + --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ + --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ + --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ + --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ + --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ + --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ + --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ + --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ + --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ + --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ + --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ + --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ + --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ + --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ + --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ + --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ + --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ + --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ + --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ + --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ + --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ + --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ + --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ + --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ + --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ + --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ + --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ + --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ + --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ + --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ + --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 # via meraki -aiosignal==1.3.1 \ - --hash=sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc \ - --hash=sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17 +aiosignal==1.4.0 \ + --hash=sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e \ + --hash=sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7 # via aiohttp asgiref==3.7.2 \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ @@ -126,9 +151,9 @@ boto3==1.34.55 \ --hash=sha256:9a6d59e035fac4366dbdaf909c4f66fc817dfbec044fa71564dcf036ad46bb19 \ --hash=sha256:ee2c96e8a4a741ecb3380e0a406baa67bfea6186be99b75bdeca3e1b5044c088 # via -r requirements.in -botocore==1.34.55 \ - --hash=sha256:07044c3cbfb86d0ecb9c56d887b8ad63a72eff0e4f6ab329cf335f1fd867ea0b \ - --hash=sha256:bb333e3845bfe65600f36bf92d09668306e224fa9f4e4f87b77f6957192ae59f +botocore==1.34.162 \ + --hash=sha256:2d918b02db88d27a75b48275e6fb2506e9adaaddbec1ffa6a8a0898b34e769be \ + --hash=sha256:adc23be4fb99ad31961236342b7cbf3c0bfc62532cd02852196032e8c0d682f3 # via # boto3 # s3transfer @@ -302,42 +327,44 @@ configparser==6.0.1 \ --hash=sha256:5a0da275bea56f871abaa9e0806331791e9d8ae2938e8b8797b99ab3e8e192c4 \ --hash=sha256:db45513e971e509496b150be31bd67b0e14ab20b78a383b677e4b158e2c682d8 # via sophos-central-siem-integration -cryptography==44.0.2 \ - --hash=sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390 \ - --hash=sha256:0529b1d5a0105dd3731fa65680b45ce49da4d8115ea76e9da77a875396727b41 \ - --hash=sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688 \ - --hash=sha256:268e4e9b177c76d569e8a145a6939eca9a5fec658c932348598818acf31ae9a5 \ - --hash=sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1 \ - --hash=sha256:2bf7bf75f7df9715f810d1b038870309342bff3069c5bd8c6b96128cb158668d \ - --hash=sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7 \ - --hash=sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843 \ - --hash=sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5 \ - --hash=sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c \ - --hash=sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a \ - --hash=sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79 \ - --hash=sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6 \ - --hash=sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181 \ - --hash=sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4 \ - --hash=sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5 \ - --hash=sha256:7ca25849404be2f8e4b3c59483d9d3c51298a22c1c61a0e84415104dacaf5562 \ - --hash=sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639 \ - --hash=sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922 \ - --hash=sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3 \ - --hash=sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d \ - --hash=sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471 \ - --hash=sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd \ - --hash=sha256:9eb9d22b0a5d8fd9925a7764a054dca914000607dff201a24c791ff5c799e1fa \ - --hash=sha256:af4ff3e388f2fa7bff9f7f2b31b87d5651c45731d3e8cfa0944be43dff5cfbdb \ - --hash=sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699 \ - --hash=sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb \ - --hash=sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa \ - --hash=sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0 \ - --hash=sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23 \ - --hash=sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9 \ - --hash=sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615 \ - --hash=sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea \ - --hash=sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7 \ - --hash=sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308 +cryptography==44.0.3 \ + --hash=sha256:02f55fb4f8b79c1221b0961488eaae21015b69b210e18c386b69de182ebb1259 \ + --hash=sha256:157f1f3b8d941c2bd8f3ffee0af9b049c9665c39d3da9db2dc338feca5e98a43 \ + --hash=sha256:192ed30fac1728f7587c6f4613c29c584abdc565d7417c13904708db10206645 \ + --hash=sha256:21a83f6f35b9cc656d71b5de8d519f566df01e660ac2578805ab245ffd8523f8 \ + --hash=sha256:25cd194c39fa5a0aa4169125ee27d1172097857b27109a45fadc59653ec06f44 \ + --hash=sha256:3883076d5c4cc56dbef0b898a74eb6992fdac29a7b9013870b34efe4ddb39a0d \ + --hash=sha256:3bb0847e6363c037df8f6ede57d88eaf3410ca2267fb12275370a76f85786a6f \ + --hash=sha256:3be3f649d91cb182c3a6bd336de8b61a0a71965bd13d1a04a0e15b39c3d5809d \ + --hash=sha256:3f07943aa4d7dad689e3bb1638ddc4944cc5e0921e3c227486daae0e31a05e54 \ + --hash=sha256:479d92908277bed6e1a1c69b277734a7771c2b78633c224445b5c60a9f4bc1d9 \ + --hash=sha256:4ffc61e8f3bf5b60346d89cd3d37231019c17a081208dfbbd6e1605ba03fa137 \ + --hash=sha256:5639c2b16764c6f76eedf722dbad9a0914960d3489c0cc38694ddf9464f1bb2f \ + --hash=sha256:58968d331425a6f9eedcee087f77fd3c927c88f55368f43ff7e0a19891f2642c \ + --hash=sha256:5d186f32e52e66994dce4f766884bcb9c68b8da62d61d9d215bfe5fb56d21334 \ + --hash=sha256:5d20cc348cca3a8aa7312f42ab953a56e15323800ca3ab0706b8cd452a3a056c \ + --hash=sha256:6866df152b581f9429020320e5eb9794c8780e90f7ccb021940d7f50ee00ae0b \ + --hash=sha256:7d5fe7195c27c32a64955740b949070f21cba664604291c298518d2e255931d2 \ + --hash=sha256:896530bc9107b226f265effa7ef3f21270f18a2026bc09fed1ebd7b66ddf6375 \ + --hash=sha256:962bc30480a08d133e631e8dfd4783ab71cc9e33d5d7c1e192f0b7c06397bb88 \ + --hash=sha256:978631ec51a6bbc0b7e58f23b68a8ce9e5f09721940933e9c217068388789fe5 \ + --hash=sha256:9b4d4a5dbee05a2c390bf212e78b99434efec37b17a4bff42f50285c5c8c9647 \ + --hash=sha256:ab0b005721cc0039e885ac3503825661bd9810b15d4f374e473f8c89b7d5460c \ + --hash=sha256:af653022a0c25ef2e3ffb2c673a50e5a0d02fecc41608f4954176f1933b12359 \ + --hash=sha256:b0cc66c74c797e1db750aaa842ad5b8b78e14805a9b5d1348dc603612d3e3ff5 \ + --hash=sha256:b424563394c369a804ecbee9b06dfb34997f19d00b3518e39f83a5642618397d \ + --hash=sha256:c138abae3a12a94c75c10499f1cbae81294a6f983b3af066390adee73f433028 \ + --hash=sha256:c6cd67722619e4d55fdb42ead64ed8843d64638e9c07f4011163e46bc512cf01 \ + --hash=sha256:c91fc8e8fd78af553f98bc7f2a1d8db977334e4eea302a4bfd75b9461c2d8904 \ + --hash=sha256:cad399780053fb383dc067475135e41c9fe7d901a97dd5d9c5dfb5611afc0d7d \ + --hash=sha256:cb90f60e03d563ca2445099edf605c16ed1d5b15182d21831f58460c48bffb93 \ + --hash=sha256:dad80b45c22e05b259e33ddd458e9e2ba099c86ccf4e88db7bbab4b747b18d06 \ + --hash=sha256:dd3db61b8fe5be220eee484a17233287d0be6932d056cf5738225b9c05ef4fff \ + --hash=sha256:e28d62e59a4dbd1d22e747f57d4f00c459af22181f0b2f787ea83f5a876d7c76 \ + --hash=sha256:e909df4053064a97f1e6565153ff8bb389af12c5c8d29c343308760890560aff \ + --hash=sha256:f3ffef566ac88f75967d7abd852ed5f182da252d23fac11b4766da3957766759 \ + --hash=sha256:fc3c9babc1e1faefd62704bb46a69f359a9819eb0292e40df3fb6e3574715cd4 \ + --hash=sha256:fe19d8bc5536a91a24a8133328880a41831b6c5df54599a8417b62fe015d3053 # via # -r requirements.in # msal @@ -347,9 +374,9 @@ defusedxml==0.7.1 \ --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ --hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 # via -r requirements.in -django==4.2.26 \ - --hash=sha256:9398e487bcb55e3f142cb56d19fbd9a83e15bb03a97edc31f408361ee76d9d7a \ - --hash=sha256:c96e64fc3c359d051a6306871bd26243db1bd02317472a62ffdbe6c3cae14280 +django==4.2.28 \ + --hash=sha256:49a23c1b83ef31525f8d71a57b040f91d34660edb3f086280a8519855655ed3c \ + --hash=sha256:a4b9cd881991add394cafa8bb3b11ad1742d1e1470ba99c3ef53dc540316ccfe # via # -r requirements.in # django-crontab @@ -810,77 +837,225 @@ pathlib==1.0.1 \ --hash=sha256:6940718dfc3eff4258203ad5021090933e5c04707d5ca8cc9e73c94a7894ea9f \ --hash=sha256:f35f95ab8b0f59e6d354090350b44a80a80635d22efdedfa84c7ad1cf0a74147 # via sophos-central-siem-integration -pillow==10.3.0 \ - --hash=sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c \ - --hash=sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2 \ - --hash=sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb \ - --hash=sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d \ - --hash=sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa \ - --hash=sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3 \ - --hash=sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1 \ - --hash=sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a \ - --hash=sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd \ - --hash=sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8 \ - --hash=sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999 \ - --hash=sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599 \ - --hash=sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936 \ - --hash=sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375 \ - --hash=sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d \ - --hash=sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b \ - --hash=sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60 \ - --hash=sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572 \ - --hash=sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3 \ - --hash=sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced \ - --hash=sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f \ - --hash=sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b \ - --hash=sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19 \ - --hash=sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f \ - --hash=sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d \ - --hash=sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383 \ - --hash=sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795 \ - --hash=sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355 \ - --hash=sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57 \ - --hash=sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09 \ - --hash=sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b \ - --hash=sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462 \ - --hash=sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf \ - --hash=sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f \ - --hash=sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a \ - --hash=sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad \ - --hash=sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9 \ - --hash=sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d \ - --hash=sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45 \ - --hash=sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994 \ - --hash=sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d \ - --hash=sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338 \ - --hash=sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463 \ - --hash=sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451 \ - --hash=sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591 \ - --hash=sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c \ - --hash=sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd \ - --hash=sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32 \ - --hash=sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9 \ - --hash=sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf \ - --hash=sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5 \ - --hash=sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828 \ - --hash=sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3 \ - --hash=sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5 \ - --hash=sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2 \ - --hash=sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b \ - --hash=sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2 \ - --hash=sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475 \ - --hash=sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3 \ - --hash=sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb \ - --hash=sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef \ - --hash=sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015 \ - --hash=sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002 \ - --hash=sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170 \ - --hash=sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84 \ - --hash=sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57 \ - --hash=sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f \ - --hash=sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27 \ - --hash=sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a +pillow==12.1.1 \ + --hash=sha256:02f84dfad02693676692746df05b89cf25597560db2857363a208e393429f5e9 \ + --hash=sha256:0330d233c1a0ead844fc097a7d16c0abff4c12e856c0b325f231820fee1f39da \ + --hash=sha256:03edcc34d688572014ff223c125a3f77fb08091e4607e7745002fc214070b35f \ + --hash=sha256:097690ba1f2efdeb165a20469d59d8bb03c55fb6621eb2041a060ae8ea3e9642 \ + --hash=sha256:178aa072084bd88ec759052feca8e56cbb14a60b39322b99a049e58090479713 \ + --hash=sha256:18e5bddd742a44b7e6b1e773ab5db102bd7a94c32555ba656e76d319d19c3850 \ + --hash=sha256:1a9b0ee305220b392e1124a764ee4265bd063e54a751a6b62eff69992f457fa9 \ + --hash=sha256:1f1625b72740fdda5d77b4def688eb8fd6490975d06b909fd19f13f391e077e0 \ + --hash=sha256:1f1be78ce9466a7ee64bfda57bdba0f7cc499d9794d518b854816c41bf0aa4e9 \ + --hash=sha256:1f90cff8aa76835cba5769f0b3121a22bd4eb9e6884cfe338216e557a9a548b8 \ + --hash=sha256:21329ec8c96c6e979cd0dfd29406c40c1d52521a90544463057d2aaa937d66a6 \ + --hash=sha256:2815a87ab27848db0321fb78c7f0b2c8649dee134b7f2b80c6a45c6831d75ccd \ + --hash=sha256:2c1fc0f2ca5f96a3c8407e41cca26a16e46b21060fe6d5b099d2cb01412222f5 \ + --hash=sha256:2e0c664be47252947d870ac0d327fea7e63985a08794758aa8af5b6cb6ec0c9c \ + --hash=sha256:339ffdcb7cbeaa08221cd401d517d4b1fe7a9ed5d400e4a8039719238620ca35 \ + --hash=sha256:344cf1e3dab3be4b1fa08e449323d98a2a3f819ad20f4b22e77a0ede31f0faa1 \ + --hash=sha256:36341d06738a9f66c8287cf8b876d24b18db9bd8740fa0672c74e259ad408cff \ + --hash=sha256:365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38 \ + --hash=sha256:3a5cbdcddad0af3da87cb16b60d23648bc3b51967eb07223e9fed77a82b457c4 \ + --hash=sha256:417423db963cb4be8bac3fc1204fe61610f6abeed1580a7a2cbb2fbda20f12af \ + --hash=sha256:42fc1f4677106188ad9a55562bbade416f8b55456f522430fadab3cef7cd4e60 \ + --hash=sha256:44ce27545b6efcf0fdbdceb31c9a5bdea9333e664cda58a7e674bb74608b3986 \ + --hash=sha256:472a8d7ded663e6162dafdf20015c486a7009483ca671cece7a9279b512fcb13 \ + --hash=sha256:47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717 \ + --hash=sha256:495c302af3aad1ca67420ddd5c7bd480c8867ad173528767d906428057a11f0e \ + --hash=sha256:4ceb838d4bd9dab43e06c363cab2eebf63846d6a4aeaea283bbdfd8f1a8ed58b \ + --hash=sha256:50480dcd74fa63b8e78235957d302d98d98d82ccbfac4c7e12108ba9ecbdba15 \ + --hash=sha256:518a48c2aab7ce596d3bf79d0e275661b846e86e4d0e7dec34712c30fe07f02a \ + --hash=sha256:559b38da23606e68681337ad74622c4dbba02254fc9cb4488a305dd5975c7eeb \ + --hash=sha256:578510d88c6229d735855e1f278aa305270438d36a05031dfaae5067cc8eb04d \ + --hash=sha256:597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b \ + --hash=sha256:5a8eb7ed8d4198bccbd07058416eeec51686b498e784eda166395a23eb99138e \ + --hash=sha256:5c0dd1636633e7e6a0afe7bf6a51a14992b7f8e60de5789018ebbdfae55b040a \ + --hash=sha256:5cb1785d97b0c3d1d1a16bc1d710c4a0049daefc4935f3a8f31f827f4d3d2e7f \ + --hash=sha256:5d1f9575a12bed9e9eedd9a4972834b08c97a352bd17955ccdebfeca5913fa0a \ + --hash=sha256:5d8c41325b382c07799a3682c1c258469ea2ff97103c53717b7893862d0c98ce \ + --hash=sha256:5dae5f21afb91322f2ff791895ddd8889e5e947ff59f71b46041c8ce6db790bc \ + --hash=sha256:600fd103672b925fe62ed08e0d874ea34d692474df6f4bf7ebe148b30f89f39f \ + --hash=sha256:6408a7b064595afcab0a49393a413732a35788f2a5092fdc6266952ed67de586 \ + --hash=sha256:652a2c9ccfb556235b2b501a3a7cf3742148cd22e04b5625c5fe057ea3e3191f \ + --hash=sha256:665e1b916b043cef294bc54d47bf02d87e13f769bc4bc5fa225a24b3a6c5aca9 \ + --hash=sha256:691ab2ac363b8217f7d31b3497108fb1f50faab2f75dfb03284ec2f217e87bf8 \ + --hash=sha256:6c52f062424c523d6c4db85518774cc3d50f5539dd6eed32b8f6229b26f24d40 \ + --hash=sha256:6c6db3b84c87d48d0088943bf33440e0c42370b99b1c2a7989216f7b42eede60 \ + --hash=sha256:7311c0a0dcadb89b36b7025dfd8326ecfa36964e29913074d47382706e516a7c \ + --hash=sha256:7aac39bcf8d4770d089588a2e1dd111cbaa42df5a94be3114222057d68336bd0 \ + --hash=sha256:7b03048319bfc6170e93bd60728a1af51d3dd7704935feb228c4d4faab35d334 \ + --hash=sha256:7e7976bf1910a8116b523b9f9f58bf410f3e8aa330cd9a2bb2953f9266ab49af \ + --hash=sha256:8089c852a56c2966cf18835db62d9b34fef7ba74c726ad943928d494fa7f4735 \ + --hash=sha256:86172b0831b82ce4f7877f280055892b31179e1576aa00d0df3bb1bbf8c3e524 \ + --hash=sha256:89b54027a766529136a06cfebeecb3a04900397a3590fd252160b888479517bf \ + --hash=sha256:89c7e895002bbe49cdc5426150377cbbc04767d7547ed145473f496dfa40408b \ + --hash=sha256:8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2 \ + --hash=sha256:8fd420ef0c52c88b5a035a0886f367748c72147b2b8f384c9d12656678dfdfa9 \ + --hash=sha256:98edb152429ab62a1818039744d8fbb3ccab98a7c29fc3d5fcef158f3f1f68b7 \ + --hash=sha256:99c1506ea77c11531d75e3a412832a13a71c7ebc8192ab9e4b2e355555920e3e \ + --hash=sha256:9ad8fa5937ab05218e2b6a4cff30295ad35afd2f83ac592e68c0d871bb0fdbc4 \ + --hash=sha256:9f51079765661884a486727f0729d29054242f74b46186026582b4e4769918e4 \ + --hash=sha256:a003d7422449f6d1e3a34e3dd4110c22148336918ddbfc6a32581cd54b2e0b2b \ + --hash=sha256:a0b1cd6232e2b618adcc54d9882e4e662a089d5768cd188f7c245b4c8c44a397 \ + --hash=sha256:a285e3eb7a5a45a2ff504e31f4a8d1b12ef62e84e5411c6804a42197c1cf586c \ + --hash=sha256:a37691702ed687799de29a518d63d4682d9016932db66d4e90c345831b02fb4e \ + --hash=sha256:a550ae29b95c6dc13cf69e2c9dc5747f814c54eeb2e32d683e5e93af56caa029 \ + --hash=sha256:ab174cd7d29a62dd139c44bf74b698039328f45cb03b4596c43473a46656b2f3 \ + --hash=sha256:ab323b787d6e18b3d91a72fc99b1a2c28651e4358749842b8f8dfacd28ef2052 \ + --hash=sha256:adebb5bee0f0af4909c30db0d890c773d1a92ffe83da908e2e9e720f8edf3984 \ + --hash=sha256:aee2810642b2898bb187ced9b349e95d2a7272930796e022efaf12e99dccd293 \ + --hash=sha256:af9a332e572978f0218686636610555ae3defd1633597be015ed50289a03c523 \ + --hash=sha256:b574c51cf7d5d62e9be37ba446224b59a2da26dc4c1bb2ecbe936a4fb1a7cb7f \ + --hash=sha256:b66e95d05ba806247aaa1561f080abc7975daf715c30780ff92a20e4ec546e1b \ + --hash=sha256:b81b5e3511211631b3f672a595e3221252c90af017e399056d0faabb9538aa80 \ + --hash=sha256:b957b71c6b2387610f556a7eb0828afbe40b4a98036fc0d2acfa5a44a0c2036f \ + --hash=sha256:bb66b7cc26f50977108790e2456b7921e773f23db5630261102233eb355a3b79 \ + --hash=sha256:c6008de247150668a705a6338156efb92334113421ceecf7438a12c9a12dab23 \ + --hash=sha256:c7697918b5be27424e9ce568193efd13d925c4481dd364e43f5dff72d33e10f8 \ + --hash=sha256:cb9bb857b2d057c6dfc72ac5f3b44836924ba15721882ef103cecb40d002d80e \ + --hash=sha256:cc7d296b5ea4d29e6570dabeaed58d31c3fea35a633a69679fb03d7664f43fb3 \ + --hash=sha256:d242e8ac078781f1de88bf823d70c1a9b3c7950a44cdf4b7c012e22ccbcd8e4e \ + --hash=sha256:d2912fd8114fc5545aa3a4b5576512f64c55a03f3ebcca4c10194d593d43ea36 \ + --hash=sha256:d470ab1178551dd17fdba0fef463359c41aaa613cdcd7ff8373f54be629f9f8f \ + --hash=sha256:d4ce8e329c93845720cd2014659ca67eac35f6433fd3050393d85f3ecef0dad5 \ + --hash=sha256:d6e4571eedf43af33d0fc233a382a76e849badbccdf1ac438841308652a08e1f \ + --hash=sha256:e65498daf4b583091ccbb2556c7000abf0f3349fcd57ef7adc9a84a394ed29f6 \ + --hash=sha256:e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32 \ + --hash=sha256:e9e8064fb1cc019296958595f6db671fba95209e3ceb0c4734c9baf97de04b20 \ + --hash=sha256:f7ed2c6543bad5a7d5530eb9e78c53132f93dfa44a28492db88b41cdab885202 \ + --hash=sha256:f95c00d5d6700b2b890479664a06e754974848afaae5e21beb4d83c106923fd0 \ + --hash=sha256:f975aa7ef9684ce7e2c18a3aa8f8e2106ce1e46b94ab713d156b2898811651d3 \ + --hash=sha256:fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563 \ + --hash=sha256:fc354a04072b765eccf2204f588a7a532c9511e8b9c7f900e1b64e3e33487090 \ + --hash=sha256:fc44ef1f3de4f45b50ccf9136999d71abb99dca7706bc75d222ed350b9fd2289 # via captcha +propcache==0.4.1 \ + --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ + --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ + --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ + --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ + --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ + --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ + --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ + --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ + --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ + --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ + --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ + --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ + --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ + --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ + --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ + --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ + --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ + --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ + --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ + --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ + --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ + --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ + --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ + --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ + --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ + --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ + --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ + --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ + --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ + --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ + --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ + --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ + --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ + --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ + --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ + --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ + --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ + --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ + --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ + --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ + --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ + --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ + --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ + --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ + --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ + --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ + --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ + --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ + --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ + --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ + --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ + --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ + --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ + --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ + --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ + --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ + --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ + --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ + --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ + --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ + --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ + --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ + --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ + --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ + --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ + --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ + --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ + --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ + --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ + --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ + --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ + --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ + --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ + --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ + --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ + --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ + --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ + --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ + --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ + --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ + --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ + --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ + --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ + --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ + --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ + --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ + --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ + --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ + --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ + --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ + --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ + --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ + --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ + --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ + --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ + --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ + --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ + --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ + --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ + --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ + --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ + --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ + --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ + --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ + --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ + --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ + --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ + --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ + --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ + --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ + --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ + --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ + --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ + --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ + --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ + --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ + --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ + --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ + --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ + --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ + --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ + --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 + # via + # aiohttp + # yarl protobuf==4.25.8 \ --hash=sha256:077ff8badf2acf8bc474406706ad890466274191a48d0abd3bd6987107c9cde5 \ --hash=sha256:15a0af558aa3b13efef102ae6e4f3efac06f1eea11afb3a57db2901447d9fb59 \ @@ -896,18 +1071,18 @@ protobuf==4.25.8 \ # via # google-api-core # googleapis-common-protos -pyasn1==0.5.1 \ - --hash=sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58 \ - --hash=sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c +pyasn1==0.6.2 \ + --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ + --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b # via # edgegrid-python # ndg-httpsclient # pyasn1-modules # python-ldap # rsa -pyasn1-modules==0.3.0 \ - --hash=sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c \ - --hash=sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d +pyasn1-modules==0.4.2 \ + --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ + --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 # via # google-auth # python-ldap @@ -919,7 +1094,7 @@ pycparser==2.21 \ --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \ --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206 # via cffi -pyfaup @ https://github.com/VultureProject/faup/archive/refs/tags/v1.5.2.zip#subdirectory=src/lib/bindings/python/ \ +pyfaup @ https://github.com/VultureProject/faup/archive/refs/tags/v1.5.2.zip#egg=pyfaup&subdirectory=src/lib/bindings/python/ \ --hash=sha256:85398f32c8b8d15af9c70cdf9c03a8aa7ea7a6b70e725af38845ebc07e9c659e # via -r requirements.in pyjwt==2.8.0 \ @@ -1041,8 +1216,8 @@ python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # via botocore -python-ldap==3.4.4 \ - --hash=sha256:7edb0accec4e037797705f3a05cbf36a9fde50d08c8f67f2aef99a2628fab828 +python-ldap==3.4.5 \ + --hash=sha256:b2f6ef1c37fe2c6a5a85212efe71311ee21847766a7d45fcb711f3b270a5f79a # via -r requirements.in python-magic==0.4.27 \ --hash=sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b \ @@ -1104,9 +1279,9 @@ soupsieve==2.5 \ --hash=sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690 \ --hash=sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7 # via beautifulsoup4 -sqlparse==0.5.3 \ - --hash=sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272 \ - --hash=sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca +sqlparse==0.5.5 \ + --hash=sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba \ + --hash=sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e # via # django # djongo @@ -1114,15 +1289,16 @@ typing-extensions==4.10.0 \ --hash=sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475 \ --hash=sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb # via + # aiosignal # pyopenssl # qrcode uritemplate==4.1.1 \ --hash=sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0 \ --hash=sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e # via google-api-python-client -urllib3==2.0.7 \ - --hash=sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84 \ - --hash=sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e +urllib3==2.6.3 \ + --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ + --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 # via # botocore # edgegrid-python @@ -1135,103 +1311,143 @@ websocket-client==1.3.3 \ --hash=sha256:5d55652dc1d0b3c734f044337d929aaf83f4f9138816ec680c1aefefb4dc4877 \ --hash=sha256:d58c5f284d6a9bf8379dab423259fe8f85b70d5fa5d2916d5791a84594b122b1 # via -r requirements.in -werkzeug==3.1.3 \ - --hash=sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e \ - --hash=sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746 +werkzeug==3.1.5 \ + --hash=sha256:5111e36e91086ece91f93268bb39b4a35c1e6f1feac762c9c822ded0a4e322dc \ + --hash=sha256:6a548b0e88955dd07ccb25539d7d0cc97417ee9e179677d22c7041c8f078ce67 # via robobrowser xmltodict==0.15.0 \ --hash=sha256:8887783bf1faba1754fc45fdf3fe03fbb3629c811ae57f91c018aace4c58d4ed \ --hash=sha256:c6d46b4e3413d1e4fc3e5016f0f1c7a5c10f8ce39efaa0cb099af986ecfc9a53 # via -r requirements.in -yarl==1.9.4 \ - --hash=sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51 \ - --hash=sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce \ - --hash=sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559 \ - --hash=sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0 \ - --hash=sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81 \ - --hash=sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc \ - --hash=sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4 \ - --hash=sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c \ - --hash=sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130 \ - --hash=sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136 \ - --hash=sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e \ - --hash=sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec \ - --hash=sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7 \ - --hash=sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1 \ - --hash=sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455 \ - --hash=sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099 \ - --hash=sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129 \ - --hash=sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10 \ - --hash=sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142 \ - --hash=sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98 \ - --hash=sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa \ - --hash=sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7 \ - --hash=sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525 \ - --hash=sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c \ - --hash=sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9 \ - --hash=sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c \ - --hash=sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8 \ - --hash=sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b \ - --hash=sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf \ - --hash=sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23 \ - --hash=sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd \ - --hash=sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27 \ - --hash=sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f \ - --hash=sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece \ - --hash=sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434 \ - --hash=sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec \ - --hash=sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff \ - --hash=sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78 \ - --hash=sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d \ - --hash=sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863 \ - --hash=sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53 \ - --hash=sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31 \ - --hash=sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15 \ - --hash=sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5 \ - --hash=sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b \ - --hash=sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57 \ - --hash=sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3 \ - --hash=sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1 \ - --hash=sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f \ - --hash=sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad \ - --hash=sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c \ - --hash=sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7 \ - --hash=sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2 \ - --hash=sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b \ - --hash=sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2 \ - --hash=sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b \ - --hash=sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9 \ - --hash=sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be \ - --hash=sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e \ - --hash=sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984 \ - --hash=sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4 \ - --hash=sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074 \ - --hash=sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2 \ - --hash=sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392 \ - --hash=sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91 \ - --hash=sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541 \ - --hash=sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf \ - --hash=sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572 \ - --hash=sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66 \ - --hash=sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575 \ - --hash=sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14 \ - --hash=sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5 \ - --hash=sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1 \ - --hash=sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e \ - --hash=sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551 \ - --hash=sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17 \ - --hash=sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead \ - --hash=sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0 \ - --hash=sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe \ - --hash=sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234 \ - --hash=sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0 \ - --hash=sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7 \ - --hash=sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34 \ - --hash=sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42 \ - --hash=sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385 \ - --hash=sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78 \ - --hash=sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be \ - --hash=sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958 \ - --hash=sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749 \ - --hash=sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec +yarl==1.22.0 \ + --hash=sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a \ + --hash=sha256:029866bde8d7b0878b9c160e72305bbf0a7342bcd20b9999381704ae03308dc8 \ + --hash=sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b \ + --hash=sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da \ + --hash=sha256:07a524d84df0c10f41e3ee918846e1974aba4ec017f990dc735aad487a0bdfdf \ + --hash=sha256:088e4e08f033db4be2ccd1f34cf29fe994772fb54cfe004bbf54db320af56890 \ + --hash=sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093 \ + --hash=sha256:0cf71bf877efeac18b38d3930594c0948c82b64547c1cf420ba48722fe5509f6 \ + --hash=sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79 \ + --hash=sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683 \ + --hash=sha256:10619d9fdee46d20edc49d3479e2f8269d0779f1b031e6f7c2aa1c76be04b7ed \ + --hash=sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2 \ + --hash=sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff \ + --hash=sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02 \ + --hash=sha256:14291620375b1060613f4aab9ebf21850058b6b1b438f386cc814813d901c60b \ + --hash=sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03 \ + --hash=sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511 \ + --hash=sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c \ + --hash=sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124 \ + --hash=sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c \ + --hash=sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da \ + --hash=sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2 \ + --hash=sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0 \ + --hash=sha256:2e4e1f6f0b4da23e61188676e3ed027ef0baa833a2e633c29ff8530800edccba \ + --hash=sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d \ + --hash=sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53 \ + --hash=sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138 \ + --hash=sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4 \ + --hash=sha256:3aa27acb6de7a23785d81557577491f6c38a5209a254d1191519d07d8fe51748 \ + --hash=sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7 \ + --hash=sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d \ + --hash=sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503 \ + --hash=sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d \ + --hash=sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2 \ + --hash=sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa \ + --hash=sha256:437840083abe022c978470b942ff832c3940b2ad3734d424b7eaffcd07f76737 \ + --hash=sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f \ + --hash=sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1 \ + --hash=sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d \ + --hash=sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694 \ + --hash=sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3 \ + --hash=sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a \ + --hash=sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d \ + --hash=sha256:4dcc74149ccc8bba31ce1944acee24813e93cfdee2acda3c172df844948ddf7b \ + --hash=sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a \ + --hash=sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6 \ + --hash=sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b \ + --hash=sha256:595697f68bd1f0c1c159fcb97b661fc9c3f5db46498043555d04805430e79bea \ + --hash=sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5 \ + --hash=sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f \ + --hash=sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df \ + --hash=sha256:5cdac20da754f3a723cceea5b3448e1a2074866406adeb4ef35b469d089adb8f \ + --hash=sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b \ + --hash=sha256:5dbeefd6ca588b33576a01b0ad58aa934bc1b41ef89dee505bf2932b22ddffba \ + --hash=sha256:62441e55958977b8167b2709c164c91a6363e25da322d87ae6dd9c6019ceecf9 \ + --hash=sha256:663e1cadaddae26be034a6ab6072449a8426ddb03d500f43daf952b74553bba0 \ + --hash=sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6 \ + --hash=sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b \ + --hash=sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967 \ + --hash=sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2 \ + --hash=sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708 \ + --hash=sha256:6dcbb0829c671f305be48a7227918cfcd11276c2d637a8033a99a02b67bf9eda \ + --hash=sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8 \ + --hash=sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10 \ + --hash=sha256:75976c6945d85dbb9ee6308cd7ff7b1fb9409380c82d6119bd778d8fcfe2931c \ + --hash=sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b \ + --hash=sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028 \ + --hash=sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e \ + --hash=sha256:80ddf7a5f8c86cb3eb4bc9028b07bbbf1f08a96c5c0bc1244be5e8fefcb94147 \ + --hash=sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33 \ + --hash=sha256:84fc3ec96fce86ce5aa305eb4aa9358279d1aa644b71fab7b8ed33fe3ba1a7ca \ + --hash=sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590 \ + --hash=sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c \ + --hash=sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53 \ + --hash=sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74 \ + --hash=sha256:99b6fc1d55782461b78221e95fc357b47ad98b041e8e20f47c1411d0aacddc60 \ + --hash=sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f \ + --hash=sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1 \ + --hash=sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27 \ + --hash=sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520 \ + --hash=sha256:a4fcfc8eb2c34148c118dfa02e6427ca278bfd0f3df7c5f99e33d2c0e81eae3e \ + --hash=sha256:a899cbd98dce6f5d8de1aad31cb712ec0a530abc0a86bd6edaa47c1090138467 \ + --hash=sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca \ + --hash=sha256:af74f05666a5e531289cb1cc9c883d1de2088b8e5b4de48004e5ca8a830ac859 \ + --hash=sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273 \ + --hash=sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e \ + --hash=sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601 \ + --hash=sha256:b580e71cac3f8113d3135888770903eaf2f507e9421e5697d6ee6d8cd1c7f054 \ + --hash=sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376 \ + --hash=sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7 \ + --hash=sha256:b85b982afde6df99ecc996990d4ad7ccbdbb70e2a4ba4de0aecde5922ba98a0b \ + --hash=sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb \ + --hash=sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65 \ + --hash=sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784 \ + --hash=sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71 \ + --hash=sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b \ + --hash=sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a \ + --hash=sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c \ + --hash=sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face \ + --hash=sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d \ + --hash=sha256:c7bd6683587567e5a49ee6e336e0612bec8329be1b7d4c8af5687dcdeb67ee1e \ + --hash=sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e \ + --hash=sha256:cb95a9b1adaa48e41815a55ae740cfda005758104049a640a398120bf02515ca \ + --hash=sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9 \ + --hash=sha256:d332fc2e3c94dad927f2112395772a4e4fedbcf8f80efc21ed7cdfae4d574fdb \ + --hash=sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95 \ + --hash=sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed \ + --hash=sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf \ + --hash=sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca \ + --hash=sha256:dd7afd3f8b0bfb4e0d9fc3c31bfe8a4ec7debe124cfd90619305def3c8ca8cd2 \ + --hash=sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62 \ + --hash=sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df \ + --hash=sha256:e1b329cb8146d7b736677a2440e422eadd775d1806a81db2d4cded80a48efc1a \ + --hash=sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67 \ + --hash=sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f \ + --hash=sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529 \ + --hash=sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486 \ + --hash=sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a \ + --hash=sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e \ + --hash=sha256:e81fda2fb4a07eda1a2252b216aa0df23ebcd4d584894e9612e80999a78fd95b \ + --hash=sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74 \ + --hash=sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d \ + --hash=sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b \ + --hash=sha256:f0d97c18dfd9a9af4490631905a3f131a8e4c9e80a39353919e2cfed8f00aedc \ + --hash=sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2 \ + --hash=sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e \ + --hash=sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8 \ + --hash=sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82 \ + --hash=sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd \ + --hash=sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249 # via aiohttp From 97eef2240dba60bf5c1f4ce95a19010c8dc47f10 Mon Sep 17 00:00:00 2001 From: Fabien Amelinck Date: Tue, 24 Feb 2026 11:31:44 +0100 Subject: [PATCH 2/8] fix(net2mongo): parsing of legacy netmask configuration (#648) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Fixed - [NETWORK] Improve rc.conf networking lines' parsing patterns See: https://github.com/VultureProject/vulture-gui/pull/623 --------- Co-authored-by: Théo Bertin --- CHANGELOG | 2 + .../home/vlt-os/scripts/net2mongo.py | 169 +--- vulture_os/toolkit/network/network.py | 197 ++++- vulture_os/toolkit/tests/test_network.py | 756 ++++++++++++++++++ 4 files changed, 945 insertions(+), 179 deletions(-) create mode 100644 vulture_os/toolkit/tests/test_network.py diff --git a/CHANGELOG b/CHANGELOG index ca9b10370..0dee92aa7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - yarl 1.9.4 -> 1.22.0 - python-ldap 3.4.4 -> 3.4.5 - werkzeug 3.1.3 -> 3.1.5 +### Fixed +- [NETWORK] Improve rc.conf networking lines' parsing patterns ## [2.35.0] - 2026-02-06 diff --git a/home/jails.apache/.zfs-source/home/vlt-os/scripts/net2mongo.py b/home/jails.apache/.zfs-source/home/vlt-os/scripts/net2mongo.py index 26278ff0b..1c26be581 100644 --- a/home/jails.apache/.zfs-source/home/vlt-os/scripts/net2mongo.py +++ b/home/jails.apache/.zfs-source/home/vlt-os/scripts/net2mongo.py @@ -36,7 +36,13 @@ from system.cluster.models import (Cluster, NetworkInterfaceCard, NetworkAddress, NetworkAddressNIC) - +from toolkit.network.network import ( + PATTERN_IFACE_NAME, + PATTERN_IFCONFIG, + parse_ifconfig_key, + parse_ifconfig_values, + parse_gateway_config +) import logging logging.config.dictConfig(settings.LOG_SETTINGS) @@ -45,29 +51,6 @@ import re import subprocess -PATTERN_IFCONFIG = re.compile('^ifconfig_(.*)="?\'?([^"\']*)"?\'?') -PATTERN_GATEWAY = re.compile("^defaultrouter=(.*)") -PATTERN_GATEWAY6 = re.compile("^ipv6_defaultrouter=(.*)") -# Handles almost all types of IPv6 formats -PATTERN_INET6 = re.compile(r"(inet6 )?(.* )?(((([0-9A-Fa-f]{1,4}:){1,6}:)|(([0-9A-Fa-f]{1,4}:){7}))([0-9A-Fa-f]{1,4}))(( prefixlen )|(/))([0-9\.]{1,3})") -PATTERN_INET = re.compile(r"(inet )?(.* )?(([0-9]{1,3}\.){3}[0-9]{1,3})(( netmask )|(\/))([0-9\.]{1,2})( .*)?") -# Correct group number for the pattern matches above, to get IP/prefix from it -# WARNING change those groups if you change the patterns above! -PATTERN_INET_IP_GROUP = 3 -PATTERN_INET_PREFIX_OR_NETMASK_GROUP = 8 -PATTERN_INET6_IP_GROUP = 3 -PATTERN_INET6_PREFIX_OR_NETMASK_GROUP = 13 -PATTERN_ALIAS = re.compile(r"( |^)alias( |$)") -PATTERN_IFACE_NAME = re.compile("([a-z]+)([0-9]+)") -PATTERN_VLAN = re.compile("vlan ([0-9]+)") -PATTERN_VLANDEV = re.compile("vlandev ([a-z0-9\.]+)") -PATTERN_LAGGPROTO = re.compile("laggproto ([a-z]+)") -PATTERN_LAGGPORT = re.compile("laggport ([a-z0-9]+)") -PATTERN_CARP_VHID = re.compile(r"( |^)vhid ([0-9]+)( |$)") -PATTERN_CARP_ADVSKEW = re.compile(r"( |^)advskew ([0-9]+)( |$)") -PATTERN_CARP_PASS = re.compile(r"( |^)pass ([0-9a-zA-Z]+)( |$)") -PATTERN_FIB = re.compile("fib ([0-9])") - def refresh_physical_NICs(node): """ Get physical NICs """ # Remove all 'unused' interfaces (may be reimported with the next for loop) @@ -75,8 +58,8 @@ def refresh_physical_NICs(node): for to_delete in deletion_list: iface_name_match = re.search(PATTERN_IFACE_NAME, to_delete.dev) if iface_name_match: - name = iface_name_match.group(1) - iface_id = iface_name_match.group(2) + name = iface_name_match.group("name") + iface_id = iface_name_match.group("id") # Only remove interfaces that cannot represent a NetworkAddress if not NetworkAddress.objects.filter(type=name, iface_id=iface_id).exists(): logger.info(f"Node::refresh_physical_NICs: Deleting obsolete interface {to_delete.dev}") @@ -89,7 +72,7 @@ def refresh_physical_NICs(node): d, created = NetworkInterfaceCard.objects.get_or_create( dev=nic, node=node) - if created: + if not created: logger.debug("Node::refresh_physical_NICs: NIC {} exists in database".format(d.dev)) else: logger.info("Node::refresh_physical_NICs: Creating NIC {}".format(nic)) @@ -98,128 +81,6 @@ def refresh_physical_NICs(node): logger.exception(e) -def parse_ifconfig_key(line, config): - split = line.split("_") - - if len(split) > 3: - logger.error(f"Node::parse_ifconfig_key: could not parse line '{line}'," - " problem is on '{tmp}' (too many '_', don't know how to read)") - return False - - if "ipv6" in split: - split.remove('ipv6') - config['ipv6'] = True - config['family'] = 'inet6' - else: - config['family'] = 'inet' - - if "alias" in split[-1]: - logger.debug("Node::parse_ifconfig_key: line is an alias") - config['nic'] = [split[0]] - config['type'] = 'alias' - - iface_name_match = re.search(PATTERN_IFACE_NAME, split[-1]) - if not iface_name_match: - return False - - config['name'] = iface_name_match.group(1) - config['iface_id'] = iface_name_match.group(2) - if config['name'] == 'vlan': - logger.debug("Node::parse_ifconfig_key: line is a vlan configuration") - config['type'] = 'vlan' - if config['name'] == 'lagg': - logger.debug("Node::parse_ifconfig_key: line is a lagg configuration") - config['type'] = 'lagg' - - return True - - -def parse_ifconfig_values(line, config): - parse_success = False - - if line.upper() in ['DHCP', 'SYNCDHCP']: - logger.debug("Node::parse_ifconfig_values: interface is configured for DHCP") - config['dhcp'] = True - config['type'] = "system" - return True - - if config.get('ipv6'): - pattern = PATTERN_INET6 - ip_group = PATTERN_INET_IP_GROUP - prefix_or_netmask_group = PATTERN_INET6_PREFIX_OR_NETMASK_GROUP - else: - pattern = PATTERN_INET - ip_group = PATTERN_INET6_IP_GROUP - prefix_or_netmask_group = PATTERN_INET_PREFIX_OR_NETMASK_GROUP - - inet_match = re.search(pattern, line) - if inet_match: - logger.debug("Node::parse_ifconfig_values: interface has an IP") - parse_success = True - config['ip'] = inet_match.group(ip_group) - logger.debug(f"Node::parse_ifconfig_values: IP {inet_match.group(ip_group)}") - config['prefix_or_netmask'] = inet_match.group(prefix_or_netmask_group) - if 'type' not in config: - if re.search(PATTERN_ALIAS, line): - config['type'] = 'alias' - else: - config['type'] = 'system' - - if carp_vhid_match := re.search(PATTERN_CARP_VHID, line): - logger.debug(f"Node::parse_ifconfig_values: Found CARP VHID {carp_vhid_match.group(2)}") - config['carp_vhid'] = carp_vhid_match.group(2) - - if carp_prio_match := re.search(PATTERN_CARP_ADVSKEW, line): - logger.debug(f"Node::parse_ifconfig_values: Found CARP skew {carp_prio_match.group(2)}") - config['carp_priority'] = carp_prio_match.group(2) - - if carp_pass_match := re.search(PATTERN_CARP_PASS, line): - logger.debug("Node::parse_ifconfig_values: Found CARP password") - config['carp_password'] = carp_pass_match.group(2) - - fib_match = re.search(PATTERN_FIB, line) - if fib_match: - logger.debug("Node::parse_ifconfig_values: interface has specific fib") - config['fib'] = fib_match.group(1) - - vlan_match = re.search(PATTERN_VLAN, line) - vlandev_match = re.search(PATTERN_VLANDEV, line) - if vlan_match and vlandev_match: - logger.debug("Node::parse_ifconfig_values: interface has vlan parameters") - parse_success = True - config['vlan'] = vlan_match.group(1) - config['nic'] = [vlandev_match.group(1)] - - laggproto_match = re.search(PATTERN_LAGGPROTO, line) - laggport_matches = re.findall(PATTERN_LAGGPORT, line) - if laggproto_match and laggport_matches: - logger.debug("Node::parse_ifconfig_values: interface is a Link Aggregation") - parse_success = True - config['lagg_proto'] = laggproto_match.group(1) - config['nic'] = laggport_matches - logger.debug("line does not define network configuration: configurations are " - f"laggproto = {config['lagg_proto']}, laggports = {config['nic']}") - - return parse_success - - -def parse_gateway_config(line, config): - gateway_match = re.search(PATTERN_GATEWAY, line) - have_gateway = False - if gateway_match: - logger.debug("Node::parse_gateway_config: this is a gateway (ipv4) configuration line") - config['defaultgateway'] = gateway_match.group(1) - have_gateway = True - - gateway6_match = re.search(PATTERN_GATEWAY6, line) - if gateway6_match: - logger.debug("Node::parse_gateway_config: this is a gateway (ipv6) configuration line") - config['defaultgateway_ipv6'] = gateway6_match.group(1) - have_gateway = True - - return have_gateway - - if __name__ == "__main__": this_node = Cluster.get_current_node() @@ -239,8 +100,8 @@ def parse_gateway_config(line, config): ifconfig_parsed = False if ifconfig_match: - key = ifconfig_match.group(1) - value = ifconfig_match.group(2) + key = ifconfig_match.group("key") + value = ifconfig_match.group("value") key_parsed = parse_ifconfig_key(key, config) @@ -354,12 +215,12 @@ def parse_gateway_config(line, config): 'name': config['name'] + config['iface_id'], 'ip': config.get('ip'), 'prefix_or_netmask': config.get('prefix_or_netmask'), - 'fib': config.get('fib', 0), + 'fib': config.get('fib', 0), 'carp_vhid': config.get('carp_vhid', 0), 'vlan': config.get('vlan', 0), 'lagg_proto': config.get('lagg_proto', ''), }) - + logger.info("Node::network_sync: {} Network Address configuration {}".format("created" if created else "updated", address)) @@ -374,7 +235,7 @@ def parse_gateway_config(line, config): "carp_priority": config.get('carp_priority', 0), "carp_passwd": config.get('carp_password', ''), } - ) + ) logger.info("Node::network_sync: {} link {}".format("created" if created else "updated", address_nic)) except Exception as e: logger.error(f"Node::network_sync: Could not create link {address} -> {iface}") diff --git a/vulture_os/toolkit/network/network.py b/vulture_os/toolkit/network/network.py index d574aef53..b0b44bee7 100644 --- a/vulture_os/toolkit/network/network.py +++ b/vulture_os/toolkit/network/network.py @@ -66,6 +66,149 @@ }, } +PATTERN_IFCONFIG = re.compile(r"^ifconfig_(?P[a-z]{1}[a-z0-9_]+)=([\"'])(?:(?=(\\?))\3)(?P.*)\2") +PATTERN_GATEWAY = re.compile(r"^defaultrouter=([\"'])(?:(?=(\\?))\2)(?P.+)\1") +PATTERN_GATEWAY6 = re.compile(r"^ipv6_defaultrouter=([\"'])(?:(?=(\\?))\2)(?P.+)\1") +# Handles all types of IPv6 formats +PATTERN_INET6 = re.compile(r"(inet6|^)( *)(?P(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))( prefixlen |\/)(?P[0-9\.]{1,3})") +PATTERN_INET = re.compile(r"(inet|^)( *)(?P((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4})( netmask (?P[0-9\.]+)|\/(?P[0-9]{1,2}))( .*)?") +# Correct group name for the pattern matches above, to get IP/prefix from it +# WARNING change those groups if you change the patterns above! +PATTERN_INET_IP_GROUP = "ip" +PATTERN_INET_PREFIX_OR_NETMASK_GROUP = "netmask" +PATTERN_INET6_IP_GROUP = "ip" +PATTERN_INET6_PREFIX_OR_NETMASK_GROUP = "prefix" +PATTERN_ALIAS = re.compile(r"( |^)alias( |$)") +PATTERN_IFACE_NAME = re.compile(r"(?P[a-z]+)(?P[0-9]+)") +PATTERN_VLAN = re.compile(r"( |^)vlan (?P[0-9]+)( |$)") +PATTERN_VLANDEV = re.compile(r"( |^)vlandev (?P[a-z0-9\.]+)( |$)") +PATTERN_LAGGPROTO = re.compile(r"( |^)laggproto (?P[a-z]+)( |$)") +PATTERN_LAGGPORT = re.compile(r"laggport ([a-z0-9]+)") +PATTERN_CARP_VHID = re.compile(r"( |^)vhid (?P[0-9]+)( |$)") +PATTERN_CARP_ADVSKEW = re.compile(r"( |^)advskew (?P[0-9]+)( |$)") +PATTERN_CARP_PASS = re.compile(r"( |^)pass (?P[0-9a-zA-Z]+)( |$)") +PATTERN_FIB = re.compile(r"( |^)fib (?P[0-9])( |$)") + + +def parse_ifconfig_key(line, config): + split = line.split("_") + + if len(split) > 3: + logger.error(f"parse_ifconfig_key: could not parse line '{line}', (too many '_', don't know how to read)") + return False + + if "ipv6" in split: + split.remove('ipv6') + config['ipv6'] = True + config['family'] = 'inet6' + else: + config['family'] = 'inet' + + if "alias" in split[-1]: + logger.debug("parse_ifconfig_key: line is an alias") + config['nic'] = [split[0]] + config['type'] = 'alias' + + iface_name_match = re.search(PATTERN_IFACE_NAME, split[-1]) + if not iface_name_match: + return False + + config['name'] = iface_name_match.group("name") + config['iface_id'] = iface_name_match.group("id") + if config['name'] == 'vlan': + logger.debug("parse_ifconfig_key: line is a vlan configuration") + config['type'] = 'vlan' + if config['name'] == 'lagg': + logger.debug("parse_ifconfig_key: line is a lagg configuration") + config['type'] = 'lagg' + + return True + + +def parse_ifconfig_values(line, config): + parse_success = False + + if line.upper() in ['DHCP', 'SYNCDHCP']: + logger.debug("parse_ifconfig_values: interface is configured for DHCP") + config['dhcp'] = True + config['type'] = "system" + return True + + if config.get('ipv6'): + pattern = PATTERN_INET6 + else: + pattern = PATTERN_INET + + inet_match = re.search(pattern, line) + if inet_match: + logger.debug("parse_ifconfig_values: interface has an IP") + parse_success = True + config['ip'] = inet_match.group('ip') + logger.debug(f"parse_ifconfig_values: IP {config['ip']}") + if 'netmask' in inet_match.groupdict().keys() and inet_match.group('netmask'): + config['prefix_or_netmask'] = inet_match.group('netmask') + elif 'prefix' in inet_match.groupdict().keys() and inet_match.group('prefix'): + config['prefix_or_netmask'] = inet_match.group('prefix') + if 'type' not in config: + if re.search(PATTERN_ALIAS, line): + config['type'] = 'alias' + else: + config['type'] = 'system' + + if carp_vhid_match := re.search(PATTERN_CARP_VHID, line): + logger.debug(f"parse_ifconfig_values: Found CARP VHID {carp_vhid_match.group('vhid')}") + config['carp_vhid'] = carp_vhid_match.group("vhid") + + if carp_prio_match := re.search(PATTERN_CARP_ADVSKEW, line): + logger.debug(f"parse_ifconfig_values: Found CARP skew {carp_prio_match.group('priority')}") + config['carp_priority'] = carp_prio_match.group("priority") + + if carp_pass_match := re.search(PATTERN_CARP_PASS, line): + logger.debug("parse_ifconfig_values: Found CARP password") + config['carp_password'] = carp_pass_match.group("password") + + fib_match = re.search(PATTERN_FIB, line) + if fib_match: + logger.debug("parse_ifconfig_values: interface has specific fib") + config['fib'] = fib_match.group("fib") + + vlan_match = re.search(PATTERN_VLAN, line) + vlandev_match = re.search(PATTERN_VLANDEV, line) + if vlan_match and vlandev_match: + logger.debug("parse_ifconfig_values: interface has vlan parameters") + parse_success = True + config['vlan'] = vlan_match.group("vlan") + config['nic'] = [vlandev_match.group("nic")] + + laggproto_match = re.search(PATTERN_LAGGPROTO, line) + laggport_matches = re.findall(PATTERN_LAGGPORT, line) + if laggproto_match and laggport_matches and len(laggport_matches) > 1: + logger.debug("parse_ifconfig_values: interface is a Link Aggregation") + parse_success = True + config['lagg_proto'] = laggproto_match.group("proto") + config['nic'] = laggport_matches + logger.debug("line does not define network configuration: configurations are " + f"laggproto = {config['lagg_proto']}, laggports = {config['nic']}") + + return parse_success + + +def parse_gateway_config(line, config): + gateway_match = re.search(PATTERN_GATEWAY, line) + have_gateway = False + if gateway_match: + logger.debug("parse_gateway_config: this is a gateway (ipv4) configuration line") + config['defaultgateway'] = gateway_match.group("gateway") + have_gateway = True + + gateway6_match = re.search(PATTERN_GATEWAY6, line) + if gateway6_match: + logger.debug("parse_gateway_config: this is a gateway (ipv6) configuration line") + config['defaultgateway_ipv6'] = gateway6_match.group("gateway") + have_gateway = True + + return have_gateway + def is_valid_ip4(ip: str) -> bool: try: @@ -74,6 +217,7 @@ def is_valid_ip4(ip: str) -> bool: except AddressValueError: return False + def is_valid_ip6(ip: str) -> bool: try: IPv6Address(ip) @@ -81,12 +225,15 @@ def is_valid_ip6(ip: str) -> bool: except AddressValueError: return False + def is_valid_ip(ip: str) -> bool: return is_valid_ip4(ip) or is_valid_ip6(ip) + def is_loopback(name: str) -> bool: return name.startswith("lo") + def is_valid_hostname(hostname: str) -> bool: # Solution taken from this SO answer: https://stackoverflow.com/a/33214423 if hostname[-1] == ".": @@ -267,16 +414,16 @@ def ifconfig_call(logger, netif_id): _, error = proc.communicate() if error: - logger.error("Node::ifconfig_call() Error on '{}' with IP '{}': {}".format( + logger.error("ifconfig_call() Error on '{}' with IP '{}': {}".format( dev, netif.ip_cidr, str(error))) ret = False continue else: - logger.info("Node::ifconfig_call() {}: IP address {} is UP".format(dev, netif.ip_cidr)) + logger.info("ifconfig_call() {}: IP address {} is UP".format(dev, netif.ip_cidr)) continue except Exception as e: - logger.error("Node::ifconfig_call(): {}".format(str(e))) + logger.error("ifconfig_call(): {}".format(str(e))) ret = False continue @@ -318,14 +465,14 @@ def address_cleanup(logger): netif.prefix = netif.prefix_or_netmask if netif.family == "inet" and str(netif.prefix) == str(prefix): - logger.debug("Node::address_cleanup(): IPv4 {}/{} has been found on {}".format( + logger.debug("address_cleanup(): IPv4 {}/{} has been found on {}".format( ip, prefix, nic.dev )) found = True elif netif.family == "inet6" and str(prefix) == str(netif.prefix_or_netmask): - logger.debug("Node::address_cleanup(): IPv6 {}/{} has been found on {}".format( + logger.debug("address_cleanup(): IPv6 {}/{} has been found on {}".format( ip, prefix, nic.dev @@ -335,11 +482,11 @@ def address_cleanup(logger): """ IP Address not found: Delete it """ if not found: logger.info( - "Node::address_cleanup(): Deleting {}/{} on {}".format( + "address_cleanup(): Deleting {}/{} on {}".format( ip, prefix, nic.dev )) - logger.debug('Node::address_cleanup() /usr/local/bin/sudo /sbin/ifconfig {} {} {} delete'.format( + logger.debug('address_cleanup() /usr/local/bin/sudo /sbin/ifconfig {} {} {} delete'.format( nic.dev, family, str(ip) + "/" + str(prefix)) ) @@ -352,7 +499,7 @@ def address_cleanup(logger): success, error = proc.communicate() if error: logger.error( - "Node::address_cleanup(): {}".format(str(error))) + "address_cleanup(): {}".format(str(error))) return ret @@ -366,10 +513,10 @@ def destroy_virtual_interface(logger, iface_name): """ ret = True - logger.info(f"Node::destroy_virtual_interface: destroying interface {iface_name}") + logger.info(f"destroy_virtual_interface: destroying interface {iface_name}") _, error = subprocess.Popen(['/usr/local/bin/sudo', '/sbin/ifconfig', iface_name, 'destroy']).communicate() if error: - logger.error(f"Node::destroy_virtual_interface: Could not destroy interface -> {str(error)}") + logger.error(f"destroy_virtual_interface: Could not destroy interface -> {str(error)}") ret = False return ret @@ -384,10 +531,10 @@ def create_virtual_interface(logger, iface_name): """ ret = True - logger.info(f"Node::create_virtual_interface: creating interface {iface_name}") + logger.info(f"create_virtual_interface: creating interface {iface_name}") _, error = subprocess.Popen(['/usr/local/bin/sudo', '/sbin/ifconfig', iface_name, 'create']).communicate() if error: - logger.error(f"Node::create_virtual_interface: Could not create interface -> {str(error)}") + logger.error(f"create_virtual_interface: Could not create interface -> {str(error)}") ret = False return ret @@ -409,7 +556,7 @@ def write_management_ips(logger): filename='network') if not status: logger.error( - f"Node::write_management_ips: Could not update value of {attr} -> {error}") + f"write_management_ips: Could not update value of {attr} -> {error}") def write_network_config(logger): @@ -435,10 +582,10 @@ def write_network_config(logger): filename="network", operation="+=") if not status: - logger.error(f"Node::write_network_config: Could not add {main_iface}" + logger.error(f"write_network_config: Could not add {main_iface}" f" to the list of cloned interfaces: {error}") else: - logger.info(f"Node::write_network_config: Added {main_iface} to the list of cloned interfaces") + logger.info(f"write_network_config: Added {main_iface} to the list of cloned interfaces") nodes_configurations = address.rc_config(node_id=node.pk) for configuration in nodes_configurations[node.pk]: @@ -446,14 +593,14 @@ def write_network_config(logger): status, error = set_rc_config(**configuration) if not status: logger.error( - "Node::write_network_config() {}:{}: {}".format( + "write_network_config() {}:{}: {}".format( nic.dev, address.ip_cidr, str(error)) ) ret = False continue else: logger.info( - "Node::write_network_config() {}:{}: Ok".format( + "write_network_config() {}:{}: Ok".format( nic.dev, address.ip_cidr) ) continue @@ -478,21 +625,21 @@ def write_network_config(logger): # Remove all past routing config status, removed = remove_rc_config(".*route.*") - logger.info(f"Node::write_network_config(): removed old routing configurations {removed}") + logger.info(f"write_network_config(): removed old routing configurations {removed}") # Apply configurations - logger.info(f"Node::write_network_config(): setting new routing configuration {configs}") + logger.info(f"write_network_config(): setting new routing configuration {configs}") for config in configs: status, error = set_rc_config(variable=config[0], value=config[1]) if not status: logger.error( - f"Node::write_network_config(routing): {config[0]} -> {str(error)}" + f"write_network_config(routing): {config[0]} -> {str(error)}" ) ret = False continue else: logger.info( - f"Node::write_network_config(routing): {config[0]} -> Ok" + f"write_network_config(routing): {config[0]} -> Ok" ) continue @@ -520,9 +667,9 @@ def remove_netif_configs(logger, rc_confs): message += str(tmp) + "\n" if not status: - logger.error(f"Node::remove_netif_configs: a problem occurred while trying to remove configuration {rc_conf}") + logger.error(f"remove_netif_configs: a problem occurred while trying to remove configuration {rc_conf}") else: - logger.info(f"Node::remove_netif_configs: successfuly removed configuration {rc_conf}") + logger.info(f"remove_netif_configs: successfuly removed configuration {rc_conf}") return message @@ -541,9 +688,9 @@ def restart_routing(logger): proc.communicate() except Exception as e: - logger.error("Node::restart_routing(): {}".format(str(e))) + logger.error("restart_routing(): {}".format(str(e))) return False - logger.info("Node::restart_routing(): OK") + logger.info("restart_routing(): OK") return True diff --git a/vulture_os/toolkit/tests/test_network.py b/vulture_os/toolkit/tests/test_network.py new file mode 100644 index 000000000..88cb75026 --- /dev/null +++ b/vulture_os/toolkit/tests/test_network.py @@ -0,0 +1,756 @@ +#!/home/vlt-os/env/bin/python +"""This file is part of Vulture OS. + +Vulture OS is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Vulture OS is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Vulture OS. If not, see http://www.gnu.org/licenses/. +""" + +__author__ = "Théo BERTIN" +__credits__ = [] +__license__ = "GPLv3" +__version__ = "4.0.0" +__maintainer__ = "Vulture OS" +__email__ = "contact@vultureproject.org" +__doc__ = 'Tests for datetime/timezone.py' + +import re + +from django.test import SimpleTestCase +from unittest.mock import patch + +from toolkit.network.network import ( + parse_ifconfig_key, + parse_ifconfig_values, + parse_gateway_config, + PATTERN_IFCONFIG +) + +class NetworkTestCase(SimpleTestCase): + TEST_CASE_NAME=f"{__name__}" + def setUp(self): + # Prevent logger from printing logs to stdout during tests + self.logger_patcher = patch('toolkit.network.network.logger') + self.logger_patcher.start() + + def tearDown(self) -> None: + # Cleanly remove the logger patch + self.logger_patcher.stop() + return super().tearDown() + + +#################### +# PATTERN_IFCONFIG # +#################### + def test_PATTERN_IFCONFIG_valid_formats(self): + for TEST_LINE, EXPECTED_KEY, EXPECTED_VALUE in [ + ( + # valid key and value, double-quotes + 'ifconfig_em0="inet 192.168.1.1/24"', + 'em0', + 'inet 192.168.1.1/24' + ), + ( + # valid key and value, single-quotes + "ifconfig_vtnet1='inet6 2001:db8:0:0:0:1/64'", + 'vtnet1', + 'inet6 2001:db8:0:0:0:1/64' + ), + ( + # alias key suffix + 'ifconfig_vmx0_alias0="inet 127.0.10.1/32"', + 'vmx0_alias0', + 'inet 127.0.10.1/32' + ), + ( + # value with escaped double-quotes + 'ifconfig_igb1="inet 127.0.10.1/32 vhid 42 advskew 100 pass \\"super secret pass\\""', + 'igb1', + 'inet 127.0.10.1/32 vhid 42 advskew 100 pass \\"super secret pass\\"' + ), + ]: + match = re.search(PATTERN_IFCONFIG, TEST_LINE) + self.assertIsNotNone(match, f"line '{TEST_LINE}' did not parse successfully") + key = match.group("key") + value = match.group("value") + self.assertEqual(key, EXPECTED_KEY) + self.assertEqual(value, EXPECTED_VALUE) + + def test_PATTERN_IFCONFIG_invalid_formats(self): + for TEST_LINE in [ + 'ifconfig_em0=inet 192.168.1.1/24', # no quote + 'ifconfig_vmx0_alias0=inet 127.0.10.1/32"', # missing quote before + 'ifconfig_vmx0_alias0="inet 127.0.10.1/32', # missing quote after + "ifconfig_vtnet1 = 'inet6 2001:db8:0:0:0:1/64'", # missing quote before + 'em0="inet 192.168.1.1/24"', # ifconfig prefix missing (plain variable) + 'IFCONFIG_em0="inet 192.168.1.1/24"', # Uppercase IFCONFIG prefix + 'ifconfig_em-0="inet 192.168.1.1/24"', # Interface name with hyphen (invalid in FreeBSD) + 'ifconfig_0em="inet 192.168.1.1/24"', # Interface name starting with digit + ]: + match = re.search(PATTERN_IFCONFIG, TEST_LINE) + self.assertIsNone(match, f"line '{TEST_LINE}' shouldn't parse successfully") + +###################### +# parse_ifconfig_key # +###################### + def test_parse_ifconfig_key_no_value(self): + TEST_LINE = '' + config = dict() + self.assertFalse(parse_ifconfig_key(TEST_LINE, config)) + + def test_parse_ifconfig_key_wrong_name_format(self): + TEST_LINE = 'foo' + config = dict() + self.assertFalse(parse_ifconfig_key(TEST_LINE, config)) + + def test_parse_ifconfig_key_too_many_underscores(self): + TEST_LINE = 'ifconfig_foo_bar_baz' + config = dict() + self.assertFalse(parse_ifconfig_key(TEST_LINE, config)) + + def test_parse_ifconfig_key_name_formats(self): + for TEST_LINE in [ + 'em0', + 'vtnet1', + 'vmx2', + 'igb0', + 'gif3', + 'wg2', + 'tun0', + 'bridge5', + 'carp10', + 'vlan128', + 'epair0a', + ]: + config = dict() + self.assertTrue(parse_ifconfig_key(TEST_LINE, config)) + + def test_parse_ifconfig_key_ipv4(self): + TEST_LINE = 'vtnet0' + config = dict() + self.assertTrue(parse_ifconfig_key(TEST_LINE, config)) + self.assertDictEqual( + config, + { + 'family': 'inet', + 'name': 'vtnet', + 'iface_id': '0', + }) + + def test_parse_ifconfig_key_ipv6(self): + TEST_LINE = 'em1_ipv6' + config = dict() + self.assertTrue(parse_ifconfig_key(TEST_LINE, config)) + self.assertDictEqual( + config, + { + 'family': 'inet6', + 'ipv6': True, + 'name': 'em', + 'iface_id': '1', + }) + + def test_parse_ifconfig_key_alias(self): + TEST_LINE = 'vmx2_alias1' + config = dict() + self.assertTrue(parse_ifconfig_key(TEST_LINE, config)) + self.assertDictEqual( + config, + { + 'family': 'inet', + 'name': 'alias', + 'iface_id': '1', + 'type': 'alias', + 'nic': ['vmx2'], + }) + + def test_parse_ifconfig_key_ipv6_alias(self): + TEST_LINE = 'vmx3_ipv6_alias10' + config = dict() + self.assertTrue(parse_ifconfig_key(TEST_LINE, config)) + self.assertDictEqual( + config, + { + 'family': 'inet6', + 'ipv6': True, + 'name': 'alias', + 'iface_id': '10', + 'type': 'alias', + 'nic': ['vmx3'], + }) + + def test_parse_ifconfig_key_vlan(self): + TEST_LINE = 'vlan128' + config = dict() + self.assertTrue(parse_ifconfig_key(TEST_LINE, config)) + self.assertDictEqual( + config, + { + 'family': 'inet', + 'name': 'vlan', + 'iface_id': '128', + 'type': 'vlan', + }) + + def test_parse_ifconfig_key_vlan_ipv6(self): + TEST_LINE = 'vlan128_ipv6' + config = dict() + self.assertTrue(parse_ifconfig_key(TEST_LINE, config)) + self.assertDictEqual( + config, + { + 'family': 'inet6', + 'ipv6': True, + 'name': 'vlan', + 'iface_id': '128', + 'type': 'vlan', + }) + + def test_parse_ifconfig_key_lagg(self): + TEST_LINE = 'lagg2' + config = dict() + self.assertTrue(parse_ifconfig_key(TEST_LINE, config)) + self.assertDictEqual( + config, + { + 'family': 'inet', + 'name': 'lagg', + 'iface_id': '2', + 'type': 'lagg', + }) + + +######################### +# parse_ifconfig_values # +######################### + def test_parse_ifconfig_values_no_value(self): + TEST_LINE = '' + config = dict() + self.assertFalse(parse_ifconfig_values(TEST_LINE, config)) + + def test_parse_ifconfig_values_wrong_ipv4(self): + for TEST_LINE in [ + 'foo', + 'inet 256.168.1.1/24', # octet out of range + 'inet 192.168.1.1.1/24', # extra octet/dot + 'inet 192.168.1/24', # too few octets/dots + 'inet 192.168.001.1/24', # ambiguous leading zero(s) + 'inet6 192.168.1.1/24', # wrong 'inet6' use + 'inet /24', # missing IP + ]: + config = dict() + self.assertFalse(parse_ifconfig_values(TEST_LINE, config), f"{TEST_LINE} shouldn't be valid") + + def test_parse_ifconfig_values_wrong_ipv6(self): + for TEST_LINE in [ + 'foo', + 'inet6 2001:db8:0:0:0:0:0:0:1/64', # too many groups + 'inet6 2001:db8:0:0:0:1/64', # too few groups + 'inet6 2001:db8:1:2:3:4::5:6:7/64', # too many groups (with double ':') + 'inet6 2001::db8::1/64', # double ':' used twice + 'inet6 2001:db8:::1/64', # triple ':' + 'inet6 :2001:db8::1/64', # starts with single colon (not ::) + 'inet 2001:db8::1/64', # wrong 'inet' use + 'inet6 2001:db8::1:/64', # ends with single colon (not ::) + 'inet6 :/64', # lone colon + ]: + config = {'ipv6': True} + self.assertFalse(parse_ifconfig_values(TEST_LINE, config), f"{TEST_LINE} shouldn't be valid") + + def test_parse_ifconfig_values_dhcp(self): + for TEST_LINE in [ + 'dhcp', + 'DHCP', + 'syncdhcp', + 'SYNCDHCP', + ]: + config = dict() + self.assertTrue(parse_ifconfig_values(TEST_LINE, config)) + self.assertDictEqual( + config, + { + 'dhcp': True, + 'type': 'system', + } + ) + + def test_parse_ifconfig_values_ipv4(self): + for TEST_LINE in [ + "inet 127.0.0.1/32", # IPv4 with /32 (host route) + "inet 10.0.0.1/8", # IPv4 with /8 class A + "inet 172.16.0.1/16", # IPv4 with /16 class B + "inet 192.168.100.1/30", # IPv4 with /30 (point-to-point) + "inet 192.168.1.50/24 up", # IPv4 with extra interface flags + "inet 10.10.0.1/24 mtu 9000", # IPv4 with MTU + "inet 192.168.1.1/24 media autoselect", # IPv4 with media option + ]: + config = dict() + self.assertTrue(parse_ifconfig_values(TEST_LINE, config)) + + def test_parse_ifconfig_values_ipv4_netmask(self): + for TEST_LINE, EXPECTED_CONF in [ + ( + # Basic IPv4 with prefix length + "inet 10.0.0.1/8", + {'ip': '10.0.0.1', 'prefix_or_netmask': '8'} + ), + ( + # Basic IPv4 with prefix length + "inet 172.16.0.1/16", + {'ip': '172.16.0.1', 'prefix_or_netmask': '16'} + ), + ( + # Basic IPv4 with prefix length + "inet 192.168.1.10/24", + {'ip': '192.168.1.10', 'prefix_or_netmask': '24'} + ), + ( + # IPv4 with dotted netmask + "inet 192.168.1.10 netmask 255.255.255.0", + {'ip': '192.168.1.10', 'prefix_or_netmask': '255.255.255.0'} + ), + ( + # IPv4 with dotted netmask + "inet 192.168.1.33 netmask 255.255.255.224", + {'ip': '192.168.1.33', 'prefix_or_netmask': '255.255.255.224'} + ), + ]: + config = dict() + self.assertTrue(parse_ifconfig_values(TEST_LINE, config)) + self.assertDictContainsSubset( + EXPECTED_CONF, + config, + f"failure on line '{TEST_LINE}'" + ) + + def test_parse_ifconfig_values_ipv6(self): + for TEST_LINE in [ + "inet6 2001:0db8:0000:0000:0000:0000:0000:0001/64", # fully expanded + "inet6 2001:0db8:85a3:0000:0000:8a2e:0370:7334/64", # RFC 3849 example + "inet6 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", # all-ones + "inet6 0000:0000:0000:0000:0000:0000:0000:0001/128", # loopback uncompressed + "inet6 0000:0000:0000:0000:0000:0000:0000:0000/0", # default route uncompressed + "inet6 ::/0", # default route (all zeros) + "inet6 ::1/128", # loopback + "inet6 2001:db8::/32", # documentation prefix, :: at end + "inet6 2001:db8::1/64", # :: in middle, single trailing group + "inet6 2001:db8::1:2/64", # :: in middle, two trailing groups + "inet6 2001:db8::1:2:3/64", # :: in middle, three trailing groups + "inet6 2001:db8::1:2:3:4/64", # :: in middle, four trailing groups + "inet6 ::ffff:192.0.2.1/96", # IPv4-mapped (::ffff:a.b.c.d) + "inet6 ::192.0.2.1/96", # IPv4-compatible (deprecated but parseable) + "inet6 fe80::1/64", # link-local, minimal + "inet6 fe80::dead:beef/64", # link-local with hex words + "inet6 fe80::1%em0/64", # link-local with zone ID + "inet6 fe80::1%vlan10/64", # zone ID on VLAN interface + "inet6 fe80::1%carp0/64", # zone ID on CARP interface + "inet6 ff02::1/128", # all-nodes multicast + "inet6 ff02::2/128", # all-routers multicast + "inet6 ff02::1:ff00:1/128", # solicited-node multicast + "inet6 ff05::101/128", # site-local NTP multicast + "inet6 100::1/64", # :: compress in leading position + "inet6 ::1:2:3:4:5:6:7/128", # :: replaces only leading zero group + "inet6 2001:db8::1/0", # default route + "inet6 2001:db8::1/1", + "inet6 2001:db8::1/7", # just below /8 boundary + "inet6 2001:db8::1/8", + "inet6 2001:db8::1/10", # link-local prefix boundary + "inet6 2001:db8::1/16", + "inet6 2001:db8::1/23", # just below /24 + "inet6 2001:db8::1/24", + "inet6 2001:db8::1/32", # typical ISP allocation + "inet6 2001:db8::1/48", # typical site allocation + "inet6 2001:db8::1/56", # typical home allocation + "inet6 2001:db8::1/63", # just below /64 + "inet6 2001:db8::1/64", # most common LAN prefix + "inet6 2001:db8::1/65", # just above /64 + "inet6 2001:db8::1/96", # IPv4-mapped boundary + "inet6 2001:db8::1/127", # point-to-point (RFC 6164) + "inet6 2001:db8::1/128", # host route + "inet6 2001:db8:1:2::1/64", # Global unicast (2000::/3) + "inet6 2600:1f14:1234:5678::1/64", # AWS-style global unicast + "inet6 fc00::1/7", # Unique Local: fc (first half of ULA range) + "inet6 fd00:1:2:3::1/48", # Unique Local: fd prefix, common ULA + "inet6 fdab:cdef:1234:5678::1/64", # Unique Local: random ULA global ID + "inet6 2002:c000:0204::1/16", # 6to4: 2002:::/16 + "inet6 2001:0000:4136:e378:8000:63bf:3fff:fdd2/128", # Teredo (2001::/32) + "inet6 2001:0020::1/28", # ORCHID v2 (2001:20::/28) + "inet6 2001:db8:cafe:babe::1/64", # Documentation (2001:db8::/32) + "inet6 3ffe:1234::1/16", # 6bone legacy (3ffe::/16, historical but parseable) + ]: + config = {'ipv6': True} + self.assertTrue(parse_ifconfig_values(TEST_LINE, config), f"line '{TEST_LINE}' did not pass validation") + + def test_parse_ifconfig_values_ipv6_netmask(self): + for TEST_LINE, EXPECTED_CONF in [ + ( # /0 — Default route (entire IPv6 space) + "inet6 2001:db8::1/0", + {'ip': '2001:db8::1', 'prefix_or_netmask': '0'} + ), + ( # /1–7 — Extremely large allocations (RIR-level) + "inet6 2001:db8::1/6", + {'ip': '2001:db8::1', 'prefix_or_netmask': '6'} + ), + ( # /8–15 — Large regional allocations + "inet6 2001:db8::1/13", + {'ip': '2001:db8::1', 'prefix_or_netmask': '13'} + ), + ( # /65–95 — Unusual subnet sizes (non-standard but valid) + "inet6 2001:db8::1/78", + {'ip': '2001:db8::1', 'prefix_or_netmask': '78'} + ), + ( # /128 — Host route (single address) + "inet6 2001:db8::1/128", + {'ip': '2001:db8::1', 'prefix_or_netmask': '128'} + ), + ( # Standard prefix using prefixlen keyword + "inet6 2001:db8::1 prefixlen 64", + {'ip': '2001:db8::1', 'prefix_or_netmask': '64'} + ), + ( # prefixlen on compressed addresses + "inet6 ::1 prefixlen 128", + {'ip': '::1', 'prefix_or_netmask': '128'} + ), + ( # prefixlen on link-local with zone + "inet6 fe80::1%em0 prefixlen 64", + {'ip': 'fe80::1%em0', 'prefix_or_netmask': '64'} + ), + ]: + config = {'ipv6': True} + self.assertTrue(parse_ifconfig_values(TEST_LINE, config)) + self.assertDictContainsSubset( + EXPECTED_CONF, + config, + f"failure on line '{TEST_LINE}'" + ) + + def test_parse_ifconfig_values_alias_or_system(self): + for TEST_LINE, INIT_CONFIG, EXPECTED_CONF in [ + ( + # No type set, no alias in value + "inet 10.0.0.1/8", + {}, + {'ip': '10.0.0.1', 'prefix_or_netmask': '8', 'type': 'system'} + ), + ( + # No type set, alias in value + "inet 192.168.100.1/30 alias ", + {}, + {'ip': '192.168.100.1', 'prefix_or_netmask': '30', 'type': 'alias'} + ), + ( + # Alias set already set, no alias value + "inet 172.16.0.1/16", + {'type': 'alias'}, + {'ip': '172.16.0.1', 'prefix_or_netmask': '16', 'type': 'alias'} + ), + ( + # Alias set already set, no alias value + "inet 192.168.1.50/24 alias", + {'type': 'alias'}, + {'ip': '192.168.1.50', 'prefix_or_netmask': '24', 'type': 'alias'} + ), + ]: + self.assertTrue(parse_ifconfig_values(TEST_LINE, INIT_CONFIG), f"line '{TEST_LINE}' hasn't passed validation") + self.assertDictEqual( + EXPECTED_CONF, + INIT_CONFIG, + f"failure on line '{TEST_LINE}'" + ) + + def test_parse_ifconfig_values_carp_params(self): + for TEST_LINE, INIT_CONFIG, EXPECTED_CONF in [ + ( + # Basic CARP with vhid and password + "inet 192.168.1.1/24 vhid 1 pass secretpass", + {}, + {'ip':'192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'carp_vhid': '1', 'carp_password': 'secretpass'}), + ( + # CARP with advskew + "inet 192.168.1.1/24 vhid 1 pass secretpass advskew 100", + {}, + {'ip':'192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'carp_vhid': '1', 'carp_password': 'secretpass', 'carp_priority': '100'}), + ( + # CARP as master + "inet 192.168.1.1/24 vhid 255 pass secretpass advskew 0", + {}, + {'ip':'192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'carp_vhid': '255', 'carp_password': 'secretpass', 'carp_priority': '0'}), + ( + # CARP IPv6 + "inet6 2001:db8::1/64 vhid 34 pass secretpass", + {'ipv6': True}, + {'ip':'2001:db8::1', 'ipv6': True, 'prefix_or_netmask': '64', 'type': 'system', 'carp_vhid': '34', 'carp_password': 'secretpass'}), + ( + # no VHID value + "inet 192.168.1.1/24 vhid pass secretpass", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'carp_password': 'secretpass'}), + ( + # no pass + "inet 192.168.1.1/24 vhid 1 advskew 100 pass", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'carp_vhid': '1', 'carp_priority': '100'}), + ( + # wrong advskew value + "inet 192.168.1.1/24 vhid 255 pass secretpass advskew foo", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'carp_vhid': '255', 'carp_password': 'secretpass'}), + ( + # wrong vhid value + "inet6 2001:db8::1/64 vhid bar pass secretpass", + {'ipv6': True}, + {'ip': '2001:db8::1', 'ipv6': True, 'prefix_or_netmask': '64', 'type': 'system', 'carp_password': 'secretpass'}), + ]: + self.assertTrue(parse_ifconfig_values(TEST_LINE, INIT_CONFIG), f"line '{TEST_LINE}' hasn't passed validation") + self.assertEqual( + EXPECTED_CONF, + INIT_CONFIG, + f"failure on line '{TEST_LINE}'" + ) + + def test_parse_ifconfig_values_fib(self): + for TEST_LINE, INIT_CONFIG, EXPECTED_CONF in [ + ( + # default FIB, not added to conf + "inet 192.168.1.1/24", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # default FIB, but explicit + "inet 192.168.1.1/24 fib 0", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'fib': '0'} + ), + ( + # non-default FIB, explicit + "inet 192.168.1.1/24 fib 3", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'fib': '3'} + ), + ( + # non-default FIB, IPv6, explicit + "inet6 2001:db8::1/64 fib 9", + {'ipv6': True}, + {'ip': '2001:db8::1', 'ipv6': True, 'prefix_or_netmask': '64', 'type': 'system', 'fib': '9'} + ), + ( + # invalid FIB (>9) + "inet 192.168.1.1/24 fib 12", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # invalid FIB (<0) + "inet6 2001:db8::1/64 fib -2", + {'ipv6': True}, + {'ip': '2001:db8::1', 'ipv6': True, 'prefix_or_netmask': '64', 'type': 'system'} + ), + ( + # invalid FIB (not a number) + "inet 192.168.1.1/24 fib fab", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ]: + self.assertTrue(parse_ifconfig_values(TEST_LINE, INIT_CONFIG), f"line '{TEST_LINE}' hasn't passed validation") + self.assertDictEqual( + EXPECTED_CONF, + INIT_CONFIG, + f"failure on line '{TEST_LINE}'" + ) + + def test_parse_ifconfig_values_vlan(self): + for TEST_LINE, INIT_CONFIG, EXPECTED_CONF in [ + ( + # default IP, no vlan + "inet 192.168.1.1/24", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # missing vlandev + "inet 192.168.1.1/24 vlan 13", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # missing vlan + "inet 192.168.1.1/24 vlandev em0", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # valid vlan conf + "inet 192.168.1.1/24 vlan 13 vlandev em0", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'vlan': '13', 'nic': ['em0']} + ), + ( + # valid vlan conf 2 + "inet 192.168.1.1/24 vlandev vtnet1 vlan 24", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'vlan': '24', 'nic': ['vtnet1']} + ), + ( + # missing vlandev value + "inet 192.168.1.1/24 vlan 24 vlandev", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # missing vlan value + "inet 192.168.1.1/24 vlandev igb2 vlan", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # wrong vlan value + "inet 192.168.1.1/24 vlandev vmx0 vlan foo", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ]: + self.assertTrue(parse_ifconfig_values(TEST_LINE, INIT_CONFIG), f"line '{TEST_LINE}' hasn't passed validation") + self.assertDictEqual( + EXPECTED_CONF, + INIT_CONFIG, + f"failure on line '{TEST_LINE}'" + ) + + def test_parse_ifconfig_values_lagg(self): + for TEST_LINE, INIT_CONFIG, EXPECTED_CONF in [ + ( + # default IP, no lagg + "inet 192.168.1.1/24", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # missing laggport + "inet 192.168.1.1/24 laggproto loadbalance", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # missing laggproto + "inet 192.168.1.1/24 laggport em0", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # valid lagg conf + "inet 192.168.1.1/24 laggproto loadbalance laggport em0 laggport em1", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'lagg_proto': 'loadbalance', 'nic': ['em0', 'em1']} + ), + ( + # valid lagg conf 2 + "inet 192.168.1.1/24 laggport vtnet1 laggproto roundrobin laggport vtnet2", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system', 'lagg_proto': 'roundrobin', 'nic': ['vtnet1', 'vtnet2']} + ), + ( + # missing a laggport + "inet 192.168.1.1/24 laggproto loadbalance laggport em0", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # wrong laggproto value + "inet 192.168.1.1/24 laggproto 12 laggport em0 laggport em1", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ( + # missing laggport value + "inet 192.168.1.1/24 laggproto loadbalance laggport em0 laggport", + {}, + {'ip': '192.168.1.1', 'prefix_or_netmask': '24', 'type': 'system'} + ), + ]: + self.assertTrue(parse_ifconfig_values(TEST_LINE, INIT_CONFIG), f"line '{TEST_LINE}' hasn't passed validation") + self.assertDictEqual( + EXPECTED_CONF, + INIT_CONFIG, + f"failure on line '{TEST_LINE}'" + ) + +######################## +# parse_gateway_config # +######################## + def test_parse_gateway_config_no_value(self): + TEST_LINE = '' + config = dict() + self.assertFalse(parse_gateway_config(TEST_LINE, config)) + + def test_parse_gateway_config_ipv4_matches(self): + for TEST_LINE, INIT_CONFIG, SHOULD_PASS, EXPECTED_CONF in [ + ( + # default router, with double quotes + 'defaultrouter="192.168.1.1"', + {}, + True, + {'defaultgateway': '192.168.1.1'} + ), + ( + # default router, with single quotes + "defaultrouter='192.168.1.1'", + {}, + True, + {'defaultgateway': '192.168.1.1'} + ), + ( + # no value + "defaultrouter=''", + {}, + False, + {} + ), + ]: + self.assertEquals(parse_gateway_config(TEST_LINE, INIT_CONFIG), SHOULD_PASS, f"line '{TEST_LINE}' hasn't passed validation") + self.assertDictEqual( + EXPECTED_CONF, + INIT_CONFIG, + f"failure on line '{TEST_LINE}'" + ) + + def test_parse_gateway_config_ipv6_matches(self): + for TEST_LINE, INIT_CONFIG, SHOULD_PASS, EXPECTED_CONF in [ + ( + # default router, with double quotes + 'ipv6_defaultrouter="fe80::1"', + {}, + True, + {'defaultgateway_ipv6': 'fe80::1'} + ), + ( + # default router, with single quotes + "ipv6_defaultrouter='fe80::1'", + {}, + True, + {'defaultgateway_ipv6': 'fe80::1'} + ), + ( + # no value + "ipv6_defaultrouter=''", + {}, + False, + {} + ), + ]: + self.assertEquals(parse_gateway_config(TEST_LINE, INIT_CONFIG), SHOULD_PASS, f"line '{TEST_LINE}' hasn't passed validation") + self.assertDictEqual( + EXPECTED_CONF, + INIT_CONFIG, + f"failure on line '{TEST_LINE}'" + ) From 0a1a27c715e3828156ac8b7b9acd65ad13ea5a2c Mon Sep 17 00:00:00 2001 From: mbonniot <97617139+0xanalog@users.noreply.github.com> Date: Wed, 25 Feb 2026 15:16:06 +0100 Subject: [PATCH 3/8] feat(static/js): Sanitize dynamic html injection through vulture-gui DOM using DOMPurify lib (avoiding CWE-79) (#652) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **[STATIC] [JS]** Sanitize dynamic html injection through vulture-gui DOM using DOMPurify lib (avoiding CWE-79) --------- Co-authored-by: Théo Bertin --- CHANGELOG | 1 + vulture_os/gui/static/js/application.js | 4 ++-- vulture_os/gui/static/js/components/ldap_user_list.js | 4 ++-- vulture_os/gui/static/js/demo/nifty-demo.js | 2 +- vulture_os/gui/static/js/doc.js | 4 ++-- vulture_os/gui/static/js/idp_view.js | 4 ++-- vulture_os/gui/static/js/listener.js | 4 ++-- vulture_os/gui/static/js/nifty.js | 6 +++--- vulture_os/gui/static/js/pki.js | 4 ++-- .../filter-control/bootstrap-table-filter-control.js | 3 ++- .../gui/static/plugins/datatables/jquery.dataTables.js | 6 ++++-- .../gui/static/plugins/unitegallery/js/unitegallery.js | 8 ++++---- vulture_os/templates/layout2.html | 2 ++ 13 files changed, 29 insertions(+), 23 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0dee92aa7..939080551 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - werkzeug 3.1.3 -> 3.1.5 ### Fixed - [NETWORK] Improve rc.conf networking lines' parsing patterns +- [GUI] [JS] Avoid DOM-based XSS (and silence JS scanner's false positives...) ## [2.35.0] - 2026-02-06 diff --git a/vulture_os/gui/static/js/application.js b/vulture_os/gui/static/js/application.js index ddd4a197f..fca5e1eaf 100644 --- a/vulture_os/gui/static/js/application.js +++ b/vulture_os/gui/static/js/application.js @@ -9,7 +9,7 @@ function init_application_form(btn, html, app_id){ function(response){ $(btn).html(html); if (response.status){ - $('#modal-application-content').html(response.template); + $('#modal-application-content').html(DOMPurify.sanitize(response.template)); $('#modal-application').modal({ backdrop: 'static', keyboard: false @@ -169,7 +169,7 @@ $(function(){ function(response){ if (!response.status){ - $('#modal-application-content').html(response.template); + $('#modal-application-content').html(DOMPurify.sanitize(response.template)); } else { $('#modal-application').modal('hide'); notify('success', gettext('Application successfully saved')) diff --git a/vulture_os/gui/static/js/components/ldap_user_list.js b/vulture_os/gui/static/js/components/ldap_user_list.js index 4f32554ae..46b7065fd 100644 --- a/vulture_os/gui/static/js/components/ldap_user_list.js +++ b/vulture_os/gui/static/js/components/ldap_user_list.js @@ -141,7 +141,7 @@ let UserListComponent = Vue.component("UserList", { }).$mount() $(`#modal-${this.id}`).modal('show') - $(`#${this.modalContentId()}`).html(comp.$el) + $(`#${this.modalContentId()}`).html(DOMPurify.sanitize(comp.$el)) }) $(nRow).find('.btn-delete').on('click', (e) => { @@ -187,7 +187,7 @@ let UserListComponent = Vue.component("UserList", { }).$mount() $(`#modal-${this.id}`).modal('show') - $(`#${this.modalContentId()}`).html(comp.$el) + $(`#${this.modalContentId()}`).html(DOMPurify.sanitize(comp.$el)) } } }) \ No newline at end of file diff --git a/vulture_os/gui/static/js/demo/nifty-demo.js b/vulture_os/gui/static/js/demo/nifty-demo.js index 542a09249..2bad90f6d 100755 --- a/vulture_os/gui/static/js/demo/nifty-demo.js +++ b/vulture_os/gui/static/js/demo/nifty-demo.js @@ -20,7 +20,7 @@ $(document).on('nifty.ready', function () { $("#demo-nifty-settings").addClass("in"); $("#demo-set-content").append(contentIndi); $.get("settings.html", function( data ) { - $("#demo-set-content").empty().append(data); + $("#demo-set-content").empty().append(DOMPurify.sanitize(data)); settingsInit(); }).fail(function(e) { $("#demo-get-status").html(e.status); diff --git a/vulture_os/gui/static/js/doc.js b/vulture_os/gui/static/js/doc.js index 1d6fdd3d9..d2057aff4 100644 --- a/vulture_os/gui/static/js/doc.js +++ b/vulture_os/gui/static/js/doc.js @@ -30,14 +30,14 @@ $(function(){ if ($('#documentation_tab').css('right') !== "0px") $('#documentation_tab').css('right', 0); - $('#documentation_tab').html(response.html); + $('#documentation_tab').html(DOMPurify.sanitize(response.html)); converter = new showdown.Converter({ literalMidWordUnderscores: true }), readme = converter.makeHtml(response.readme); - $('#documentation_content').html(readme) + $('#documentation_content').html(DOMPurify.sanitize(readme)) bind_buttons(); } ) diff --git a/vulture_os/gui/static/js/idp_view.js b/vulture_os/gui/static/js/idp_view.js index f17eb419c..e20061f0f 100644 --- a/vulture_os/gui/static/js/idp_view.js +++ b/vulture_os/gui/static/js/idp_view.js @@ -48,7 +48,7 @@ let idp_view = new Vue({ }).$mount() $("#modalAddUser").modal('show') - $("#modalAddUserContent").html(comp.$el) + $("#modalAddUserContent").html(DOMPurify.sanitize(comp.$el)) }, initTable() { @@ -121,7 +121,7 @@ let idp_view = new Vue({ }).$mount() $("#modalAddUser").modal('show') - $("#modalAddUserContent").html(comp.$el) + $("#modalAddUserContent").html(DOMPurify.sanitize(comp.$el)) }) $(nRow).find('.btn-delete').on('click', (e) => { diff --git a/vulture_os/gui/static/js/listener.js b/vulture_os/gui/static/js/listener.js index 8ebeef84e..988eecab2 100644 --- a/vulture_os/gui/static/js/listener.js +++ b/vulture_os/gui/static/js/listener.js @@ -41,7 +41,7 @@ $(function() { ) .done(function(response){ //TODO ensure objects and JS is refreshed to show correctly - $('#api_collector_form_div').html(response); + $('#api_collector_form_div').html(DOMPurify.sanitize(response)); // Refresh tags-input bootstrap fields after their import in the DOM $('#api_collector_form_div').find('[data-role="tagsinput"]').each(function(index){ $( this ).tagsinput(); @@ -169,7 +169,7 @@ $(function() { } var data = response.data; $('#id_api_parser_has_been_tested').val('1'); - $('#modal-test-apiparser-body').html('
' + JSON.stringify(data, null, 4) + "
"); + $('#modal-test-apiparser-body').html(DOMPurify.sanitize('
' + JSON.stringify(data, null, 4) + "
")); $('#modal-test-apiparser').modal('show'); }) diff --git a/vulture_os/gui/static/js/nifty.js b/vulture_os/gui/static/js/nifty.js index 03de98198..6f8149e63 100755 --- a/vulture_os/gui/static/js/nifty.js +++ b/vulture_os/gui/static/js/nifty.js @@ -410,7 +410,7 @@ el.prop('disabled', true).data('niftyOverlay',ovId); target.addClass('panel-overlay-wrap'); - panelOv.appendTo(target).html(el.data('overlayTemplate')); + panelOv.appendTo(target).html(DOMPurify.sanitize(el.data('overlayTemplate'))); return null; }, 'hide': function(el){ @@ -1143,7 +1143,7 @@ if (elHasSub) { $listSub.removeAttr('style').appendTo($el.parent()); }else if($listWidget.length){ - $listWidget.appendTo($listWidgetParent); + $listWidget.appendTo(DOMPurify.sanitize($listWidgetParent)); } clearInterval(hidePopover); }) @@ -1160,7 +1160,7 @@ if (elHasSub) { $listSub.removeAttr('style').appendTo($el.parent()); }else if($listWidget.length){ - $listWidget.appendTo($listWidgetParent); + $listWidget.appendTo(DOMPurify.sanitize($listWidgetParent)); } clearInterval(hidePopover); }) diff --git a/vulture_os/gui/static/js/pki.js b/vulture_os/gui/static/js/pki.js index 008197687..8d86a9580 100644 --- a/vulture_os/gui/static/js/pki.js +++ b/vulture_os/gui/static/js/pki.js @@ -9,7 +9,7 @@ function init_pki_form(btn, html, pki_id){ function(response){ $(btn).html(html); if (response.status){ - $('#modal-pki-content').html(response.template); + $('#modal-pki-content').html(DOMPurify.sanitize(response.template)); $('#modal-pki').modal({ backdrop: 'static', keyboard: false @@ -135,7 +135,7 @@ $(function(){ function(response){ if (!response.status){ - $('#modal-pki-content').html(response.template); + $('#modal-pki-content').html(DOMPurify.sanitize(response.template)); } else { $('#modal-pki').modal('hide'); notify('success', gettext('pki successfully saved')) diff --git a/vulture_os/gui/static/plugins/bootstrap-table/extensions/filter-control/bootstrap-table-filter-control.js b/vulture_os/gui/static/plugins/bootstrap-table/extensions/filter-control/bootstrap-table-filter-control.js index fe923ea8a..b7f3b134b 100755 --- a/vulture_os/gui/static/plugins/bootstrap-table/extensions/filter-control/bootstrap-table-filter-control.js +++ b/vulture_os/gui/static/plugins/bootstrap-table/extensions/filter-control/bootstrap-table-filter-control.js @@ -3,6 +3,7 @@ * @webSite: http://djhvscf.github.io/Blog * @version: v2.1.2 */ +import { sanitize } from '../../../DOMPurify/purify.min.js'; (function ($) { @@ -35,7 +36,7 @@ if (!existOptionInSelectControl(selectControl, value)) { selectControl.append($("") .attr("value", value) - .text($('
').html(text).text())); + .text($('
').html(sanitize(text)).text())); } }; diff --git a/vulture_os/gui/static/plugins/datatables/jquery.dataTables.js b/vulture_os/gui/static/plugins/datatables/jquery.dataTables.js index 1d8a220ba..32b71005f 100755 --- a/vulture_os/gui/static/plugins/datatables/jquery.dataTables.js +++ b/vulture_os/gui/static/plugins/datatables/jquery.dataTables.js @@ -23,6 +23,8 @@ /*jslint evil: true, undef: true, browser: true */ /*globals $, jQuery,define,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros,_fnBrowserDetect,_fnGetColumns*/ +import { sanitize } from "../DOMPurify/purify.min"; + (/** @lends */function( window, document, undefined ) { (function( factory ) { @@ -1229,7 +1231,7 @@ var nDiv = document.createElement('div'); nDiv.className = oSettings.oClasses.sSortJUIWrapper; - $(nTh).contents().appendTo(nDiv); + $(nTh).contents().appendTo(sanitize(nDiv)); var nSpan = document.createElement('span'); nSpan.className = oSettings.oClasses.sSortIcon; @@ -3910,7 +3912,7 @@ style.overflow = "hidden"; outer.appendChild(inner); - document.body.appendChild(outer); + document.body.appendChild(sanitize(outer)); var w1 = inner.offsetWidth; outer.style.overflow = 'scroll'; var w2 = inner.offsetWidth; diff --git a/vulture_os/gui/static/plugins/unitegallery/js/unitegallery.js b/vulture_os/gui/static/plugins/unitegallery/js/unitegallery.js index 5e269481b..6659e60a1 100755 --- a/vulture_os/gui/static/plugins/unitegallery/js/unitegallery.js +++ b/vulture_os/gui/static/plugins/unitegallery/js/unitegallery.js @@ -1,6 +1,6 @@ // Unite Gallery, Version: 1.7.40, released 29 Nov 2016 - +import { sanitize } from "../../DOMPurify/purify.min"; /** * write something to debug line @@ -19239,11 +19239,11 @@ var g_ugWistiaAPI = new UGWistiaAPI(); if(type == "jquery"){ var objGallery = document.getElementById(galleryID); - objGallery.innerHTML = message; + objGallery.innerHTML = sanitize(message); objGallery.style.display = "block"; } else - jQuery(galleryID).show().html(message); + jQuery(galleryID).show().html(sanitize(message)); return(false); } @@ -19595,7 +19595,7 @@ function UniteGalleryMain(){ g_objWrapper.children().remove(); - g_objWrapper.html(html); + g_objWrapper.html(sanitize(html)); g_objWrapper.show(); } diff --git a/vulture_os/templates/layout2.html b/vulture_os/templates/layout2.html index 5f0b41a67..e19b53bce 100644 --- a/vulture_os/templates/layout2.html +++ b/vulture_os/templates/layout2.html @@ -90,6 +90,8 @@ + + {% if DEV_MODE %} From ffe3b9a8225ed43e7b6f3ffe3178ca4bd3c53499 Mon Sep 17 00:00:00 2001 From: Fabien Amelinck Date: Tue, 20 Jan 2026 10:28:51 +0100 Subject: [PATCH 4/8] change(logomhiredis): use raw_message_nolf template --- CHANGELOG | 1 + vulture_os/applications/logfwd/config/om_hiredis.tpl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 939080551..f2aac21ef 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Changed +- [APPLICATIONS] [LOGOMHIREDIS] Use new raw_message_nolf template to send logs without newline added - [DEPENDENCIES] - aiohappyeyeballs 2.4.4 -> 2.6.1 - aiohttp 3.10.5 -> 3.13.3 diff --git a/vulture_os/applications/logfwd/config/om_hiredis.tpl b/vulture_os/applications/logfwd/config/om_hiredis.tpl index a01bb8d7a..74b7d43f0 100644 --- a/vulture_os/applications/logfwd/config/om_hiredis.tpl +++ b/vulture_os/applications/logfwd/config/om_hiredis.tpl @@ -37,7 +37,7 @@ stream.outField="{{stream_outfield}}" stream.capacityLimit="{{stream_capacitylimit}}" {%- endif %} - Template="{% if send_as_raw %}raw_message{% else %}{{ out_template }}_json{% endif %}" + Template="{% if send_as_raw %}raw_message_nolf{% else %}{{ out_template }}_json{% endif %}" queue.type="LinkedList" queue.size="{{queue_size}}" queue.dequeuebatchsize="{{dequeue_size}}" From 4ca0db8ba992e40fcb90ed69b95d85f5af28d9a3 Mon Sep 17 00:00:00 2001 From: Fabien Amelinck Date: Thu, 26 Feb 2026 11:29:15 +0100 Subject: [PATCH 5/8] fix(collectors): improperly set JSONFields due to a djongo bug (#651) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Added - [API_PARSER] Add api_collector parameters in the returned representation of Frontends through APIs ### Fixed - [API_PARSER] Fix a bug preventing to create/update frontend through APIs --------- Co-authored-by: Théo Bertin --- CHANGELOG | 3 +++ vulture_os/services/frontend/form.py | 14 +++++++------- vulture_os/services/frontend/models.py | 4 ++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f2aac21ef..c59e9035f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- [API_PARSER] Add api_collector parameters in the returned representation of Frontends through APIs ### Changed - [APPLICATIONS] [LOGOMHIREDIS] Use new raw_message_nolf template to send logs without newline added - [DEPENDENCIES] @@ -27,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - [NETWORK] Improve rc.conf networking lines' parsing patterns - [GUI] [JS] Avoid DOM-based XSS (and silence JS scanner's false positives...) +- [API_PARSER] Fix a bug preventing to create/update frontend through APIs ## [2.35.0] - 2026-02-06 diff --git a/vulture_os/services/frontend/form.py b/vulture_os/services/frontend/form.py index 726547b5d..941974528 100644 --- a/vulture_os/services/frontend/form.py +++ b/vulture_os/services/frontend/form.py @@ -39,7 +39,7 @@ from services.frontend.models import (Frontend, FrontendReputationContext, Listener, COMPRESSION_ALGO_CHOICES, LISTENING_MODE_CHOICES, LOG_LEVEL_CHOICES, MODE_CHOICES, DARWIN_MODE_CHOICES, REDIS_MODE_CHOICES, REDIS_STARTID_CHOICES, - FILEBEAT_LISTENING_MODE, FILEBEAT_MODULE_LIST, SENTINEL_ONE_ACCOUNT_TYPE_CHOICES, + FILEBEAT_LISTENING_MODE, FILEBEAT_MODULE_LIST, get_available_timezones) from services.rsyslogd.form import RsyslogQueueForm @@ -274,7 +274,7 @@ def __init__(self, *args, **kwargs): 'waf_barracuda_token', "beyondtrust_pra_client_id", "beyondtrust_pra_secret", "beyondtrust_pra_host", "lockself_x_auth_token", "lockself_x_ls_token", "lockself_host", "lockself_organization_id", - "cisco_umbrella_managed_org_api_key", "cisco_umbrella_managed_org_secret_key", "cisco_umbrella_managed_org_customers_id", + "cisco_umbrella_managed_org_api_key", "cisco_umbrella_managed_org_secret_key", "cisco_umbrella_managed_org_get_dns", "cisco_umbrella_managed_org_get_proxy", "catonetworks_account_id", "catonetworks_api_key", "infoblox_threat_defense_host", "infoblox_threat_defense_token", @@ -282,10 +282,10 @@ def __init__(self, *args, **kwargs): "beyondtrust_reportings_get_team_logs", "beyondtrust_reportings_get_access_session_logs", "beyondtrust_reportings_get_vault_account_activity_logs", "beyondtrust_reportings_get_support_session_logs", "varonis_host", "varonis_api_key", "armis_centrix_host", "armis_centrix_secretkey", "armis_centrix_get_activity_logs", - "perception_point_x_ray_host", "perception_point_x_ray_token", "perception_point_x_ray_organization_id", "perception_point_x_ray_environment_id", "perception_point_x_ray_case_types", + "perception_point_x_ray_host", "perception_point_x_ray_token", "perception_point_x_ray_organization_id", "perception_point_x_ray_environment_id", "extrahop_host", "extrahop_id", "extrahop_secret", "hornetsecurity_app_id", "hornetsecurity_token", - "ubika_base_refresh_token", "ubika_namespaces", + "ubika_base_refresh_token", "sentinel_one_graph_token", "sentinel_one_graph_console_url", 'messagetrace_o365_tenant_id', 'messagetrace_o365_client_id', 'messagetrace_o365_client_secret', 'cnapp_wiz_client_id', 'cnapp_wiz_client_secret', 'cnapp_wiz_api_url', @@ -399,7 +399,7 @@ class Meta: 'waf_barracuda_token', "beyondtrust_pra_client_id", "beyondtrust_pra_secret", "beyondtrust_pra_host", 'lockself_x_auth_token', 'lockself_x_ls_token', 'lockself_host', 'lockself_organization_id', - 'cisco_umbrella_managed_org_api_key', 'cisco_umbrella_managed_org_secret_key', 'cisco_umbrella_managed_org_customers_id', + 'cisco_umbrella_managed_org_api_key', 'cisco_umbrella_managed_org_secret_key', 'cisco_umbrella_managed_org_get_dns', 'cisco_umbrella_managed_org_get_proxy', 'catonetworks_api_key', 'catonetworks_account_id', "infoblox_threat_defense_host", "infoblox_threat_defense_token", @@ -409,10 +409,10 @@ class Meta: "beyondtrust_reportings_get_support_session_logs", "varonis_host", "varonis_api_key", "armis_centrix_host", "armis_centrix_secretkey", "armis_centrix_get_activity_logs", - "perception_point_x_ray_host", "perception_point_x_ray_token", "perception_point_x_ray_organization_id", "perception_point_x_ray_environment_id", "perception_point_x_ray_case_types", + "perception_point_x_ray_host", "perception_point_x_ray_token", "perception_point_x_ray_organization_id", "perception_point_x_ray_environment_id", "extrahop_host", "extrahop_id", "extrahop_secret", "hornetsecurity_app_id", "hornetsecurity_token", - "ubika_base_refresh_token", "ubika_namespaces", + "ubika_base_refresh_token", "sentinel_one_graph_token", "sentinel_one_graph_console_url", 'messagetrace_o365_tenant_id', 'messagetrace_o365_client_id', 'messagetrace_o365_client_secret', 'cnapp_wiz_client_id', 'cnapp_wiz_client_secret', 'cnapp_wiz_api_url', diff --git a/vulture_os/services/frontend/models.py b/vulture_os/services/frontend/models.py index 2e56d8ea4..ff970a100 100644 --- a/vulture_os/services/frontend/models.py +++ b/vulture_os/services/frontend/models.py @@ -1836,6 +1836,10 @@ def to_dict(self, fields=None): result['log_forwarders'] = [LogOM().select_log_om(log_fwd.id).to_template() for log_fwd in self.log_forwarders.all().only('id')] + if not fields or "api_parser_parameters" in fields: + excluded_fields = ("id", "apicollector_ptr", "frontend", "last_collected_timestamps") + result['api_parser_parameters'] = model_to_dict(self.api_collector, exclude=excluded_fields) if self.api_collector else None + return result def to_html_template(self): From 7c97aac0f26cfd72e5ec961c3ba4c95582ab49cc Mon Sep 17 00:00:00 2001 From: Kevin Guillemot Date: Wed, 25 Feb 2026 14:57:36 +0100 Subject: [PATCH 6/8] fix(api_parser): Do not delete redis key if collector is already running --- CHANGELOG | 1 + vulture_os/gui/crontab/api_clients_parser.py | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c59e9035f..5003e700c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [NETWORK] Improve rc.conf networking lines' parsing patterns - [GUI] [JS] Avoid DOM-based XSS (and silence JS scanner's false positives...) - [API_PARSER] Fix a bug preventing to create/update frontend through APIs +- [API_PARSER] Fix possibility of multiple running instances of a collector ## [2.35.0] - 2026-02-06 diff --git a/vulture_os/gui/crontab/api_clients_parser.py b/vulture_os/gui/crontab/api_clients_parser.py index 439fdc2db..7c85a9f9f 100644 --- a/vulture_os/gui/crontab/api_clients_parser.py +++ b/vulture_os/gui/crontab/api_clients_parser.py @@ -55,11 +55,10 @@ def execute_parser(frontend): extra={'frontend': str(frontend.name)}) logger.exception(e, extra={'frontend': str(frontend.name)}) collector.frontend.status[Cluster.get_current_node().name] = "ERROR" - finally: - # Delete running key in redis - logger.info("API Collector {} (tenant={}): ending".format(frontend.name, frontend.tenants_config.name), - extra={'frontend': str(frontend.name)}) - collector.finish() + # Delete running key in redis - only if not already running (see return above) + logger.info("API Collector {} (tenant={}): ending".format(frontend.name, frontend.tenants_config.name), + extra={'frontend': str(frontend.name)}) + collector.finish() def node_selected(current_node, frontend): """ Small routine that verify if this node has to run the collector """ From 63e8196d2fbb6b258abe278fe43875dfeccc3840 Mon Sep 17 00:00:00 2001 From: Fabien Amelinck Date: Mon, 2 Mar 2026 16:24:28 +0100 Subject: [PATCH 7/8] fix(static/js): don't sanitize datatables plugin --- .../gui/static/plugins/datatables/jquery.dataTables.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vulture_os/gui/static/plugins/datatables/jquery.dataTables.js b/vulture_os/gui/static/plugins/datatables/jquery.dataTables.js index 32b71005f..1d8a220ba 100755 --- a/vulture_os/gui/static/plugins/datatables/jquery.dataTables.js +++ b/vulture_os/gui/static/plugins/datatables/jquery.dataTables.js @@ -23,8 +23,6 @@ /*jslint evil: true, undef: true, browser: true */ /*globals $, jQuery,define,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros,_fnBrowserDetect,_fnGetColumns*/ -import { sanitize } from "../DOMPurify/purify.min"; - (/** @lends */function( window, document, undefined ) { (function( factory ) { @@ -1231,7 +1229,7 @@ import { sanitize } from "../DOMPurify/purify.min"; var nDiv = document.createElement('div'); nDiv.className = oSettings.oClasses.sSortJUIWrapper; - $(nTh).contents().appendTo(sanitize(nDiv)); + $(nTh).contents().appendTo(nDiv); var nSpan = document.createElement('span'); nSpan.className = oSettings.oClasses.sSortIcon; @@ -3912,7 +3910,7 @@ import { sanitize } from "../DOMPurify/purify.min"; style.overflow = "hidden"; outer.appendChild(inner); - document.body.appendChild(sanitize(outer)); + document.body.appendChild(outer); var w1 = inner.offsetWidth; outer.style.overflow = 'scroll'; var w2 = inner.offsetWidth; From 92567031dda80f71b8a6d1a0f716116d8f81878f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Bertin?= Date: Fri, 6 Mar 2026 09:51:18 +0100 Subject: [PATCH 8/8] doc(CHANGELOG): Version 2.35.1 --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 5003e700c..5f5c2a0f1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] + + +## [2.35.1] - 2026-03-06 ### Added - [API_PARSER] Add api_collector parameters in the returned representation of Frontends through APIs ### Changed