diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7fb7214af..1cfe42b69 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ env: jobs: test: runs-on: [self-hosted, Linux] - container: rust:1.75 + container: rust:1.77 services: postgres: diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8bec6c503..651253db2 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -16,7 +16,7 @@ env: jobs: rustdoc: runs-on: [self-hosted, Linux] - container: rust:1.75 + container: rust:1.77 services: postgres: image: postgres:15-alpine diff --git a/.sqlx/query-198f1ff51b4777d0727dae0613f642a4ef429df77c70bdf5e2ca50f30af3eda1.json b/.sqlx/query-198f1ff51b4777d0727dae0613f642a4ef429df77c70bdf5e2ca50f30af3eda1.json new file mode 100644 index 000000000..c90fbf57c --- /dev/null +++ b/.sqlx/query-198f1ff51b4777d0727dae0613f642a4ef429df77c70bdf5e2ca50f30af3eda1.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT wn.name FROM wireguard_network wn JOIN wireguard_network_allowed_group wnag ON wn.id = wnag.network_id WHERE wnag.group_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "name", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false + ] + }, + "hash": "198f1ff51b4777d0727dae0613f642a4ef429df77c70bdf5e2ca50f30af3eda1" +} diff --git a/.sqlx/query-d89f6eae4627862933a8f148f54f9eb916a2b11c62fb06b735b22324cd35f6eb.json b/.sqlx/query-d89f6eae4627862933a8f148f54f9eb916a2b11c62fb06b735b22324cd35f6eb.json deleted file mode 100644 index 5188e8bef..000000000 --- a/.sqlx/query-d89f6eae4627862933a8f148f54f9eb916a2b11c62fb06b735b22324cd35f6eb.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT g.name as name, COALESCE(ARRAY_AGG(u.username) FILTER (WHERE u.username IS NOT NULL), '{}') as members FROM \"group\" g LEFT JOIN \"group_user\" gu ON gu.group_id = g.id LEFT JOIN \"user\" u ON u.id = gu.user_id GROUP BY g.name", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "name", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "members", - "type_info": "TextArray" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - false, - null - ] - }, - "hash": "d89f6eae4627862933a8f148f54f9eb916a2b11c62fb06b735b22324cd35f6eb" -} diff --git a/.sqlx/query-eb753d506ce15b17b7aca1f5dd3dd03b382a667f0f0bc506e0cbc45118eea293.json b/.sqlx/query-eb753d506ce15b17b7aca1f5dd3dd03b382a667f0f0bc506e0cbc45118eea293.json new file mode 100644 index 000000000..f23df5d70 --- /dev/null +++ b/.sqlx/query-eb753d506ce15b17b7aca1f5dd3dd03b382a667f0f0bc506e0cbc45118eea293.json @@ -0,0 +1,32 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT g.name as name, COALESCE(ARRAY_AGG(DISTINCT u.username) FILTER (WHERE u.username IS NOT NULL), '{}') as \"members!\", COALESCE(ARRAY_AGG(DISTINCT wn.name) FILTER (WHERE wn.name IS NOT NULL), '{}') as \"vpn_locations!\" FROM \"group\" g LEFT JOIN \"group_user\" gu ON gu.group_id = g.id LEFT JOIN \"user\" u ON u.id = gu.user_id LEFT JOIN \"wireguard_network_allowed_group\" wnag ON wnag.group_id = g.id LEFT JOIN \"wireguard_network\" wn ON wn.id = wnag.network_id GROUP BY g.name", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "name", + "type_info": "Text" + }, + { + "ordinal": 1, + "name": "members!", + "type_info": "TextArray" + }, + { + "ordinal": 2, + "name": "vpn_locations!", + "type_info": "TextArray" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false, + null, + null + ] + }, + "hash": "eb753d506ce15b17b7aca1f5dd3dd03b382a667f0f0bc506e0cbc45118eea293" +} diff --git a/Cargo.lock b/Cargo.lock index 14cc67abc..2224fd62a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,18 +67,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "android-tzdata" @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "argon2" @@ -225,18 +225,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] name = "async-trait" -version = "0.1.78" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -256,14 +256,14 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "axum" @@ -287,7 +287,7 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper", + "sync_wrapper 0.1.2", "tower", "tower-layer", "tower-service", @@ -295,9 +295,9 @@ dependencies = [ [[package]] name = "axum" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", "axum-core 0.4.3", @@ -306,7 +306,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.0", "http-body-util", - "hyper 1.2.0", + "hyper 1.3.1", "hyper-util", "itoa", "matchit", @@ -319,7 +319,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 1.0.1", "tokio", "tower", "tower-layer", @@ -333,7 +333,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e7c467bdcd2bd982ce5c8742a1a178aba7b03db399fd18f5d5d438f5aa91cb4" dependencies = [ - "axum 0.7.4", + "axum 0.7.5", "forwarded-header-value", "serde", ] @@ -370,7 +370,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper", + "sync_wrapper 0.1.2", "tower-layer", "tower-service", "tracing", @@ -378,14 +378,14 @@ dependencies = [ [[package]] name = "axum-extra" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "895ff42f72016617773af68fb90da2a9677d89c62338ec09162d4909d86fdd8f" +checksum = "0be6ea09c9b96cb5076af0de2e383bd2bc0c18f827cf1967bdd353e0b910d733" dependencies = [ - "axum 0.7.4", + "axum 0.7.5", "axum-core 0.4.3", "bytes", - "cookie 0.18.0", + "cookie 0.18.1", "futures-util", "headers", "http 1.1.0", @@ -397,13 +397,14 @@ dependencies = [ "tower", "tower-layer", "tower-service", + "tracing", ] [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -438,6 +439,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + [[package]] name = "base64ct" version = "1.6.0" @@ -512,9 +519,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -530,18 +537,18 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" dependencies = [ "serde", ] [[package]] name = "cc" -version = "1.0.90" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" [[package]] name = "cfg-if" @@ -551,9 +558,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -561,7 +568,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -617,9 +624,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.3" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -634,19 +641,19 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.0", + "strsim 0.11.1", ] [[package]] name = "clap_derive" -version = "4.5.3" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -736,12 +743,12 @@ dependencies = [ [[package]] name = "cookie" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ "aes-gcm", - "base64 0.21.7", + "base64 0.22.0", "percent-encoding", "rand", "subtle", @@ -793,9 +800,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.0.1" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" dependencies = [ "crc-catalog", ] @@ -912,7 +919,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -936,7 +943,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -947,7 +954,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -962,7 +969,7 @@ version = "0.10.0" dependencies = [ "anyhow", "argon2", - "axum 0.7.4", + "axum 0.7.5", "axum-client-ip", "axum-extra", "base64 0.21.7", @@ -1023,9 +1030,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -1071,9 +1078,9 @@ dependencies = [ [[package]] name = "deunicode" -version = "1.4.3" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6e854126756c496b8c81dec88f9a706b15b875c5849d4097a3854476b9fdf94" +checksum = "322ef0094744e63628e6f0eb2295517f79276a5b342a4c2ff3042566ca181d4e" [[package]] name = "digest" @@ -1095,7 +1102,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -1159,9 +1166,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" dependencies = [ "serde", ] @@ -1189,11 +1196,11 @@ dependencies = [ [[package]] name = "email-encoding" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfb21b9878cf7a348dcb8559109aabc0ec40d69924bd706fa5149846c4fef75" +checksum = "60d1d33cdaede7e24091f039632eb5d3c7469fe5b066a985281a34fc70fa317f" dependencies = [ - "base64 0.21.7", + "base64 0.22.0", "memchr", ] @@ -1205,9 +1212,9 @@ checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -1322,9 +1329,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "ff" @@ -1338,9 +1345,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" +checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e" [[package]] name = "finl_unicode" @@ -1500,7 +1507,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -1555,9 +1562,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "js-sys", @@ -1592,7 +1599,7 @@ dependencies = [ "bstr", "log", "regex-automata 0.4.6", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -1619,9 +1626,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -1629,26 +1636,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.2.5", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "h2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 1.1.0", - "indexmap 2.2.5", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -1874,7 +1862,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.25", + "h2", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -1890,14 +1878,13 @@ dependencies = [ [[package]] name = "hyper" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.3", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -1917,7 +1904,7 @@ dependencies = [ "futures-util", "http 0.2.12", "hyper 0.14.28", - "rustls 0.21.10", + "rustls 0.21.11", "tokio", "tokio-rustls 0.24.1", ] @@ -1957,7 +1944,7 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.0", - "hyper 1.2.0", + "hyper 1.3.1", "pin-project-lite", "socket2", "tokio", @@ -2079,9 +2066,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -2121,15 +2108,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.12.1" @@ -2141,9 +2119,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" @@ -2156,9 +2134,9 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "9.2.0" +version = "9.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ea04a7c5c055c175f189b6dc6ba036fd62306b58c66c9f6389036c503a3f4" +checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" dependencies = [ "base64 0.21.7", "js-sys", @@ -2236,12 +2214,12 @@ dependencies = [ [[package]] name = "lettre" -version = "0.11.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357ff5edb6d8326473a64c82cf41ddf78ab116f89668c50c4fac1b321e5e80f4" +checksum = "47460276655930189e0919e4fbf46e46476b14f934f18a63dd726a5fb7b60e2e" dependencies = [ "async-trait", - "base64 0.21.7", + "base64 0.22.0", "chumsky", "email-encoding", "email_address", @@ -2285,12 +2263,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -2361,9 +2333,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mime" @@ -2412,14 +2384,14 @@ name = "model_derive" version = "0.1.2" dependencies = [ "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] name = "multimap" -version = "0.8.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" [[package]] name = "native-tls" @@ -2557,7 +2529,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -2689,7 +2661,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -2700,9 +2672,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.101" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", @@ -2721,9 +2693,9 @@ dependencies = [ [[package]] name = "ordered-multimap" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d6a8c22fc714f0c2373e6091bf6f5e9b37b1bc0b1184874b7e0a4e303d318f" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" dependencies = [ "dlv-list", "hashbrown 0.14.3", @@ -2861,11 +2833,11 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pem" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ - "base64 0.21.7", + "base64 0.22.0", "serde", ] @@ -2886,9 +2858,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" dependencies = [ "memchr", "thiserror", @@ -2897,9 +2869,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" dependencies = [ "pest", "pest_generator", @@ -2907,22 +2879,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] name = "pest_meta" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" dependencies = [ "once_cell", "pest", @@ -2936,7 +2908,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.2.5", + "indexmap 2.2.6", ] [[package]] @@ -2994,14 +2966,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -3038,9 +3010,9 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "platforms" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" [[package]] name = "polyval" @@ -3068,12 +3040,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.2.16" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" dependencies = [ "proc-macro2", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -3129,9 +3101,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -3148,15 +3120,15 @@ dependencies = [ "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", "unarray", ] [[package]] name = "prost" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" dependencies = [ "bytes", "prost-derive", @@ -3164,13 +3136,13 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" dependencies = [ "bytes", - "heck 0.4.1", - "itertools 0.11.0", + "heck 0.5.0", + "itertools 0.12.1", "log", "multimap", "once_cell", @@ -3179,29 +3151,28 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.53", + "syn 2.0.60", "tempfile", - "which", ] [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] name = "prost-types" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +checksum = "3235c33eb02c1f1e212abdbe34c78b264b038fb58ca612664343271e36e55ffe" dependencies = [ "prost", ] @@ -3245,9 +3216,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -3314,14 +3285,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", "regex-automata 0.4.6", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -3341,7 +3312,7 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -3352,15 +3323,15 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "reqwest" -version = "0.11.26" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bf93c4af7a8bb7d879d51cebe797356ff10ae8516ace542b5182d9dcac10b2" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", "bytes", @@ -3369,7 +3340,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.3.25", + "h2", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", @@ -3384,12 +3355,12 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.10", + "rustls 0.21.11", "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "system-configuration", "tokio", "tokio-native-tls", @@ -3540,9 +3511,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "e3cc72858054fcff6d7dea32df2aeaee6a7c24227366d7ea429aada2f26b16ad" dependencies = [ "bitflags 2.5.0", "errno", @@ -3553,9 +3524,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ "log", "ring 0.17.8", @@ -3565,14 +3536,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.2" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.2", + "rustls-webpki 0.102.3", "subtle", "zeroize", ] @@ -3584,7 +3555,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", - "rustls-pemfile 2.1.1", + "rustls-pemfile 2.1.2", "rustls-pki-types", "schannel", "security-framework", @@ -3601,19 +3572,19 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f48172685e6ff52a556baa527774f61fcaa884f59daf3375c62a3f1cd2549dab" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64 0.21.7", + "base64 0.22.0", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" [[package]] name = "rustls-webpki" @@ -3627,9 +3598,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.2" +version = "0.102.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf" dependencies = [ "ring 0.17.8", "rustls-pki-types", @@ -3638,9 +3609,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" [[package]] name = "ryu" @@ -3659,9 +3630,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.0" +version = "2.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ef2175c2907e7c8bc0a9c3f86aeb5ec1f3b275300ad58a44d0c3ae379a5e52e" +checksum = "7c453e59a955f81fb62ee5d596b450383d699f152d350e9d23a0db2adb78e4c0" dependencies = [ "cfg-if", "derive_more", @@ -3671,9 +3642,9 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.0" +version = "2.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b8eb8fd61c5cdd3390d9b2132300a7e7618955b98b8416f118c1b4e144f" +checksum = "18cf6c6447f813ef19eb450e985bcce6705f9ce7660db221b59093d15c79c4b7" dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", @@ -3751,9 +3722,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -3764,9 +3735,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" dependencies = [ "core-foundation-sys", "libc", @@ -3780,9 +3751,9 @@ checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] @@ -3809,20 +3780,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", @@ -3881,7 +3852,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.5", + "indexmap 2.2.6", "serde", "serde_derive", "serde_json", @@ -3898,19 +3869,20 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] name = "serde_yaml" -version = "0.8.26" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 1.9.3", + "indexmap 2.2.6", + "itoa", "ryu", "serde", - "yaml-rust", + "unsafe-libyaml", ] [[package]] @@ -4014,9 +3986,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -4099,7 +4071,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.2.5", + "indexmap 2.2.6", "ipnetwork", "log", "memchr", @@ -4292,9 +4264,9 @@ dependencies = [ [[package]] name = "ssh-key" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b71299a724c8d84956caaf8fc3b3ea57c3587fe2d0b800cd0dc1f3599905d7e" +checksum = "ca9b366a80cf18bb6406f4cf4d10aebfb46140a8c0c33f666a144c5c76ecbafc" dependencies = [ "p256", "p384", @@ -4348,9 +4320,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "struct-patch" @@ -4369,7 +4341,7 @@ checksum = "f14a349c27ebe59faba22f933c9c734d428da7231e88a247e9d8c61eea964ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -4391,7 +4363,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -4413,9 +4385,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.53" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", @@ -4428,6 +4400,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "synstructure" version = "0.12.6" @@ -4503,22 +4481,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -4533,9 +4511,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -4554,9 +4532,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -4588,9 +4566,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -4622,7 +4600,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -4641,7 +4619,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls 0.21.11", "tokio", ] @@ -4651,7 +4629,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.22.2", + "rustls 0.22.4", "rustls-pki-types", "tokio", ] @@ -4693,7 +4671,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "toml_datetime", "winnow", ] @@ -4704,7 +4682,7 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "toml_datetime", "winnow", ] @@ -4715,7 +4693,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "toml_datetime", "winnow", ] @@ -4732,7 +4710,7 @@ dependencies = [ "base64 0.21.7", "bytes", "flate2", - "h2 0.3.25", + "h2", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", @@ -4741,7 +4719,7 @@ dependencies = [ "pin-project", "prost", "rustls-native-certs", - "rustls-pemfile 2.1.1", + "rustls-pemfile 2.1.2", "rustls-pki-types", "tokio", "tokio-rustls 0.25.0", @@ -4762,7 +4740,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -4842,7 +4820,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -4898,9 +4876,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "uaparser" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf694e7b0434d4fad6c879e984e8fdc3a62f5533c3d421762244f9e9d03f6927" +checksum = "2a4d8fcdf9685cad74cecf1553af084ab4c494e833c47d3c50ca32cba8035545" dependencies = [ "derive_more", "lazy_static", @@ -5048,6 +5026,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "untrusted" version = "0.7.1" @@ -5164,7 +5148,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", "wasm-bindgen-shared", ] @@ -5198,7 +5182,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5307,18 +5291,6 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - [[package]] name = "whoami" version = "1.5.1" @@ -5366,7 +5338,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -5384,7 +5356,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -5404,17 +5376,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -5425,9 +5398,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -5437,9 +5410,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -5449,9 +5422,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -5461,9 +5440,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -5473,9 +5452,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -5485,9 +5464,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -5497,9 +5476,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" @@ -5559,15 +5538,6 @@ dependencies = [ "time", ] -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "zerocopy" version = "0.7.32" @@ -5585,7 +5555,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] [[package]] @@ -5605,5 +5575,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.60", ] diff --git a/Dockerfile b/Dockerfile index cf8e819f6..e25ee8b1d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.75 as chef +FROM rust:1.77 as chef WORKDIR /build diff --git a/justfile b/justfile index 81597462b..b510d5c89 100644 --- a/justfile +++ b/justfile @@ -1,9 +1,11 @@ # build release binary build: cargo build --release + # remove test databases drop-test-dbs: ./drop_test_dbs.sh + # move tag to current commit move-tag TAG: # remove local tag @@ -16,3 +18,11 @@ move-tag TAG: git push # push new tag to remote git push origin {{TAG}} + +# format Rust project +format: + cargo +nightly --locked fmt --all # use nightly toolchain for better import handling + +# lint Rust project +lint: + cargo clippy --all-targets --all-features diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 6d833ff50..fcc85b9ec 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.75" +channel = "1.77" diff --git a/src/db/models/group.rs b/src/db/models/group.rs index 33bf950bb..ce8f00aad 100644 --- a/src/db/models/group.rs +++ b/src/db/models/group.rs @@ -72,6 +72,26 @@ impl Group { Ok(Vec::new()) } } + + /// Fetches a list of VPN locations where a given group is explicitly allowed. + /// This does not include VPN locations where all groups are implicitly allowed (admin group), + /// because no access control in configured. + pub async fn allowed_vpn_locations<'e, E>(&self, executor: E) -> Result, SqlxError> + where + E: PgExecutor<'e>, + { + if let Some(id) = self.id { + query_scalar!( + "SELECT wn.name FROM wireguard_network wn JOIN wireguard_network_allowed_group wnag ON wn.id = wnag.network_id \ + WHERE wnag.group_id = $1", + id + ) + .fetch_all(executor) + .await + } else { + Ok(Vec::new()) + } + } } impl WireguardNetwork { @@ -125,7 +145,7 @@ impl WireguardNetwork { transaction: &mut PgConnection, allowed_groups: Vec, ) -> Result<(), ModelError> { - info!("Setting allowed groups for network {self}"); + info!("Setting allowed groups for network {self} to : {allowed_groups:?}"); if allowed_groups.is_empty() { return self.clear_allowed_groups(transaction).await; } diff --git a/src/grpc/enrollment.rs b/src/grpc/enrollment.rs index 6a37bb8c7..683677baa 100644 --- a/src/grpc/enrollment.rs +++ b/src/grpc/enrollment.rs @@ -165,7 +165,7 @@ impl EnrollmentServer { let response = super::proto::EnrollmentStartResponse { admin: admin_info, user: Some(user_info), - deadline_timestamp: session_deadline.timestamp(), + deadline_timestamp: session_deadline.and_utc().timestamp(), final_page_content: enrollment .get_welcome_page_content(&mut transaction) .await?, @@ -510,7 +510,7 @@ impl From for ProtoDevice { name: device.name, pubkey: device.wireguard_pubkey, user_id: device.user_id, - created_at: device.created.timestamp(), + created_at: device.created.and_utc().timestamp(), } } } diff --git a/src/grpc/gateway.rs b/src/grpc/gateway.rs index f60f80073..ea994fcb6 100644 --- a/src/grpc/gateway.rs +++ b/src/grpc/gateway.rs @@ -4,7 +4,7 @@ use std::{ task::{Context, Poll}, }; -use chrono::{NaiveDateTime, Utc}; +use chrono::{DateTime, Utc}; use sqlx::{query, Error as SqlxError, PgExecutor}; use tokio::{ sync::{ @@ -156,8 +156,9 @@ impl WireguardPeerStats { collected_at: Utc::now().naive_utc(), upload: stats.upload as i64, download: stats.download as i64, - latest_handshake: NaiveDateTime::from_timestamp_opt(stats.latest_handshake as i64, 0) - .unwrap_or_default(), + latest_handshake: DateTime::from_timestamp(stats.latest_handshake as i64, 0) + .unwrap_or_default() + .naive_utc(), allowed_ips: Some(stats.allowed_ips), } } diff --git a/src/grpc/password_reset.rs b/src/grpc/password_reset.rs index 12a523341..c68a15c3c 100644 --- a/src/grpc/password_reset.rs +++ b/src/grpc/password_reset.rs @@ -161,7 +161,7 @@ impl PasswordResetServer { .await?; let response = PasswordResetStartResponse { - deadline_timestamp: session_deadline.timestamp(), + deadline_timestamp: session_deadline.and_utc().timestamp(), }; transaction.commit().await.map_err(|_| { diff --git a/src/handlers/group.rs b/src/handlers/group.rs index 64e708ead..d7f9d7e90 100644 --- a/src/handlers/group.rs +++ b/src/handlers/group.rs @@ -5,7 +5,7 @@ use axum::{ use serde_json::json; use sqlx::query_as; -use super::{ApiResponse, GroupInfo, Username}; +use super::{ApiResponse, EditGroupInfo, GroupInfo, Username}; use crate::{ appstate::AppState, auth::{SessionInfo, UserAdminRole}, @@ -98,10 +98,13 @@ pub(crate) async fn list_groups_info( let q_result = query_as!( GroupInfo, "SELECT g.name as name, \ - COALESCE(ARRAY_AGG(u.username) FILTER (WHERE u.username IS NOT NULL), '{}') as members \ + COALESCE(ARRAY_AGG(DISTINCT u.username) FILTER (WHERE u.username IS NOT NULL), '{}') as \"members!\", \ + COALESCE(ARRAY_AGG(DISTINCT wn.name) FILTER (WHERE wn.name IS NOT NULL), '{}') as \"vpn_locations!\" \ FROM \"group\" g \ LEFT JOIN \"group_user\" gu ON gu.group_id = g.id \ LEFT JOIN \"user\" u ON u.id = gu.user_id \ + LEFT JOIN \"wireguard_network_allowed_group\" wnag ON wnag.group_id = g.id \ + LEFT JOIN \"wireguard_network\" wn ON wn.id = wnag.network_id \ GROUP BY g.name" ) .fetch_all(&appstate.pool) @@ -139,9 +142,10 @@ pub(crate) async fn get_group( debug!("Retrieving group {name}"); if let Some(group) = Group::find_by_name(&appstate.pool, &name).await? { let members = group.member_usernames(&appstate.pool).await?; + let vpn_locations = group.allowed_vpn_locations(&appstate.pool).await?; info!("Retrieved group {name}"); Ok(ApiResponse { - json: json!(GroupInfo::new(name, Some(members))), + json: json!(GroupInfo::new(name, members, vpn_locations)), status: StatusCode::OK, }) } else { @@ -155,7 +159,7 @@ pub(crate) async fn get_group( pub(crate) async fn create_group( _role: UserAdminRole, State(appstate): State, - Json(group_info): Json, + Json(group_info): Json, ) -> Result { debug!("Creating group {}", group_info.name); @@ -167,16 +171,14 @@ pub(crate) async fn create_group( group.save(&appstate.pool).await?; // TODO: create group in LDAP - if let Some(ref members) = group_info.members { - for username in members { - let Some(user) = User::find_by_username(&mut *transaction, username).await? else { - let msg = format!("Failed to find user {username}"); - error!(msg); - return Err(WebError::ObjectNotFound(msg)); - }; - user.add_to_group(&mut *transaction, &group).await?; - // let _result = ldap_add_user_to_group(&mut *transaction, username, &group.name).await; - } + for username in &group_info.members { + let Some(user) = User::find_by_username(&mut *transaction, username).await? else { + let msg = format!("Failed to find user {username}"); + error!(msg); + return Err(WebError::ObjectNotFound(msg)); + }; + user.add_to_group(&mut *transaction, &group).await?; + // TODO: update LDAP } transaction.commit().await?; @@ -195,7 +197,7 @@ pub(crate) async fn modify_group( _role: UserAdminRole, State(appstate): State, Path(name): Path, - Json(group_info): Json, + Json(group_info): Json, ) -> Result { debug!("Modifying group {}", group_info.name); let Some(mut group) = Group::find_by_name(&appstate.pool, &name).await? else { @@ -211,38 +213,34 @@ pub(crate) async fn modify_group( if group.name != group_info.name { group.name = group_info.name; group.save(&mut *transaction).await?; - // let _result = ldap_modify_group(&mut *transaction, &group.name, &group).await; + // TODO: update LDAP } // Modify group members. - if let Some(ref members) = group_info.members { - let mut current_members = group.members(&mut *transaction).await?; - for username in members { - if let Some(index) = current_members - .iter() - .position(|gm| &gm.username == username) - { - // This member is already in the group. - current_members.remove(index); - continue; - } - - // Add new members to the group. - if let Some(user) = User::find_by_username(&mut *transaction, username).await? { - user.add_to_group(&mut *transaction, &group).await?; - // let _result = - // ldap_add_user_to_group(&mut *transaction, username, &group.name).await; - } + let mut current_members = group.members(&mut *transaction).await?; + for username in &group_info.members { + if let Some(index) = current_members + .iter() + .position(|gm| &gm.username == username) + { + // This member is already in the group. + current_members.remove(index); + continue; } - // Remove outstanding members. - for user in current_members { - user.remove_from_group(&mut *transaction, &group).await?; - // let _result = - // ldap_remove_user_from_group(&mut *transaction, &user.username, &group.name).await; + // Add new members to the group. + if let Some(user) = User::find_by_username(&mut *transaction, username).await? { + user.add_to_group(&mut *transaction, &group).await?; + // TODO: update LDAP } } + // Remove outstanding members. + for user in current_members { + user.remove_from_group(&mut *transaction, &group).await?; + // TODO: update LDAP + } + transaction.commit().await?; WireguardNetwork::sync_all_networks(&appstate).await?; @@ -325,8 +323,8 @@ pub(crate) async fn remove_group_member( user.username, group.name ); user.remove_from_group(&appstate.pool, &group).await?; - // let _result = - // ldap_remove_user_from_group(&appstate.pool, &user.username, &group.name).await; + // TODO: update LDAP + WireguardNetwork::sync_all_networks(&appstate).await?; info!("Removed user: {} from group: {}", user.username, group.name); Ok(ApiResponse { diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 768256ca3..0ee11dc38 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -173,19 +173,28 @@ impl AuthCode { #[derive(Deserialize, Serialize)] pub struct GroupInfo { pub name: String, - pub members: Option>, + pub members: Vec, + pub vpn_locations: Vec, } impl GroupInfo { #[must_use] - pub fn new>(name: S, members: Option>) -> Self { + pub fn new>(name: S, members: Vec, vpn_locations: Vec) -> Self { Self { name: name.into(), members, + vpn_locations, } } } +/// Dedicated `GroupInfo` variant for group modification operations. +#[derive(Deserialize, Serialize)] +pub struct EditGroupInfo { + pub name: String, + pub members: Vec, +} + #[derive(Deserialize, Serialize)] pub struct Username { pub username: String, diff --git a/tests/group.rs b/tests/group.rs index dc62ff9d2..31040e0a9 100644 --- a/tests/group.rs +++ b/tests/group.rs @@ -2,6 +2,7 @@ mod common; use defguard::handlers::{Auth, GroupInfo}; use reqwest::StatusCode; +use serde_json::json; use self::common::make_test_client; @@ -15,7 +16,7 @@ async fn test_create_group() { assert_eq!(response.status(), StatusCode::OK); // Create new group. - let data = GroupInfo::new("hogwards", Some(vec!["hpotter".into()])); + let data = GroupInfo::new("hogwards", vec!["hpotter".into()], Vec::new()); let response = client.post("/api/v1/group").json(&data).send().await; assert_eq!(response.status(), StatusCode::CREATED); @@ -42,12 +43,12 @@ async fn test_modify_group() { assert_eq!(response.status(), StatusCode::OK); // Create new group. - let data = GroupInfo::new("hogwards", Some(vec!["hpotter".into()])); + let data = GroupInfo::new("hogwards", vec!["hpotter".into()], Vec::new()); let response = client.post("/api/v1/group").json(&data).send().await; assert_eq!(response.status(), StatusCode::CREATED); // Rename group. - let data = GroupInfo::new("gryffindor", None); + let data = GroupInfo::new("gryffindor", Vec::new(), Vec::new()); let response = client .put("/api/v1/group/hogwards") .json(&data) @@ -76,7 +77,7 @@ async fn test_modify_group_members() { assert_eq!(response.status(), StatusCode::OK); // Create new group. - let data = GroupInfo::new("hogwards", Some(vec!["hpotter".into()])); + let data = GroupInfo::new("hogwards", vec!["hpotter".into()], Vec::new()); let response = client.post("/api/v1/group").json(&data).send().await; assert_eq!(response.status(), StatusCode::CREATED); @@ -84,10 +85,10 @@ async fn test_modify_group_members() { let response = client.get("/api/v1/group/hogwards").send().await; assert_eq!(response.status(), StatusCode::OK); let group_info: GroupInfo = response.json().await; - assert_eq!(group_info.members.unwrap(), vec!["hpotter".to_string()]); + assert_eq!(group_info.members, vec!["hpotter".to_string()]); // Change group members. - let data = GroupInfo::new("hogwards", Some(Vec::new())); + let data = GroupInfo::new("hogwards", Vec::new(), Vec::new()); let response = client .put("/api/v1/group/hogwards") .json(&data) @@ -99,5 +100,51 @@ async fn test_modify_group_members() { let response = client.get("/api/v1/group/hogwards").send().await; assert_eq!(response.status(), StatusCode::OK); let group_info: GroupInfo = response.json().await; - assert!(group_info.members.unwrap().is_empty()); + assert!(group_info.members.is_empty()); +} + +#[tokio::test] +async fn test_modify_group_no_locations_in_request() { + let (client, _) = make_test_client().await; + + // Authorize as an administrator. + let auth = Auth::new("admin", "pass123"); + let response = client.post("/api/v1/auth").json(&auth).send().await; + assert_eq!(response.status(), StatusCode::OK); + + // Create new group. + let data = json!({ + "name": "hogwards", + "members": [ + "hpotter", + "admin" + ] + }); + let response = client.post("/api/v1/group").json(&data).send().await; + assert_eq!(response.status(), StatusCode::CREATED); + + // Rename group. + let data = json!({ + "name": "gryffindor", + "members": [ + "hpotter", + ] + }); + let response = client + .put("/api/v1/group/hogwards") + .json(&data) + .send() + .await; + assert_eq!(response.status(), StatusCode::OK); + + // Try to get the group by its old name. + let response = client.get("/api/v1/group/hogwards").send().await; + assert_eq!(response.status(), StatusCode::NOT_FOUND); + + // Get group info. + let response = client.get("/api/v1/group/gryffindor").send().await; + assert_eq!(response.status(), StatusCode::OK); + let group_info: GroupInfo = response.json().await; + assert_eq!(group_info.name, "gryffindor"); + assert_eq!(group_info.members, vec!["hpotter"]); } diff --git a/tests/wireguard.rs b/tests/wireguard.rs index 59446a48a..5da65cf49 100644 --- a/tests/wireguard.rs +++ b/tests/wireguard.rs @@ -8,7 +8,7 @@ use defguard::{ }, Device, GatewayEvent, WireguardNetwork, }, - handlers::{wireguard::WireguardNetworkData, Auth}, + handlers::{wireguard::WireguardNetworkData, Auth, GroupInfo}, }; use matches::assert_matches; use reqwest::StatusCode; @@ -53,6 +53,11 @@ async fn test_network() { let event = wg_rx.try_recv().unwrap(); assert_matches!(event, GatewayEvent::NetworkCreated(..)); + // check vpn locations for `admin` group + let response = client.get("/api/v1/group/admin").send().await; + let group_info: GroupInfo = response.json().await; + assert!(group_info.vpn_locations.is_empty()); + // modify network let network_data = WireguardNetworkData { name: "my network".into(), @@ -61,7 +66,7 @@ async fn test_network() { port: 55555, allowed_ips: Some("10.1.1.0/24".into()), dns: None, - allowed_groups: vec![], + allowed_groups: vec!["admin".into()], mfa_enabled: false, keepalive_interval: DEFAULT_KEEPALIVE_INTERVAL, peer_disconnect_threshold: DEFAULT_DISCONNECT_THRESHOLD, @@ -75,6 +80,12 @@ async fn test_network() { let event = wg_rx.try_recv().unwrap(); assert_matches!(event, GatewayEvent::NetworkModified(..)); + // check vpn locations for `admin` group + let response = client.get("/api/v1/group/admin").send().await; + assert_eq!(response.status(), StatusCode::OK); + let group_info: GroupInfo = response.json().await; + assert_eq!(group_info.vpn_locations, vec!["my network"]); + // list networks let response = client.get("/api/v1/network").send().await; assert_eq!(response.status(), StatusCode::OK); diff --git a/web/src/i18n/en/index.ts b/web/src/i18n/en/index.ts index bd1427f8a..b17b71b4e 100644 --- a/web/src/i18n/en/index.ts +++ b/web/src/i18n/en/index.ts @@ -23,6 +23,7 @@ const en: BaseTranslation = { delete: 'Delete', rename: 'Rename', copy: 'Copy', + edit: 'Edit', }, key: 'Key', name: 'Name', @@ -45,6 +46,21 @@ const en: BaseTranslation = { searchPlaceholder: 'Filter/Search', submit: 'Create group', }, + editGroup: { + title: 'Edit group', + selectAll: 'Select all users', + groupName: 'Group name', + searchPlaceholder: 'Filter/Search', + submit: 'Update group', + }, + deleteGroup: { + title: 'Delete group {name:string}', + subTitle: 'This action will permanently delete this group.', + locationListHeader: 'This group is currently assigned to following VPN Locations:', + locationListFooter: `If this is the only allowed group for a given location, the location will become accessible to all users.`, + submit: 'Delete group', + cancel: 'Cancel', + }, deviceConfig: { title: 'Device VPN configurations', }, diff --git a/web/src/i18n/i18n-types.ts b/web/src/i18n/i18n-types.ts index 6fa101406..40142d1f6 100644 --- a/web/src/i18n/i18n-types.ts +++ b/web/src/i18n/i18n-types.ts @@ -86,6 +86,10 @@ type RootTranslation = { * C​o​p​y */ copy: string + /** + * E​d​i​t + */ + edit: string } /** * K​e​y @@ -147,6 +151,55 @@ type RootTranslation = { */ submit: string } + editGroup: { + /** + * E​d​i​t​ ​g​r​o​u​p + */ + title: string + /** + * S​e​l​e​c​t​ ​a​l​l​ ​u​s​e​r​s + */ + selectAll: string + /** + * G​r​o​u​p​ ​n​a​m​e + */ + groupName: string + /** + * F​i​l​t​e​r​/​S​e​a​r​c​h + */ + searchPlaceholder: string + /** + * U​p​d​a​t​e​ ​g​r​o​u​p + */ + submit: string + } + deleteGroup: { + /** + * D​e​l​e​t​e​ ​g​r​o​u​p​ ​{​n​a​m​e​} + * @param {string} name + */ + title: RequiredParams<'name'> + /** + * T​h​i​s​ ​a​c​t​i​o​n​ ​w​i​l​l​ ​p​e​r​m​a​n​e​n​t​l​y​ ​d​e​l​e​t​e​ ​t​h​i​s​ ​g​r​o​u​p​. + */ + subTitle: string + /** + * T​h​i​s​ ​g​r​o​u​p​ ​i​s​ ​c​u​r​r​e​n​t​l​y​ ​a​s​s​i​g​n​e​d​ ​t​o​ ​f​o​l​l​o​w​i​n​g​ ​V​P​N​ ​L​o​c​a​t​i​o​n​s​: + */ + locationListHeader: string + /** + * I​f​ ​t​h​i​s​ ​i​s​ ​t​h​e​ ​o​n​l​y​ ​a​l​l​o​w​e​d​ ​g​r​o​u​p​ ​f​o​r​ ​a​ ​g​i​v​e​n​ ​l​o​c​a​t​i​o​n​,​ ​t​h​e​ ​l​o​c​a​t​i​o​n​ ​w​i​l​l​ ​b​e​c​o​m​e​ ​<​b​>​a​c​c​e​s​s​i​b​l​e​ ​t​o​ ​a​l​l​ ​u​s​e​r​s​<​/​b​>​. + */ + locationListFooter: string + /** + * D​e​l​e​t​e​ ​g​r​o​u​p + */ + submit: string + /** + * C​a​n​c​e​l + */ + cancel: string + } deviceConfig: { /** * D​e​v​i​c​e​ ​V​P​N​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​s @@ -3879,6 +3932,10 @@ export type TranslationFunctions = { * Copy */ copy: () => LocalizedString + /** + * Edit + */ + edit: () => LocalizedString } /** * Key @@ -3940,6 +3997,54 @@ export type TranslationFunctions = { */ submit: () => LocalizedString } + editGroup: { + /** + * Edit group + */ + title: () => LocalizedString + /** + * Select all users + */ + selectAll: () => LocalizedString + /** + * Group name + */ + groupName: () => LocalizedString + /** + * Filter/Search + */ + searchPlaceholder: () => LocalizedString + /** + * Update group + */ + submit: () => LocalizedString + } + deleteGroup: { + /** + * Delete group {name} + */ + title: (arg: { name: string }) => LocalizedString + /** + * This action will permanently delete this group. + */ + subTitle: () => LocalizedString + /** + * This group is currently assigned to following VPN Locations: + */ + locationListHeader: () => LocalizedString + /** + * If this is the only allowed group for a given location, the location will become accessible to all users. + */ + locationListFooter: () => LocalizedString + /** + * Delete group + */ + submit: () => LocalizedString + /** + * Cancel + */ + cancel: () => LocalizedString + } deviceConfig: { /** * Device VPN configurations diff --git a/web/src/i18n/pl/index.ts b/web/src/i18n/pl/index.ts index d7a413aad..698fa3f43 100644 --- a/web/src/i18n/pl/index.ts +++ b/web/src/i18n/pl/index.ts @@ -18,6 +18,7 @@ const pl: Translation = { delete: 'Usuń', copy: 'Skopiuj', rename: 'Zmień nazwę', + edit: 'Edytuj', }, conditions: { and: 'I', @@ -45,6 +46,22 @@ const pl: Translation = { submit: 'Stwórz grupę', title: 'Dodaj grupę', }, + editGroup: { + groupName: 'Nazwa grupy', + searchPlaceholder: 'Szukaj', + selectAll: 'Zaznacz wszystkich', + submit: 'Zmień grupę', + title: 'Edytuj grupę', + }, + deleteGroup: { + title: 'Usuń grupę {name}', + subTitle: 'Grupa zostanie nieodwołalnie usunięta.', + locationListHeader: + 'Ta grupa jest obecnie przypisana do następujących lokalizacji:', + locationListFooter: `Jeżeli to jedyna dozwolona grupa dla danej lokalizacji, stanie się ona dostępna dla wszystkich użytkowników.`, + submit: 'Usuń grupę', + cancel: 'Wróć', + }, registerEmailMFA: { title: 'Skonfiguruj e-mail MFA', form: { @@ -1292,7 +1309,7 @@ Uwaga, podane tutaj konfiguracje nie posiadają klucza prywatnego. Musisz uzupe }, networkPage: { pageTitle: 'Edycja lokalizacji', - addNetwork: '+ Dodaj lokalizacje', + addNetwork: '+ Dodaj lokalizację', controls: { networkSelect: { label: 'Wybór lokalizacji', diff --git a/web/src/pages/groups/components/GroupsList/GroupsList.tsx b/web/src/pages/groups/components/GroupsList/GroupsList.tsx index 5d62d057d..33aa81db6 100644 --- a/web/src/pages/groups/components/GroupsList/GroupsList.tsx +++ b/web/src/pages/groups/components/GroupsList/GroupsList.tsx @@ -1,13 +1,16 @@ import './style.scss'; import { useMutation, useQueryClient } from '@tanstack/react-query'; +import parse from 'html-react-parser'; import { orderBy } from 'lodash-es'; -import { useCallback, useMemo } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import { useI18nContext } from '../../../../i18n/i18n-react'; import { EditButton } from '../../../../shared/defguard-ui/components/Layout/EditButton/EditButton'; import { EditButtonOption } from '../../../../shared/defguard-ui/components/Layout/EditButton/EditButtonOption'; import { EditButtonOptionStyleVariant } from '../../../../shared/defguard-ui/components/Layout/EditButton/types'; +import { ConfirmModal } from '../../../../shared/defguard-ui/components/Layout/modals/ConfirmModal/ConfirmModal'; +import { ConfirmModalType } from '../../../../shared/defguard-ui/components/Layout/modals/ConfirmModal/types'; import { ListHeader, ListSortDirection, @@ -82,6 +85,7 @@ type RowProps = { const CustomRow = ({ group }: RowProps) => { const openModal = useAddGroupModal((s) => s.open); + const [isDeleteModalOpen, setDeleteModalOpen] = useState(false); const { groups: { deleteGroup }, @@ -101,35 +105,75 @@ const CustomRow = ({ group }: RowProps) => { queryClient.invalidateQueries({ queryKey: [QueryKeys.FETCH_GROUPS], }); + setDeleteModalOpen(false); }, onError: () => { toaster.error(LL.messages.error()); }, }); - return ( -
-
-

{titleCase(group.name)}

+ const locationList = (locations: string[]) => ( + <> +
+
+

{LL.modals.deleteGroup.locationListHeader()}

+
    + {locations.map((locationName) => ( +
  • {locationName}
  • + ))} +
+
+
+

{parse(LL.modals.deleteGroup.locationListFooter())}

- - { - openModal(group); - }} - /> - {group.name.toLowerCase() !== 'admin' && ( + + ); + + return ( + <> +
+
+

{titleCase(group.name)}

+
+ { - mutate(group.name); + openModal(group); }} /> - )} - -
+ {group.name.toLowerCase() !== 'admin' && ( + { + setDeleteModalOpen(true); + }} + /> + )} +
+
+ setDeleteModalOpen(v)} + onSubmit={() => mutate(group.name)} + onCancel={() => setDeleteModalOpen(false)} + title={LL.modals.deleteGroup.title({ + name: group.name, + })} + subTitle={ +
+

{LL.modals.deleteGroup.subTitle()}

+ {group.vpn_locations.length > 0 && locationList(group.vpn_locations)} +
+ } + submitText={LL.modals.deleteGroup.submit()} + cancelText={LL.modals.deleteGroup.cancel()} + loading={isLoading} + /> + ); }; diff --git a/web/src/pages/groups/components/GroupsList/style.scss b/web/src/pages/groups/components/GroupsList/style.scss index 51f6be24d..4ec641f89 100644 --- a/web/src/pages/groups/components/GroupsList/style.scss +++ b/web/src/pages/groups/components/GroupsList/style.scss @@ -63,3 +63,10 @@ } } } + +#group-delete-modal { + ul { + display: inline-block; + text-align: left; + } +} diff --git a/web/src/pages/groups/components/modals/AddGroupModal/AddGroupModal.tsx b/web/src/pages/groups/components/modals/AddGroupModal/AddGroupModal.tsx index ab690cf3b..2be146fda 100644 --- a/web/src/pages/groups/components/modals/AddGroupModal/AddGroupModal.tsx +++ b/web/src/pages/groups/components/modals/AddGroupModal/AddGroupModal.tsx @@ -33,12 +33,13 @@ import { useAddGroupModal } from './useAddGroupModal'; export const AddGroupModal = () => { const isOpen = useAddGroupModal((s) => s.visible); const close = useAddGroupModal((s) => s.close); + const groupInfo = useAddGroupModal((s) => s.groupInfo); const { LL } = useI18nContext(); return ( @@ -66,8 +67,8 @@ const ModalContent = () => { } = useApi(); const queryClient = useQueryClient(); const { LL } = useI18nContext(); - const localLL = LL.modals.addGroup; const groupInfo = useAddGroupModal((s) => s.groupInfo); + const localLL = groupInfo ? LL.modals.editGroup : LL.modals.addGroup; const closeModal = useAddGroupModal((s) => s.close); const toaster = useToaster(); const [searchValue, setSearch] = useState(''); diff --git a/web/src/shared/types.ts b/web/src/shared/types.ts index ba7cf92e9..6d91636d2 100644 --- a/web/src/shared/types.ts +++ b/web/src/shared/types.ts @@ -980,5 +980,6 @@ export type Group = string; export type GroupInfo = { name: string; - members?: string[]; + members: string[]; + vpn_locations: string[]; };