sqlx: update dependency and protect against injections

This commit is contained in:
Valentin Tolmer 2022-03-22 20:45:59 +01:00 committed by nitnelave
parent bafb1dc5cc
commit 5e2eea0d97
10 changed files with 496 additions and 309 deletions

457
Cargo.lock generated
View File

@ -75,7 +75,7 @@ dependencies = [
"actix-service", "actix-service",
"actix-tls", "actix-tls",
"actix-utils", "actix-utils",
"ahash 0.7.4", "ahash",
"base64", "base64",
"bitflags", "bitflags",
"brotli2", "brotli2",
@ -89,7 +89,7 @@ dependencies = [
"h2", "h2",
"http", "http",
"httparse", "httparse",
"itoa", "itoa 0.4.8",
"language-tags", "language-tags",
"local-channel", "local-channel",
"log", "log",
@ -212,7 +212,7 @@ dependencies = [
"actix-service", "actix-service",
"actix-utils", "actix-utils",
"actix-web-codegen", "actix-web-codegen",
"ahash 0.7.4", "ahash",
"bytes", "bytes",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"cookie", "cookie",
@ -221,7 +221,7 @@ dependencies = [
"encoding_rs", "encoding_rs",
"futures-core", "futures-core",
"futures-util", "futures-util",
"itoa", "itoa 0.4.8",
"language-tags", "language-tags",
"log", "log",
"mime", "mime",
@ -306,26 +306,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.4.7" version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
[[package]]
name = "ahash"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "796540673305a66d127804eef19ad696f1f204b8c1025aaca4958c17eab32877"
dependencies = [
"getrandom 0.2.3",
"once_cell",
"version_check",
]
[[package]]
name = "ahash"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
dependencies = [ dependencies = [
"getrandom 0.2.3", "getrandom 0.2.3",
"once_cell", "once_cell",
@ -465,6 +448,12 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "base64ct"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c"
[[package]] [[package]]
name = "bincode" name = "bincode"
version = "1.3.3" version = "1.3.3"
@ -555,12 +544,6 @@ dependencies = [
"uuid", "uuid",
] ]
[[package]]
name = "build_const"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7"
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.7.0" version = "3.7.0"
@ -693,6 +676,12 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "const-oid"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b"
[[package]] [[package]]
name = "const_fn" name = "const_fn"
version = "0.4.8" version = "0.4.8"
@ -749,13 +738,19 @@ dependencies = [
[[package]] [[package]]
name = "crc" name = "crc"
version = "1.8.1" version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23"
dependencies = [ dependencies = [
"build_const", "crc-catalog",
] ]
[[package]]
name = "crc-catalog"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403"
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.2.1" version = "1.2.1"
@ -831,6 +826,17 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "crypto-bigint"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03"
dependencies = [
"generic-array",
"rand_core 0.6.3",
"subtle",
]
[[package]] [[package]]
name = "crypto-mac" name = "crypto-mac"
version = "0.10.1" version = "0.10.1"
@ -906,6 +912,16 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "der"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4"
dependencies = [
"const-oid",
"crypto-bigint",
]
[[package]] [[package]]
name = "derive_builder" name = "derive_builder"
version = "0.10.2" version = "0.10.2"
@ -976,6 +992,26 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "dirs"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]] [[package]]
name = "discard" name = "discard"
version = "1.0.4" version = "1.0.4"
@ -1086,6 +1122,18 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "flume"
version = "0.10.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a"
dependencies = [
"futures-core",
"futures-sink",
"pin-project",
"spin 0.9.2",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -1146,9 +1194,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.17" version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink", "futures-sink",
@ -1156,9 +1204,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.17" version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
[[package]] [[package]]
name = "futures-enum" name = "futures-enum"
@ -1173,9 +1221,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-executor" name = "futures-executor"
version = "0.3.17" version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-task", "futures-task",
@ -1183,19 +1231,28 @@ dependencies = [
] ]
[[package]] [[package]]
name = "futures-io" name = "futures-intrusive"
version = "0.3.17" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e"
dependencies = [
"futures-core",
"lock_api",
"parking_lot",
]
[[package]]
name = "futures-io"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.17" version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512"
dependencies = [ dependencies = [
"autocfg 1.0.1",
"proc-macro-hack",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
@ -1203,23 +1260,22 @@ dependencies = [
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.17" version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.17" version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
[[package]] [[package]]
name = "futures-util" name = "futures-util"
version = "0.3.17" version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
dependencies = [ dependencies = [
"autocfg 1.0.1",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-io", "futures-io",
@ -1229,8 +1285,6 @@ dependencies = [
"memchr", "memchr",
"pin-project-lite", "pin-project-lite",
"pin-utils", "pin-utils",
"proc-macro-hack",
"proc-macro-nested",
"slab", "slab",
] ]
@ -1430,23 +1484,23 @@ name = "hashbrown"
version = "0.9.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
dependencies = [
"ahash 0.4.7",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.11.2" version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [
"ahash",
]
[[package]] [[package]]
name = "hashlink" name = "hashlink"
version = "0.6.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d99cf782f0dc4372d26846bec3de7804ceb5df083c2d4462c0b8d2330e894fa8" checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf"
dependencies = [ dependencies = [
"hashbrown 0.9.1", "hashbrown 0.11.2",
] ]
[[package]] [[package]]
@ -1528,7 +1582,7 @@ checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
dependencies = [ dependencies = [
"bytes", "bytes",
"fnv", "fnv",
"itoa", "itoa 0.4.8",
] ]
[[package]] [[package]]
@ -1575,7 +1629,7 @@ dependencies = [
"http-body", "http-body",
"httparse", "httparse",
"httpdate", "httpdate",
"itoa", "itoa 0.4.8",
"pin-project-lite", "pin-project-lite",
"socket2", "socket2",
"tokio", "tokio",
@ -1622,12 +1676,12 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.7.0" version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
dependencies = [ dependencies = [
"autocfg 1.0.1", "autocfg 1.0.1",
"hashbrown 0.11.2", "hashbrown 0.9.1",
"serde", "serde",
] ]
@ -1667,6 +1721,12 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "itoa"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]] [[package]]
name = "jobserver" name = "jobserver"
version = "0.1.24" version = "0.1.24"
@ -1765,7 +1825,7 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
dependencies = [ dependencies = [
"spin", "spin 0.5.2",
] ]
[[package]] [[package]]
@ -1856,9 +1916,9 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.101" version = "0.2.121"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
[[package]] [[package]]
name = "libm" name = "libm"
@ -1868,9 +1928,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
[[package]] [[package]]
name = "libsqlite3-sys" name = "libsqlite3-sys"
version = "0.20.1" version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64d31059f22935e6c31830db5249ba2b7ecd54fd73a9909286f0a67aa55c2fbd" checksum = "d2cafc7c74096c336d9d27145f7ebd4f4b6f95ba16aa5a282387267e6925cb58"
dependencies = [ dependencies = [
"cc", "cc",
"pkg-config", "pkg-config",
@ -1923,6 +1983,7 @@ dependencies = [
"orion", "orion",
"rand 0.8.4", "rand 0.8.4",
"sea-query", "sea-query",
"sea-query-binder",
"secstr", "secstr",
"serde", "serde",
"serde_json", "serde_json",
@ -1949,6 +2010,7 @@ dependencies = [
"chrono", "chrono",
"graphql_client", "graphql_client",
"http", "http",
"indexmap",
"jwt", "jwt",
"lldap_auth", "lldap_auth",
"rand 0.8.4", "rand 0.8.4",
@ -2232,17 +2294,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "num-bigint"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
dependencies = [
"autocfg 1.0.1",
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-bigint" name = "num-bigint"
version = "0.3.3" version = "0.3.3"
@ -2256,9 +2307,9 @@ dependencies = [
[[package]] [[package]]
name = "num-bigint-dig" name = "num-bigint-dig"
version = "0.6.1" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d51546d704f52ef14b3c962b5776e53d5b862e5790e40a350d366c209bd7f7a" checksum = "4547ee5541c18742396ae2c895d0717d0f886d8823b8399cdaf7b07d63ad0480"
dependencies = [ dependencies = [
"autocfg 0.1.7", "autocfg 0.1.7",
"byteorder", "byteorder",
@ -2267,8 +2318,7 @@ dependencies = [
"num-integer", "num-integer",
"num-iter", "num-iter",
"num-traits", "num-traits",
"rand 0.7.3", "rand 0.8.4",
"serde",
"smallvec", "smallvec",
"zeroize", "zeroize",
] ]
@ -2301,6 +2351,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [ dependencies = [
"autocfg 1.0.1", "autocfg 1.0.1",
"libm",
] ]
[[package]] [[package]]
@ -2324,9 +2375,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.8.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
@ -2443,9 +2494,9 @@ dependencies = [
[[package]] [[package]]
name = "paste" name = "paste"
version = "1.0.5" version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5"
[[package]] [[package]]
name = "pear" name = "pear"
@ -2471,14 +2522,12 @@ dependencies = [
] ]
[[package]] [[package]]
name = "pem" name = "pem-rfc7468"
version = "0.8.3" version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" checksum = "84e93a3b1cc0510b03020f33f21e62acdde3dcaef432edc95bea377fbd4c2cd4"
dependencies = [ dependencies = [
"base64", "base64ct",
"once_cell",
"regex",
] ]
[[package]] [[package]]
@ -2528,6 +2577,30 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkcs1"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "116bee8279d783c0cf370efa1a94632f2108e5ef0bb32df31f051647810a4e2c"
dependencies = [
"der",
"pem-rfc7468",
"zeroize",
]
[[package]]
name = "pkcs8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447"
dependencies = [
"der",
"pem-rfc7468",
"pkcs1",
"spki",
"zeroize",
]
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.19" version = "0.3.19"
@ -2599,17 +2672,11 @@ version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro-nested"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.29" version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
@ -2629,9 +2696,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.9" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" checksum = "b4af2ec4714533fcdf07e886f17025ace8b997b9ce51204ee69b6da831c3da57"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -2742,13 +2809,24 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "redox_users"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7776223e2696f1aa4c6b0170e83212f47296a00424305117d013dfe86fb0fe55"
dependencies = [
"getrandom 0.2.3",
"redox_syscall",
"thiserror",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.5.4" version = "1.5.4"
@ -2835,9 +2913,9 @@ dependencies = [
[[package]] [[package]]
name = "rsa" name = "rsa"
version = "0.3.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3648b669b10afeab18972c105e284a7b953a669b0be3514c27f9b17acab2f9cd" checksum = "e05c2603e2823634ab331437001b411b9ed11660fbc4066f3908c84a9439260d"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"digest", "digest",
@ -2846,12 +2924,10 @@ dependencies = [
"num-integer", "num-integer",
"num-iter", "num-iter",
"num-traits", "num-traits",
"pem", "pkcs1",
"rand 0.7.3", "pkcs8",
"sha2", "rand 0.8.4",
"simple_asn1",
"subtle", "subtle",
"thiserror",
"zeroize", "zeroize",
] ]
@ -2924,21 +3000,40 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "sea-query" name = "sea-query"
version = "0.9.6" version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/SeaQL/sea-query/?rev=f2b74b2875a1a5a5550a7c8658d3fcd385134925#f2b74b2875a1a5a5550a7c8658d3fcd385134925"
checksum = "f3266fa53846a5ac9eaf85709979acde05d9ba54a5fa4a0b35d897074f1569a2"
dependencies = [ dependencies = [
"chrono", "chrono",
"sea-query-derive", "sea-query-derive",
"sea-query-driver",
]
[[package]]
name = "sea-query-binder"
version = "0.1.0"
source = "git+https://github.com/SeaQL/sea-query/?rev=f2b74b2875a1a5a5550a7c8658d3fcd385134925#f2b74b2875a1a5a5550a7c8658d3fcd385134925"
dependencies = [
"sea-query",
"sqlx",
] ]
[[package]] [[package]]
name = "sea-query-derive" name = "sea-query-derive"
version = "0.1.2" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/SeaQL/sea-query/?rev=f2b74b2875a1a5a5550a7c8658d3fcd385134925#f2b74b2875a1a5a5550a7c8658d3fcd385134925"
checksum = "0f30d6681c05300d4d92aa3dce08585b52c775735d632bb1f16f9f68f29c832d" dependencies = [
"heck 0.4.0",
"proc-macro2",
"quote",
"syn",
"thiserror",
]
[[package]]
name = "sea-query-driver"
version = "0.1.1"
source = "git+https://github.com/SeaQL/sea-query/?rev=f2b74b2875a1a5a5550a7c8658d3fcd385134925#f2b74b2875a1a5a5550a7c8658d3fcd385134925"
dependencies = [ dependencies = [
"heck 0.3.3",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
@ -3012,18 +3107,18 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.130" version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.130" version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -3032,12 +3127,12 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.67" version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"itoa", "itoa 1.0.1",
"ryu", "ryu",
"serde", "serde",
] ]
@ -3049,7 +3144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
dependencies = [ dependencies = [
"form_urlencoded", "form_urlencoded",
"itoa", "itoa 0.4.8",
"ryu", "ryu",
"serde", "serde",
] ]
@ -3075,9 +3170,9 @@ checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.9.6" version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
dependencies = [ dependencies = [
"block-buffer", "block-buffer",
"cfg-if 1.0.0", "cfg-if 1.0.0",
@ -3125,17 +3220,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "simple_asn1"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b"
dependencies = [
"chrono",
"num-bigint 0.2.6",
"num-traits",
]
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.4" version = "0.4.4"
@ -3144,9 +3228,9 @@ checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.6.1" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]] [[package]]
name = "smartstring" name = "smartstring"
@ -3180,23 +3264,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]] [[package]]
name = "sqlformat" name = "spin"
version = "0.1.7" version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "684001e7985ec1a9a66963b77ed151ef22a7876b3fdd7e37a57ec774f54b7d96" checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5"
dependencies = [ dependencies = [
"lazy_static", "lock_api",
"maplit", ]
[[package]]
name = "spki"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32"
dependencies = [
"der",
]
[[package]]
name = "sqlformat"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4"
dependencies = [
"itertools",
"nom 7.0.0", "nom 7.0.0",
"regex",
"unicode_categories", "unicode_categories",
] ]
[[package]] [[package]]
name = "sqlx" name = "sqlx"
version = "0.5.1" version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2739d54a2ae9fdd0f545cb4e4b5574efb95e2ec71b7f921678e246fb20dcaaf" checksum = "fc15591eb44ffb5816a4a70a7efd5dd87bfd3aa84c4c200401c4396140525826"
dependencies = [ dependencies = [
"sqlx-core", "sqlx-core",
"sqlx-macros", "sqlx-macros",
@ -3204,11 +3304,11 @@ dependencies = [
[[package]] [[package]]
name = "sqlx-core" name = "sqlx-core"
version = "0.5.1" version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1cad9cae4ca8947eba1a90e8ec7d3c59e7a768e2f120dc9013b669c34a90711" checksum = "195183bf6ff8328bb82c0511a83faf60aacf75840103388851db61d7a9854ae3"
dependencies = [ dependencies = [
"ahash 0.6.3", "ahash",
"atoi", "atoi",
"base64", "base64",
"bitflags", "bitflags",
@ -3216,29 +3316,32 @@ dependencies = [
"bytes", "bytes",
"chrono", "chrono",
"crc", "crc",
"crossbeam-channel",
"crossbeam-queue", "crossbeam-queue",
"crossbeam-utils",
"digest", "digest",
"dirs",
"either", "either",
"flume",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-executor",
"futures-intrusive",
"futures-util", "futures-util",
"generic-array", "generic-array",
"hashlink", "hashlink",
"hex", "hex",
"hmac 0.10.1", "hmac 0.11.0",
"itoa", "indexmap",
"itoa 1.0.1",
"libc", "libc",
"libsqlite3-sys", "libsqlite3-sys",
"log", "log",
"md-5", "md-5",
"memchr", "memchr",
"num-bigint 0.3.3", "num-bigint",
"once_cell", "once_cell",
"parking_lot", "paste",
"percent-encoding", "percent-encoding",
"rand 0.7.3", "rand 0.8.4",
"rsa", "rsa",
"serde", "serde",
"serde_json", "serde_json",
@ -3256,14 +3359,14 @@ dependencies = [
[[package]] [[package]]
name = "sqlx-macros" name = "sqlx-macros"
version = "0.5.1" version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01caee2b3935b4efe152f3262afbe51546ce3b1fc27ad61014e1b3cf5f55366e" checksum = "eee35713129561f5e55c554bba1c378e2a7e67f81257b7311183de98c50e6f94"
dependencies = [ dependencies = [
"dotenv", "dotenv",
"either", "either",
"futures",
"heck 0.3.3", "heck 0.3.3",
"once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"sha2", "sha2",
@ -3275,9 +3378,9 @@ dependencies = [
[[package]] [[package]]
name = "sqlx-rt" name = "sqlx-rt"
version = "0.3.0" version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ce2e16b6774c671cc183e1d202386fdf9cde1e8468c1894a7f2a63eb671c4f4" checksum = "b555e70fbbf84e269ec3858b7a6515bcfe7a166a7cc9c636dd6efd20431678b6"
dependencies = [ dependencies = [
"actix-rt", "actix-rt",
"native-tls", "native-tls",
@ -3374,9 +3477,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.75" version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -3443,18 +3546,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.28" version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "283d5230e63df9608ac7d9691adc1dfb6e701225436eb64d0b9a7f0a5a04f6ec" checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.28" version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa3884228611f5cd3608e2d409bf7dce832e4eb3135e3f11addbd7e41bd68e71" checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -3576,9 +3679,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-stream" name = "tokio-stream"
version = "0.1.7" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f" checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"pin-project-lite", "pin-project-lite",
@ -3976,9 +4079,9 @@ dependencies = [
[[package]] [[package]]
name = "whoami" name = "whoami"
version = "1.1.3" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7741161a40200a867c96dfa5574544efa4178cf4c8f770b62dd1cc0362d7ae1" checksum = "524b58fa5a20a2fb3014dd6358b70e6579692a56ef6fce928834e488f42f65e8"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
"web-sys", "web-sys",

View File

@ -16,3 +16,12 @@ rev = '67050812695b7a8a90b81b0637e347fc6629daed'
[patch.crates-io.yew_form_derive] [patch.crates-io.yew_form_derive]
git = 'https://github.com/sassman/yew_form/' git = 'https://github.com/sassman/yew_form/'
rev = '67050812695b7a8a90b81b0637e347fc6629daed' rev = '67050812695b7a8a90b81b0637e347fc6629daed'
# TODO: remove after https://github.com/SeaQL/sea-query has a release >0.25
[patch.crates-io.sea-query]
git = 'https://github.com/SeaQL/sea-query/'
rev = 'f2b74b2875a1a5a5550a7c8658d3fcd385134925'
[patch.crates-io.sea-query-binder]
git = 'https://github.com/SeaQL/sea-query/'
rev = 'f2b74b2875a1a5a5550a7c8658d3fcd385134925'

View File

@ -21,6 +21,9 @@ yew-router = "0.15"
yew_form = "0.1.8" yew_form = "0.1.8"
yew_form_derive = "*" yew_form_derive = "*"
# Needed because of https://github.com/tkaitchuck/aHash/issues/95
indexmap = "=1.6.2"
[dependencies.web-sys] [dependencies.web-sys]
version = "0.3" version = "0.3"
features = [ features = [

View File

@ -13,7 +13,7 @@ js = []
[dependencies] [dependencies]
rust-argon2 = "0.8" rust-argon2 = "0.8"
curve25519-dalek = "3" curve25519-dalek = "3"
digest = "*" digest = "0.9"
generic-array = "*" generic-array = "*"
rand = "0.8" rand = "0.8"
serde = "*" serde = "*"

View File

@ -34,7 +34,7 @@ native-tls = "0.2.10"
serde = "*" serde = "*"
serde_json = "1" serde_json = "1"
sha2 = "0.9" sha2 = "0.9"
sqlx-core = "=0.5.1" sqlx-core = "0.5.11"
thiserror = "*" thiserror = "*"
time = "0.2" time = "0.2"
tokio = { version = "1.13.1", features = ["full"] } tokio = { version = "1.13.1", features = ["full"] }
@ -64,7 +64,7 @@ features = [
] ]
[dependencies.sqlx] [dependencies.sqlx]
version = "0.5.1" version = "0.5.11"
features = [ features = [
"any", "any",
"chrono", "chrono",
@ -76,8 +76,12 @@ features = [
] ]
[dependencies.sea-query] [dependencies.sea-query]
version = "0.9.4" version = "^0.25"
features = ["with-chrono"] features = ["with-chrono", "sqlx-sqlite"]
[dependencies.sea-query-binder]
version = "*"
features = ["with-chrono", "sqlx-sqlite", "sqlx-any"]
[dependencies.figment] [dependencies.figment]
features = ["env", "toml"] features = ["env", "toml"]

View File

@ -2,8 +2,9 @@ use super::{error::*, handler::*, sql_tables::*};
use crate::infra::configuration::Configuration; use crate::infra::configuration::Configuration;
use async_trait::async_trait; use async_trait::async_trait;
use futures_util::StreamExt; use futures_util::StreamExt;
use sea_query::{Expr, Iden, Order, Query, SimpleExpr}; use sea_query::{Cond, Expr, Iden, Order, Query, SimpleExpr};
use sqlx::{FromRow, Row}; use sea_query_binder::SqlxBinder;
use sqlx::{query_as_with, query_with, FromRow, Row};
use std::collections::HashSet; use std::collections::HashSet;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -101,7 +102,7 @@ fn get_group_filter_expr(filter: GroupRequestFilter) -> SimpleExpr {
Query::select() Query::select()
.column(Memberships::GroupId) .column(Memberships::GroupId)
.from(Memberships::Table) .from(Memberships::Table)
.and_where(Expr::col(Memberships::UserId).eq(user)) .cond_where(Expr::col(Memberships::UserId).eq(user))
.take(), .take(),
), ),
} }
@ -114,7 +115,7 @@ impl BackendHandler for SqlBackendHandler {
filters: Option<UserRequestFilter>, filters: Option<UserRequestFilter>,
get_groups: bool, get_groups: bool,
) -> Result<Vec<UserAndGroups>> { ) -> Result<Vec<UserAndGroups>> {
let query = { let (query, values) = {
let mut query_builder = Query::select() let mut query_builder = Query::select()
.column((Users::Table, Users::UserId)) .column((Users::Table, Users::UserId))
.column(Users::Email) .column(Users::Email)
@ -154,14 +155,24 @@ impl BackendHandler for SqlBackendHandler {
&& filter != UserRequestFilter::Or(Vec::new()) && filter != UserRequestFilter::Or(Vec::new())
{ {
let (RequiresGroup(requires_group), condition) = get_user_filter_expr(filter); let (RequiresGroup(requires_group), condition) = get_user_filter_expr(filter);
query_builder.and_where(condition); query_builder.cond_where(condition);
if requires_group && !get_groups { if requires_group {
add_join_group_tables(&mut query_builder); query_builder
.left_join(
Memberships::Table,
Expr::tbl(Users::Table, Users::UserId)
.equals(Memberships::Table, Memberships::UserId),
)
.left_join(
Groups::Table,
Expr::tbl(Memberships::Table, Memberships::GroupId)
.equals(Groups::Table, Groups::GroupId),
);
} }
} }
} }
query_builder.to_string(DbQueryBuilder {}) query_builder.build_sqlx(DbQueryBuilder {})
}; };
log::error!("query: {}", &query); log::error!("query: {}", &query);
@ -170,7 +181,7 @@ impl BackendHandler for SqlBackendHandler {
let mut users = Vec::new(); let mut users = Vec::new();
// The rows are returned sorted by user_id. We group them by // The rows are returned sorted by user_id. We group them by
// this key which gives us one element (`rows`) per group. // this key which gives us one element (`rows`) per group.
for (_, rows) in &sqlx::query(&query) for (_, rows) in &query_with(&query, values)
.fetch_all(&self.sql_pool) .fetch_all(&self.sql_pool)
.await? .await?
.into_iter() .into_iter()
@ -200,7 +211,7 @@ impl BackendHandler for SqlBackendHandler {
} }
async fn list_groups(&self, filters: Option<GroupRequestFilter>) -> Result<Vec<Group>> { async fn list_groups(&self, filters: Option<GroupRequestFilter>) -> Result<Vec<Group>> {
let query: String = { let (query, values) = {
let mut query_builder = Query::select() let mut query_builder = Query::select()
.column((Groups::Table, Groups::GroupId)) .column((Groups::Table, Groups::GroupId))
.column(Groups::DisplayName) .column(Groups::DisplayName)
@ -223,11 +234,11 @@ impl BackendHandler for SqlBackendHandler {
if filter != GroupRequestFilter::And(Vec::new()) if filter != GroupRequestFilter::And(Vec::new())
&& filter != GroupRequestFilter::Or(Vec::new()) && filter != GroupRequestFilter::Or(Vec::new())
{ {
query_builder.and_where(get_group_filter_expr(filter)); query_builder.cond_where(get_group_filter_expr(filter));
} }
} }
query_builder.to_string(DbQueryBuilder {}) query_builder.build_sqlx(DbQueryBuilder {})
}; };
// For group_by. // For group_by.
@ -235,7 +246,7 @@ impl BackendHandler for SqlBackendHandler {
let mut groups = Vec::new(); let mut groups = Vec::new();
// The rows are returned sorted by display_name, equivalent to group_id. We group them by // The rows are returned sorted by display_name, equivalent to group_id. We group them by
// this key which gives us one element (`rows`) per group. // this key which gives us one element (`rows`) per group.
for ((group_id, display_name), rows) in &sqlx::query(&query) for ((group_id, display_name), rows) in &query_with(query.as_str(), values)
.fetch_all(&self.sql_pool) .fetch_all(&self.sql_pool)
.await? .await?
.into_iter() .into_iter()
@ -261,7 +272,7 @@ impl BackendHandler for SqlBackendHandler {
} }
async fn get_user_details(&self, user_id: &UserId) -> Result<User> { async fn get_user_details(&self, user_id: &UserId) -> Result<User> {
let query = Query::select() let (query, values) = Query::select()
.column(Users::UserId) .column(Users::UserId)
.column(Users::Email) .column(Users::Email)
.column(Users::DisplayName) .column(Users::DisplayName)
@ -270,25 +281,27 @@ impl BackendHandler for SqlBackendHandler {
.column(Users::Avatar) .column(Users::Avatar)
.column(Users::CreationDate) .column(Users::CreationDate)
.from(Users::Table) .from(Users::Table)
.and_where(Expr::col(Users::UserId).eq(user_id)) .cond_where(Expr::col(Users::UserId).eq(user_id))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
Ok(sqlx::query_as::<_, User>(&query) Ok(query_as_with::<_, User, _>(query.as_str(), values)
.fetch_one(&self.sql_pool) .fetch_one(&self.sql_pool)
.await?) .await?)
} }
async fn get_group_details(&self, group_id: GroupId) -> Result<GroupIdAndName> { async fn get_group_details(&self, group_id: GroupId) -> Result<GroupIdAndName> {
let query = Query::select() let (query, values) = Query::select()
.column(Groups::GroupId) .column(Groups::GroupId)
.column(Groups::DisplayName) .column(Groups::DisplayName)
.from(Groups::Table) .from(Groups::Table)
.and_where(Expr::col(Groups::GroupId).eq(group_id)) .cond_where(Expr::col(Groups::GroupId).eq(group_id))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
Ok(sqlx::query_as::<_, GroupIdAndName>(&query) Ok(
query_as_with::<_, GroupIdAndName, _>(query.as_str(), values)
.fetch_one(&self.sql_pool) .fetch_one(&self.sql_pool)
.await?) .await?,
)
} }
async fn get_user_groups(&self, user_id: &UserId) -> Result<HashSet<GroupIdAndName>> { async fn get_user_groups(&self, user_id: &UserId) -> Result<HashSet<GroupIdAndName>> {
@ -297,7 +310,7 @@ impl BackendHandler for SqlBackendHandler {
groups.insert(GroupIdAndName(GroupId(1), "lldap_admin".to_string())); groups.insert(GroupIdAndName(GroupId(1), "lldap_admin".to_string()));
return Ok(groups); return Ok(groups);
} }
let query: String = Query::select() let (query, values) = Query::select()
.column((Groups::Table, Groups::GroupId)) .column((Groups::Table, Groups::GroupId))
.column(Groups::DisplayName) .column(Groups::DisplayName)
.from(Groups::Table) .from(Groups::Table)
@ -306,10 +319,10 @@ impl BackendHandler for SqlBackendHandler {
Expr::tbl(Groups::Table, Groups::GroupId) Expr::tbl(Groups::Table, Groups::GroupId)
.equals(Memberships::Table, Memberships::GroupId), .equals(Memberships::Table, Memberships::GroupId),
) )
.and_where(Expr::col(Memberships::UserId).eq(user_id)) .cond_where(Expr::col(Memberships::UserId).eq(user_id))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&query) query_with(query.as_str(), values)
// Extract the group id from the row. // Extract the group id from the row.
.map(|row: DbRow| { .map(|row: DbRow| {
GroupIdAndName( GroupIdAndName(
@ -338,20 +351,21 @@ impl BackendHandler for SqlBackendHandler {
Users::LastName, Users::LastName,
Users::CreationDate, Users::CreationDate,
]; ];
let values = vec![ let (query, values) = Query::insert()
.into_table(Users::Table)
.columns(columns)
.values_panic(vec![
request.user_id.into(), request.user_id.into(),
request.email.into(), request.email.into(),
request.display_name.unwrap_or_default().into(), request.display_name.unwrap_or_default().into(),
request.first_name.unwrap_or_default().into(), request.first_name.unwrap_or_default().into(),
request.last_name.unwrap_or_default().into(), request.last_name.unwrap_or_default().into(),
chrono::Utc::now().naive_utc().into(), chrono::Utc::now().naive_utc().into(),
]; ])
let query = Query::insert() .build_sqlx(DbQueryBuilder {});
.into_table(Users::Table) query_with(query.as_str(), values)
.columns(columns) .execute(&self.sql_pool)
.values_panic(values) .await?;
.to_string(DbQueryBuilder {});
sqlx::query(&query).execute(&self.sql_pool).await?;
Ok(()) Ok(())
} }
@ -372,12 +386,14 @@ impl BackendHandler for SqlBackendHandler {
if values.is_empty() { if values.is_empty() {
return Ok(()); return Ok(());
} }
let query = Query::update() let (query, values) = Query::update()
.table(Users::Table) .table(Users::Table)
.values(values) .values(values)
.and_where(Expr::col(Users::UserId).eq(request.user_id)) .cond_where(Expr::col(Users::UserId).eq(request.user_id))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&query).execute(&self.sql_pool).await?; query_with(query.as_str(), values)
.execute(&self.sql_pool)
.await?;
Ok(()) Ok(())
} }
@ -389,66 +405,83 @@ impl BackendHandler for SqlBackendHandler {
if values.is_empty() { if values.is_empty() {
return Ok(()); return Ok(());
} }
let query = Query::update() let (query, values) = Query::update()
.table(Groups::Table) .table(Groups::Table)
.values(values) .values(values)
.and_where(Expr::col(Groups::GroupId).eq(request.group_id)) .cond_where(Expr::col(Groups::GroupId).eq(request.group_id))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&query).execute(&self.sql_pool).await?; query_with(query.as_str(), values)
.execute(&self.sql_pool)
.await?;
Ok(()) Ok(())
} }
async fn delete_user(&self, user_id: &UserId) -> Result<()> { async fn delete_user(&self, user_id: &UserId) -> Result<()> {
let delete_query = Query::delete() let (delete_query, values) = Query::delete()
.from_table(Users::Table) .from_table(Users::Table)
.and_where(Expr::col(Users::UserId).eq(user_id)) .cond_where(Expr::col(Users::UserId).eq(user_id))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&delete_query).execute(&self.sql_pool).await?; query_with(delete_query.as_str(), values)
.execute(&self.sql_pool)
.await?;
Ok(()) Ok(())
} }
async fn create_group(&self, group_name: &str) -> Result<GroupId> { async fn create_group(&self, group_name: &str) -> Result<GroupId> {
let query = Query::insert() let (query, values) = Query::insert()
.into_table(Groups::Table) .into_table(Groups::Table)
.columns(vec![Groups::DisplayName]) .columns(vec![Groups::DisplayName])
.values_panic(vec![group_name.into()]) .values_panic(vec![group_name.into()])
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&query).execute(&self.sql_pool).await?; query_with(query.as_str(), values)
let query = Query::select() .execute(&self.sql_pool)
.await?;
let (query, values) = Query::select()
.column(Groups::GroupId) .column(Groups::GroupId)
.from(Groups::Table) .from(Groups::Table)
.and_where(Expr::col(Groups::DisplayName).eq(group_name)) .cond_where(Expr::col(Groups::DisplayName).eq(group_name))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
let row = sqlx::query(&query).fetch_one(&self.sql_pool).await?; let row = query_with(query.as_str(), values)
.fetch_one(&self.sql_pool)
.await?;
Ok(GroupId(row.get::<i32, _>(&*Groups::GroupId.to_string()))) Ok(GroupId(row.get::<i32, _>(&*Groups::GroupId.to_string())))
} }
async fn delete_group(&self, group_id: GroupId) -> Result<()> { async fn delete_group(&self, group_id: GroupId) -> Result<()> {
let delete_query = Query::delete() let (delete_query, values) = Query::delete()
.from_table(Groups::Table) .from_table(Groups::Table)
.and_where(Expr::col(Groups::GroupId).eq(group_id)) .cond_where(Expr::col(Groups::GroupId).eq(group_id))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&delete_query).execute(&self.sql_pool).await?; query_with(delete_query.as_str(), values)
.execute(&self.sql_pool)
.await?;
Ok(()) Ok(())
} }
async fn add_user_to_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()> { async fn add_user_to_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()> {
let query = Query::insert() let (query, values) = Query::insert()
.into_table(Memberships::Table) .into_table(Memberships::Table)
.columns(vec![Memberships::UserId, Memberships::GroupId]) .columns(vec![Memberships::UserId, Memberships::GroupId])
.values_panic(vec![user_id.into(), group_id.into()]) .values_panic(vec![user_id.into(), group_id.into()])
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&query).execute(&self.sql_pool).await?; query_with(query.as_str(), values)
.execute(&self.sql_pool)
.await?;
Ok(()) Ok(())
} }
async fn remove_user_from_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()> { async fn remove_user_from_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()> {
let query = Query::delete() let (query, values) = Query::delete()
.from_table(Memberships::Table) .from_table(Memberships::Table)
.and_where(Expr::col(Memberships::GroupId).eq(group_id)) .cond_where(
.and_where(Expr::col(Memberships::UserId).eq(user_id)) Cond::all()
.to_string(DbQueryBuilder {}); .add(Expr::col(Memberships::GroupId).eq(group_id))
sqlx::query(&query).execute(&self.sql_pool).await?; .add(Expr::col(Memberships::UserId).eq(user_id)),
)
.build_sqlx(DbQueryBuilder {});
query_with(query.as_str(), values)
.execute(&self.sql_pool)
.await?;
Ok(()) Ok(())
} }
} }
@ -846,4 +879,26 @@ mod tests {
assert_eq!(get_user_names(&handler, None).await, vec!["val"]); assert_eq!(get_user_names(&handler, None).await, vec!["val"]);
} }
#[tokio::test]
async fn test_sql_injection() {
let sql_pool = get_initialized_db().await;
let config = get_default_config();
let handler = SqlBackendHandler::new(config, sql_pool);
let user_name = UserId::new(r#"bob"e"i'o;aü"#);
insert_user(&handler, user_name.as_str(), "bob00").await;
{
let users = handler
.list_users(None, false)
.await
.unwrap()
.into_iter()
.map(|u| u.user.user_id)
.collect::<Vec<_>>();
assert_eq!(users, vec![user_name.clone()]);
let user = handler.get_user_details(&user_name).await.unwrap();
assert_eq!(user.user_id, user_name);
}
}
} }

View File

@ -9,6 +9,7 @@ use async_trait::async_trait;
use lldap_auth::opaque; use lldap_auth::opaque;
use log::*; use log::*;
use sea_query::{Expr, Iden, Query}; use sea_query::{Expr, Iden, Query};
use sea_query_binder::SqlxBinder;
use secstr::SecUtf8; use secstr::SecUtf8;
use sqlx::Row; use sqlx::Row;
@ -53,12 +54,15 @@ impl SqlBackendHandler {
) -> Result<Option<opaque::server::ServerRegistration>> { ) -> Result<Option<opaque::server::ServerRegistration>> {
// Fetch the previously registered password file from the DB. // Fetch the previously registered password file from the DB.
let password_file_bytes = { let password_file_bytes = {
let query = Query::select() let (query, values) = Query::select()
.column(Users::PasswordHash) .column(Users::PasswordHash)
.from(Users::Table) .from(Users::Table)
.and_where(Expr::col(Users::UserId).eq(username)) .cond_where(Expr::col(Users::UserId).eq(username))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
if let Some(row) = sqlx::query(&query).fetch_optional(&self.sql_pool).await? { if let Some(row) = sqlx::query_with(query.as_str(), values)
.fetch_optional(&self.sql_pool)
.await?
{
if let Some(bytes) = if let Some(bytes) =
row.get::<Option<Vec<u8>>, _>(&*Users::PasswordHash.to_string()) row.get::<Option<Vec<u8>>, _>(&*Users::PasswordHash.to_string())
{ {
@ -94,12 +98,15 @@ impl LoginHandler for SqlBackendHandler {
))); )));
} }
} }
let query = Query::select() let (query, values) = Query::select()
.column(Users::PasswordHash) .column(Users::PasswordHash)
.from(Users::Table) .from(Users::Table)
.and_where(Expr::col(Users::UserId).eq(&request.name)) .cond_where(Expr::col(Users::UserId).eq(&request.name))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
if let Ok(row) = sqlx::query(&query).fetch_one(&self.sql_pool).await { if let Ok(row) = sqlx::query_with(&query, values)
.fetch_one(&self.sql_pool)
.await
{
if let Some(password_hash) = if let Some(password_hash) =
row.get::<Option<Vec<u8>>, _>(&*Users::PasswordHash.to_string()) row.get::<Option<Vec<u8>>, _>(&*Users::PasswordHash.to_string())
{ {
@ -209,15 +216,14 @@ impl OpaqueHandler for SqlOpaqueHandler {
opaque::server::registration::get_password_file(request.registration_upload); opaque::server::registration::get_password_file(request.registration_upload);
{ {
// Set the user password to the new password. // Set the user password to the new password.
let update_query = Query::update() let (update_query, values) = Query::update()
.table(Users::Table) .table(Users::Table)
.values(vec![( .value(Users::PasswordHash, password_file.serialize().into())
Users::PasswordHash, .cond_where(Expr::col(Users::UserId).eq(username))
password_file.serialize().into(), .build_sqlx(DbQueryBuilder {});
)]) sqlx::query_with(update_query.as_str(), values)
.and_where(Expr::col(Users::UserId).eq(username)) .execute(&self.sql_pool)
.to_string(DbQueryBuilder {}); .await?;
sqlx::query(&update_query).execute(&self.sql_pool).await?;
} }
Ok(()) Ok(())
} }

View File

@ -169,16 +169,16 @@ pub async fn init_table(pool: &Pool) -> sqlx::Result<()> {
.foreign_key( .foreign_key(
ForeignKey::create() ForeignKey::create()
.name("MembershipUserForeignKey") .name("MembershipUserForeignKey")
.table(Memberships::Table, Users::Table) .from(Memberships::Table, Memberships::UserId)
.col(Memberships::UserId, Users::UserId) .to(Users::Table, Users::UserId)
.on_delete(ForeignKeyAction::Cascade) .on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade), .on_update(ForeignKeyAction::Cascade),
) )
.foreign_key( .foreign_key(
ForeignKey::create() ForeignKey::create()
.name("MembershipGroupForeignKey") .name("MembershipGroupForeignKey")
.table(Memberships::Table, Groups::Table) .from(Memberships::Table, Memberships::GroupId)
.col(Memberships::GroupId, Groups::GroupId) .to(Groups::Table, Groups::GroupId)
.on_delete(ForeignKeyAction::Cascade) .on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade), .on_update(ForeignKeyAction::Cascade),
) )

View File

@ -55,8 +55,8 @@ pub async fn init_table(pool: &Pool) -> sqlx::Result<()> {
.foreign_key( .foreign_key(
ForeignKey::create() ForeignKey::create()
.name("JwtRefreshStorageUserForeignKey") .name("JwtRefreshStorageUserForeignKey")
.table(JwtRefreshStorage::Table, Users::Table) .from(JwtRefreshStorage::Table, JwtRefreshStorage::UserId)
.col(JwtRefreshStorage::UserId, Users::UserId) .to(Users::Table, Users::UserId)
.on_delete(ForeignKeyAction::Cascade) .on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade), .on_update(ForeignKeyAction::Cascade),
) )
@ -94,8 +94,8 @@ pub async fn init_table(pool: &Pool) -> sqlx::Result<()> {
.foreign_key( .foreign_key(
ForeignKey::create() ForeignKey::create()
.name("JwtStorageUserForeignKey") .name("JwtStorageUserForeignKey")
.table(JwtStorage::Table, Users::Table) .from(JwtStorage::Table, JwtStorage::UserId)
.col(JwtStorage::UserId, Users::UserId) .to(Users::Table, Users::UserId)
.on_delete(ForeignKeyAction::Cascade) .on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade), .on_update(ForeignKeyAction::Cascade),
) )
@ -127,8 +127,8 @@ pub async fn init_table(pool: &Pool) -> sqlx::Result<()> {
.foreign_key( .foreign_key(
ForeignKey::create() ForeignKey::create()
.name("PasswordResetTokensUserForeignKey") .name("PasswordResetTokensUserForeignKey")
.table(PasswordResetTokens::Table, Users::Table) .from(PasswordResetTokens::Table, PasswordResetTokens::UserId)
.col(PasswordResetTokens::UserId, Users::UserId) .to(Users::Table, Users::UserId)
.on_delete(ForeignKeyAction::Cascade) .on_delete(ForeignKeyAction::Cascade)
.on_update(ForeignKeyAction::Cascade), .on_update(ForeignKeyAction::Cascade),
) )

View File

@ -3,7 +3,8 @@ use crate::domain::{error::*, handler::UserId, sql_backend_handler::SqlBackendHa
use async_trait::async_trait; use async_trait::async_trait;
use futures_util::StreamExt; use futures_util::StreamExt;
use sea_query::{Expr, Iden, Query, SimpleExpr}; use sea_query::{Expr, Iden, Query, SimpleExpr};
use sqlx::Row; use sea_query_binder::SqlxBinder;
use sqlx::{query_as_with, query_with, Row};
use std::collections::HashSet; use std::collections::HashSet;
fn gen_random_string(len: usize) -> String { fn gen_random_string(len: usize) -> String {
@ -19,12 +20,12 @@ fn gen_random_string(len: usize) -> String {
#[async_trait] #[async_trait]
impl TcpBackendHandler for SqlBackendHandler { impl TcpBackendHandler for SqlBackendHandler {
async fn get_jwt_blacklist(&self) -> anyhow::Result<HashSet<u64>> { async fn get_jwt_blacklist(&self) -> anyhow::Result<HashSet<u64>> {
let query = Query::select() let (query, values) = Query::select()
.column(JwtStorage::JwtHash) .column(JwtStorage::JwtHash)
.from(JwtStorage::Table) .from(JwtStorage::Table)
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&query) query_with(&query, values)
.map(|row: DbRow| row.get::<i64, _>(&*JwtStorage::JwtHash.to_string()) as u64) .map(|row: DbRow| row.get::<i64, _>(&*JwtStorage::JwtHash.to_string()) as u64)
.fetch(&self.sql_pool) .fetch(&self.sql_pool)
.collect::<Vec<sqlx::Result<u64>>>() .collect::<Vec<sqlx::Result<u64>>>()
@ -45,7 +46,7 @@ impl TcpBackendHandler for SqlBackendHandler {
s.finish() s.finish()
}; };
let duration = chrono::Duration::days(30); let duration = chrono::Duration::days(30);
let query = Query::insert() let (query, values) = Query::insert()
.into_table(JwtRefreshStorage::Table) .into_table(JwtRefreshStorage::Table)
.columns(vec![ .columns(vec![
JwtRefreshStorage::RefreshTokenHash, JwtRefreshStorage::RefreshTokenHash,
@ -57,71 +58,75 @@ impl TcpBackendHandler for SqlBackendHandler {
user.into(), user.into(),
(chrono::Utc::now() + duration).naive_utc().into(), (chrono::Utc::now() + duration).naive_utc().into(),
]) ])
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&query).execute(&self.sql_pool).await?; query_with(&query, values).execute(&self.sql_pool).await?;
Ok((refresh_token, duration)) Ok((refresh_token, duration))
} }
async fn check_token(&self, refresh_token_hash: u64, user: &UserId) -> Result<bool> { async fn check_token(&self, refresh_token_hash: u64, user: &UserId) -> Result<bool> {
let query = Query::select() let (query, values) = Query::select()
.expr(SimpleExpr::Value(1.into())) .expr(SimpleExpr::Value(1.into()))
.from(JwtRefreshStorage::Table) .from(JwtRefreshStorage::Table)
.and_where(Expr::col(JwtRefreshStorage::RefreshTokenHash).eq(refresh_token_hash as i64)) .and_where(Expr::col(JwtRefreshStorage::RefreshTokenHash).eq(refresh_token_hash as i64))
.and_where(Expr::col(JwtRefreshStorage::UserId).eq(user)) .and_where(Expr::col(JwtRefreshStorage::UserId).eq(user))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
Ok(sqlx::query(&query) Ok(query_with(&query, values)
.fetch_optional(&self.sql_pool) .fetch_optional(&self.sql_pool)
.await? .await?
.is_some()) .is_some())
} }
async fn blacklist_jwts(&self, user: &UserId) -> Result<HashSet<u64>> { async fn blacklist_jwts(&self, user: &UserId) -> Result<HashSet<u64>> {
use sqlx::Result; use sqlx::Result;
let query = Query::select() let (query, values) = Query::select()
.column(JwtStorage::JwtHash) .column(JwtStorage::JwtHash)
.from(JwtStorage::Table) .from(JwtStorage::Table)
.and_where(Expr::col(JwtStorage::UserId).eq(user)) .and_where(Expr::col(JwtStorage::UserId).eq(user))
.and_where(Expr::col(JwtStorage::Blacklisted).eq(true)) .and_where(Expr::col(JwtStorage::Blacklisted).eq(true))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
let result = sqlx::query(&query) let result = query_with(&query, values)
.map(|row: DbRow| row.get::<i64, _>(&*JwtStorage::JwtHash.to_string()) as u64) .map(|row: DbRow| row.get::<i64, _>(&*JwtStorage::JwtHash.to_string()) as u64)
.fetch(&self.sql_pool) .fetch(&self.sql_pool)
.collect::<Vec<sqlx::Result<u64>>>() .collect::<Vec<sqlx::Result<u64>>>()
.await .await
.into_iter() .into_iter()
.collect::<Result<HashSet<u64>>>(); .collect::<Result<HashSet<u64>>>();
let query = Query::update() let (query, values) = Query::update()
.table(JwtStorage::Table) .table(JwtStorage::Table)
.values(vec![(JwtStorage::Blacklisted, true.into())]) .values(vec![(JwtStorage::Blacklisted, true.into())])
.and_where(Expr::col(JwtStorage::UserId).eq(user)) .and_where(Expr::col(JwtStorage::UserId).eq(user))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&query).execute(&self.sql_pool).await?; query_with(&query, values).execute(&self.sql_pool).await?;
Ok(result?) Ok(result?)
} }
async fn delete_refresh_token(&self, refresh_token_hash: u64) -> Result<()> { async fn delete_refresh_token(&self, refresh_token_hash: u64) -> Result<()> {
let query = Query::delete() let (query, values) = Query::delete()
.from_table(JwtRefreshStorage::Table) .from_table(JwtRefreshStorage::Table)
.and_where(Expr::col(JwtRefreshStorage::RefreshTokenHash).eq(refresh_token_hash)) .and_where(Expr::col(JwtRefreshStorage::RefreshTokenHash).eq(refresh_token_hash))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&query).execute(&self.sql_pool).await?; query_with(&query, values).execute(&self.sql_pool).await?;
Ok(()) Ok(())
} }
async fn start_password_reset(&self, user: &UserId) -> Result<Option<String>> { async fn start_password_reset(&self, user: &UserId) -> Result<Option<String>> {
let query = Query::select() let (query, values) = Query::select()
.column(Users::UserId) .column(Users::UserId)
.from(Users::Table) .from(Users::Table)
.and_where(Expr::col(Users::UserId).eq(user)) .and_where(Expr::col(Users::UserId).eq(user))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
// Check that the user exists. // Check that the user exists.
if sqlx::query(&query).fetch_one(&self.sql_pool).await.is_err() { if query_with(&query, values)
.fetch_one(&self.sql_pool)
.await
.is_err()
{
return Ok(None); return Ok(None);
} }
let token = gen_random_string(100); let token = gen_random_string(100);
let duration = chrono::Duration::minutes(10); let duration = chrono::Duration::minutes(10);
let query = Query::insert() let (query, values) = Query::insert()
.into_table(PasswordResetTokens::Table) .into_table(PasswordResetTokens::Table)
.columns(vec![ .columns(vec![
PasswordResetTokens::Token, PasswordResetTokens::Token,
@ -133,31 +138,33 @@ impl TcpBackendHandler for SqlBackendHandler {
user.into(), user.into(),
(chrono::Utc::now() + duration).naive_utc().into(), (chrono::Utc::now() + duration).naive_utc().into(),
]) ])
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&query).execute(&self.sql_pool).await?; query_with(&query, values).execute(&self.sql_pool).await?;
Ok(Some(token)) Ok(Some(token))
} }
async fn get_user_id_for_password_reset_token(&self, token: &str) -> Result<UserId> { async fn get_user_id_for_password_reset_token(&self, token: &str) -> Result<UserId> {
let query = Query::select() let (query, values) = Query::select()
.column(PasswordResetTokens::UserId) .column(PasswordResetTokens::UserId)
.from(PasswordResetTokens::Table) .from(PasswordResetTokens::Table)
.and_where(Expr::col(PasswordResetTokens::Token).eq(token)) .and_where(Expr::col(PasswordResetTokens::Token).eq(token))
.and_where( .and_where(
Expr::col(PasswordResetTokens::ExpiryDate).gt(chrono::Utc::now().naive_utc()), Expr::col(PasswordResetTokens::ExpiryDate).gt(chrono::Utc::now().naive_utc()),
) )
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
let (user_id,) = sqlx::query_as(&query).fetch_one(&self.sql_pool).await?; let (user_id,) = query_as_with(&query, values)
.fetch_one(&self.sql_pool)
.await?;
Ok(user_id) Ok(user_id)
} }
async fn delete_password_reset_token(&self, token: &str) -> Result<()> { async fn delete_password_reset_token(&self, token: &str) -> Result<()> {
let query = Query::delete() let (query, values) = Query::delete()
.from_table(PasswordResetTokens::Table) .from_table(PasswordResetTokens::Table)
.and_where(Expr::col(PasswordResetTokens::Token).eq(token)) .and_where(Expr::col(PasswordResetTokens::Token).eq(token))
.to_string(DbQueryBuilder {}); .build_sqlx(DbQueryBuilder {});
sqlx::query(&query).execute(&self.sql_pool).await?; query_with(&query, values).execute(&self.sql_pool).await?;
Ok(()) Ok(())
} }
} }