almost works, still need to impl auth

This commit is contained in:
Joe Ardent 2023-12-17 16:41:04 -08:00
parent d4a684de29
commit 57eb4001ee
12 changed files with 266 additions and 309 deletions

321
Cargo.lock generated
View file

@ -158,8 +158,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a41603f7cdbf5ac4af60760f17253eb6adf6ec5b6f14a7ed830cf687d375f163" checksum = "a41603f7cdbf5ac4af60760f17253eb6adf6ec5b6f14a7ed830cf687d375f163"
dependencies = [ dependencies = [
"askama", "askama",
"axum-core 0.4.1", "axum-core",
"http 1.0.0", "http",
] ]
[[package]] [[package]]
@ -175,7 +175,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde", "serde",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]
@ -231,7 +231,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]
@ -265,38 +265,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "axum"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
dependencies = [
"async-trait",
"axum-core 0.3.4",
"bitflags 1.3.2",
"bytes",
"futures-util",
"http 0.2.11",
"http-body 0.4.6",
"hyper 0.14.27",
"itoa",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"rustversion",
"serde",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tower",
"tower-layer",
"tower-service",
]
[[package]] [[package]]
name = "axum" name = "axum"
version = "0.7.2" version = "0.7.2"
@ -304,14 +272,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "202651474fe73c62d9e0a56c6133f7a0ff1dc1c8cf7a5b03381af2a26553ac9d" checksum = "202651474fe73c62d9e0a56c6133f7a0ff1dc1c8cf7a5b03381af2a26553ac9d"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum-core 0.4.1", "axum-core",
"axum-macros", "axum-macros",
"bytes", "bytes",
"futures-util", "futures-util",
"http 1.0.0", "http",
"http-body 1.0.0", "http-body",
"http-body-util", "http-body-util",
"hyper 1.0.1", "hyper",
"hyper-util", "hyper-util",
"itoa", "itoa",
"matchit", "matchit",
@ -331,23 +299,6 @@ dependencies = [
"tower-service", "tower-service",
] ]
[[package]]
name = "axum-core"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
dependencies = [
"async-trait",
"bytes",
"futures-util",
"http 0.2.11",
"http-body 0.4.6",
"mime",
"rustversion",
"tower-layer",
"tower-service",
]
[[package]] [[package]]
name = "axum-core" name = "axum-core"
version = "0.4.1" version = "0.4.1"
@ -357,8 +308,8 @@ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes",
"futures-util", "futures-util",
"http 1.0.0", "http",
"http-body 1.0.0", "http-body",
"http-body-util", "http-body-util",
"mime", "mime",
"pin-project-lite", "pin-project-lite",
@ -375,8 +326,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40f7051fdc094b6e5ea06cab9bca4b198c54dee4472a9419155f0ff19f19901e" checksum = "40f7051fdc094b6e5ea06cab9bca4b198c54dee4472a9419155f0ff19f19901e"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum-core 0.4.1", "axum-core",
"http 1.0.0", "http",
] ]
[[package]] [[package]]
@ -386,7 +337,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61b018d073eea48729e2309c8ecd7198e1eea90e132d99a5e1cc7e952053c8d6" checksum = "61b018d073eea48729e2309c8ecd7198e1eea90e132d99a5e1cc7e952053c8d6"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum 0.7.2", "axum",
"ring", "ring",
"serde", "serde",
"thiserror", "thiserror",
@ -407,24 +358,34 @@ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]
name = "axum-test" name = "axum-test"
version = "9.1.1" version = "14.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8822bb73c863cdc96a4476fdae6443495c9c312f9f659720aa4ea59d76074577" checksum = "56ac99db40006a1a3fffeb381f2a78cb341dbc99d07b561e8bd119e22a2b1b0f"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait",
"auto-future", "auto-future",
"axum 0.6.20", "axum",
"cookie 0.17.0", "bytes",
"hyper 0.14.27", "cookie",
"portpicker", "http",
"http-body-util",
"hyper",
"hyper-util",
"pretty_assertions",
"reserve-port",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded",
"smallvec",
"tokio", "tokio",
"tower",
"url",
] ]
[[package]] [[package]]
@ -621,7 +582,7 @@ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]
@ -638,9 +599,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]] [[package]]
name = "const-oid" name = "const-oid"
version = "0.9.5" version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]] [[package]]
name = "constant_time_eq" name = "constant_time_eq"
@ -648,16 +609,6 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "cookie"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24"
dependencies = [
"time 0.3.30",
"version_check",
]
[[package]] [[package]]
name = "cookie" name = "cookie"
version = "0.18.0" version = "0.18.0"
@ -701,9 +652,9 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
[[package]] [[package]]
name = "crossbeam-queue" name = "crossbeam-queue"
version = "0.3.8" version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" checksum = "b9bcf5bdbfdd6030fb4a1c497b5d5fc5921aa2f60d359a17e249c0e6df3de153"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"crossbeam-utils", "crossbeam-utils",
@ -711,9 +662,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.16" version = "0.8.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
] ]
@ -769,6 +720,12 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.9.0" version = "0.9.0"
@ -942,7 +899,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]
@ -1012,7 +969,7 @@ dependencies = [
"futures-core", "futures-core",
"futures-sink", "futures-sink",
"futures-util", "futures-util",
"http 1.0.0", "http",
"indexmap", "indexmap",
"slab", "slab",
"tokio", "tokio",
@ -1062,9 +1019,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]] [[package]]
name = "hkdf" name = "hkdf"
version = "0.12.3" version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
dependencies = [ dependencies = [
"hmac 0.12.1", "hmac 0.12.1",
] ]
@ -1090,22 +1047,11 @@ dependencies = [
[[package]] [[package]]
name = "home" name = "home"
version = "0.5.5" version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.52.0",
]
[[package]]
name = "http"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb"
dependencies = [
"bytes",
"fnv",
"itoa",
] ]
[[package]] [[package]]
@ -1119,17 +1065,6 @@ dependencies = [
"itoa", "itoa",
] ]
[[package]]
name = "http-body"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
"http 0.2.11",
"pin-project-lite",
]
[[package]] [[package]]
name = "http-body" name = "http-body"
version = "1.0.0" version = "1.0.0"
@ -1137,7 +1072,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
dependencies = [ dependencies = [
"bytes", "bytes",
"http 1.0.0", "http",
] ]
[[package]] [[package]]
@ -1148,16 +1083,16 @@ checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-util", "futures-util",
"http 1.0.0", "http",
"http-body 1.0.0", "http-body",
"pin-project-lite", "pin-project-lite",
] ]
[[package]] [[package]]
name = "http-range-header" name = "http-range-header"
version = "0.3.1" 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 = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" checksum = "3ce4ef31cda248bbdb6e6820603b82dfcd9e833db65a43e997a0ccec777d11fe"
[[package]] [[package]]
name = "httparse" name = "httparse"
@ -1180,29 +1115,6 @@ dependencies = [
"libm", "libm",
] ]
[[package]]
name = "hyper"
version = "0.14.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http 0.2.11",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"socket2 0.4.10",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "1.0.1" version = "1.0.1"
@ -1213,13 +1125,14 @@ dependencies = [
"futures-channel", "futures-channel",
"futures-util", "futures-util",
"h2", "h2",
"http 1.0.0", "http",
"http-body 1.0.0", "http-body",
"httparse", "httparse",
"httpdate", "httpdate",
"itoa", "itoa",
"pin-project-lite", "pin-project-lite",
"tokio", "tokio",
"want",
] ]
[[package]] [[package]]
@ -1231,11 +1144,11 @@ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
"futures-util", "futures-util",
"http 1.0.0", "http",
"http-body 1.0.0", "http-body",
"hyper 1.0.1", "hyper",
"pin-project-lite", "pin-project-lite",
"socket2 0.5.5", "socket2",
"tokio", "tokio",
"tower", "tower",
"tower-service", "tower-service",
@ -1576,7 +1489,7 @@ name = "optional_optional_user"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]
@ -1657,7 +1570,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]
@ -1699,15 +1612,6 @@ version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "portpicker"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be97d76faf1bfab666e1375477b23fde79eccf0276e9b63b92a39d676a889ba9"
dependencies = [
"rand",
]
[[package]] [[package]]
name = "powerfmt" name = "powerfmt"
version = "0.2.0" version = "0.2.0"
@ -1720,6 +1624,16 @@ version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "pretty_assertions"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66"
dependencies = [
"diff",
"yansi",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.70" version = "1.0.70"
@ -1831,6 +1745,16 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "reserve-port"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3969e7fe15c6c1532ba1a761628298e870bbd18c252fd41a58445f6091c372a0"
dependencies = [
"lazy_static",
"thiserror",
]
[[package]] [[package]]
name = "ring" name = "ring"
version = "0.17.7" version = "0.17.7"
@ -1941,7 +1865,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]
@ -2076,16 +2000,6 @@ version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "socket2"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d"
dependencies = [
"libc",
"winapi",
]
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.5.5" version = "0.5.5"
@ -2373,9 +2287,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.39" version = "2.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2403,22 +2317,22 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.50" version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.50" version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]
@ -2500,7 +2414,7 @@ dependencies = [
"parking_lot", "parking_lot",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
"socket2 0.5.5", "socket2",
"tokio-macros", "tokio-macros",
"tracing", "tracing",
"windows-sys 0.48.0", "windows-sys 0.48.0",
@ -2514,7 +2428,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]
@ -2576,10 +2490,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fd0118512cf0b3768f7fcccf0bef1ae41d68f2b45edc1e77432b36c97c56c6d" checksum = "4fd0118512cf0b3768f7fcccf0bef1ae41d68f2b45edc1e77432b36c97c56c6d"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum-core 0.4.1", "axum-core",
"cookie 0.18.0", "cookie",
"futures-util", "futures-util",
"http 1.0.0", "http",
"parking_lot", "parking_lot",
"pin-project-lite", "pin-project-lite",
"tower-layer", "tower-layer",
@ -2588,16 +2502,16 @@ dependencies = [
[[package]] [[package]]
name = "tower-http" name = "tower-http"
version = "0.4.4" 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 = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" checksum = "09e12e6351354851911bdf8c2b8f2ab15050c567d70a8b9a37ae7b8301a4080d"
dependencies = [ dependencies = [
"bitflags 2.4.1", "bitflags 2.4.1",
"bytes", "bytes",
"futures-core",
"futures-util", "futures-util",
"http 0.2.11", "http",
"http-body 0.4.6", "http-body",
"http-body-util",
"http-range-header", "http-range-header",
"httpdate", "httpdate",
"mime", "mime",
@ -2641,9 +2555,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d733b3ae4a6a4cb80cd585e87ffe1a1a7011174581785039c83c4cd63ee61c" checksum = "b1d733b3ae4a6a4cb80cd585e87ffe1a1a7011174581785039c83c4cd63ee61c"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum-core 0.4.1", "axum-core",
"futures", "futures",
"http 1.0.0", "http",
"parking_lot", "parking_lot",
"serde", "serde",
"serde_json", "serde_json",
@ -2702,7 +2616,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]
@ -2903,7 +2817,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2925,7 +2839,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2945,13 +2859,14 @@ dependencies = [
"askama_axum", "askama_axum",
"async-session", "async-session",
"async-trait", "async-trait",
"axum 0.7.2", "axum",
"axum-htmx", "axum-htmx",
"axum-login", "axum-login",
"axum-macros", "axum-macros",
"axum-test", "axum-test",
"chrono", "chrono",
"clap", "clap",
"http",
"julid-rs", "julid-rs",
"justerror", "justerror",
"optional_optional_user", "optional_optional_user",
@ -3144,23 +3059,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]] [[package]]
name = "zerocopy" name = "yansi"
version = "0.7.30" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
[[package]]
name = "zerocopy"
version = "0.7.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d"
dependencies = [ dependencies = [
"zerocopy-derive", "zerocopy-derive",
] ]
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.7.30" version = "0.7.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.39", "syn 2.0.41",
] ]
[[package]] [[package]]

View file

@ -20,6 +20,7 @@ axum-login = "0.10"
axum-macros = "0.4" axum-macros = "0.4"
chrono = { version = "0.4", default-features = false, features = ["std", "clock"] } chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }
clap = { version = "4", features = ["derive", "env", "unicode", "suggestions", "usage"] } clap = { version = "4", features = ["derive", "env", "unicode", "suggestions", "usage"] }
http = "1.0.0"
julid-rs = "1" julid-rs = "1"
justerror = "1" justerror = "1"
password-hash = { version = "0.5", features = ["std", "getrandom"] } password-hash = { version = "0.5", features = ["std", "getrandom"] }
@ -33,13 +34,13 @@ tokio = { version = "1", features = ["full", "tracing"], default-features = fals
tokio-retry = "0.3" tokio-retry = "0.3"
tokio-stream = "0.1" tokio-stream = "0.1"
tower = { version = "0.4", features = ["util", "timeout"], default-features = false } tower = { version = "0.4", features = ["util", "timeout"], default-features = false }
tower-http = { version = "0.4", features = ["add-extension", "trace", "tracing", "fs"], default-features = false } tower-http = { version = "0.5", features = ["add-extension", "trace", "tracing", "fs"], default-features = false }
tower-sessions = { version = "0.7", default-features = false, features = ["sqlite-store"] } tower-sessions = { version = "0.7", default-features = false, features = ["sqlite-store"] }
tracing = "0.1" tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] }
unicode-segmentation = "1" unicode-segmentation = "1"
[dev-dependencies] [dev-dependencies]
axum-test = "9" axum-test = "14"
serde_test = "1" serde_test = "1"

71
src/auth.rs Normal file
View file

@ -0,0 +1,71 @@
use async_trait::async_trait;
use axum_login::{AuthnBackend, UserId};
use sqlx::SqlitePool;
use tower_sessions::{
cookie::time::Duration, Expiry, SessionManagerLayer,
SqliteStore,
};
use crate::User;
const SESSION_TTL: Duration = Duration::new((365.2422 * 24. * 3600.0) as i64, 0);
#[derive(Debug, Clone)]
pub struct AuthStore(SqlitePool);
pub type AuthSession = axum_login::AuthSession<AuthStore>;
impl AuthStore {
pub fn new(pool: SqlitePool) -> Self {
AuthStore(pool)
}
}
impl std::ops::DerefMut for AuthStore {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl std::ops::Deref for AuthStore {
type Target = SqlitePool;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[async_trait]
impl AuthnBackend for AuthStore {
type User = User;
type Credentials = String;
type Error = sqlx::Error;
async fn authenticate(
&self,
_creds: Self::Credentials,
) -> Result<Option<Self::User>, Self::Error> {
todo!()
}
async fn get_user(&self, _user_id: &UserId<Self>) -> Result<Option<Self::User>, Self::Error> {
todo!()
}
}
pub async fn session_layer(pool: SqlitePool) -> SessionManagerLayer<SqliteStore> {
let store = SqliteStore::new(pool);
store
.migrate()
.await
.expect("Calling `migrate()` should be reliable, is the DB gone?");
SessionManagerLayer::new(store)
.with_secure(true)
.with_expiry(Expiry::OnInactivity(SESSION_TTL))
}

View file

@ -1,22 +1,14 @@
use async_session::SessionStore; use std::time::Duration;
use axum_login::{AuthManagerLayer, AuthManagerLayerBuilder, AuthSession, AuthUser, AuthnBackend};
use julid::Julid;
use sqlx::{ use sqlx::{
migrate::Migrator, migrate::Migrator,
sqlite::{SqliteConnectOptions, SqliteJournalMode, SqlitePoolOptions}, sqlite::{SqliteConnectOptions, SqliteJournalMode, SqlitePoolOptions},
SqlitePool, SqlitePool,
}; };
use tower_sessions::{
cookie::time::Duration, session_store::ExpiredDeletion, Expiry, Session, SessionManagerLayer,
SqliteStore,
};
use crate::User;
const MAX_CONNS: u32 = 200; const MAX_CONNS: u32 = 200;
const MIN_CONNS: u32 = 5; const MIN_CONNS: u32 = 5;
const TIMEOUT: u64 = 11; const TIMEOUT: u64 = 11;
const SESSION_TTL: Duration = Duration::new((365.2422 * 24. * 3600.0) as i64, 0);
pub fn get_db_pool() -> SqlitePool { pub fn get_db_pool() -> SqlitePool {
let db_filename = { let db_filename = {
@ -48,8 +40,7 @@ pub fn get_db_pool() -> SqlitePool {
.journal_mode(SqliteJournalMode::Wal) .journal_mode(SqliteJournalMode::Wal)
.synchronous(sqlx::sqlite::SqliteSynchronous::Normal) .synchronous(sqlx::sqlite::SqliteSynchronous::Normal)
.filename(&db_filename) .filename(&db_filename)
// need to build this out of band and put it in the project root; see instructions at // be sure to have run `make` so that the libjulid extension is built
// https://gitlab.com/nebkor/julid
.extension("./libjulid") .extension("./libjulid")
.busy_timeout(Duration::from_secs(TIMEOUT)) .busy_timeout(Duration::from_secs(TIMEOUT))
.create_if_missing(true); .create_if_missing(true);
@ -86,25 +77,6 @@ pub fn get_db_pool() -> SqlitePool {
pool pool
} }
pub async fn session_layer(pool: SqlitePool) -> SessionManagerLayer<SqliteStore> {
let store = SqliteStore::new(pool);
store
.migrate()
.await
.expect("Calling `migrate()` should be reliable, is the DB gone?");
SessionManagerLayer::new(store)
.with_secure(true)
.with_expiry(Expiry::OnInactivity(SESSION_TTL.into()))
}
pub async fn auth_layer(
pool: SqlitePool,
secret: &[u8],
) -> AuthManagerLayer<SqliteStore, SessionManagerLayer<SqliteStore>> {
todo!()
}
//-************************************************************************ //-************************************************************************
// Tests for `db` module. // Tests for `db` module.
//-************************************************************************ //-************************************************************************

View file

@ -1,21 +1,19 @@
use axum::response::{IntoResponse, Redirect}; use axum::response::{IntoResponse, Redirect};
use crate::{AuthContext, MainPage}; use crate::{AuthSession, MainPage};
pub async fn handle_slash_redir() -> impl IntoResponse { pub async fn handle_slash_redir() -> impl IntoResponse {
Redirect::to("/") Redirect::to("/")
} }
pub async fn handle_slash(auth: AuthContext) -> impl IntoResponse { pub async fn handle_slash(auth: AuthSession) -> impl IntoResponse {
if let Some(ref user) = auth.current_user { if let Some(ref user) = auth.user {
let name = &user.username; let name = &user.username;
tracing::debug!("Logged in as: {name}"); tracing::debug!("Logged in as: {name}");
} else { } else {
tracing::debug!("Not logged in."); tracing::debug!("Not logged in.");
} }
MainPage { MainPage { user: auth.user }
user: auth.current_user,
}
} }
#[cfg(test)] #[cfg(test)]

View file

@ -1,4 +1,4 @@
use axum::routing::IntoMakeService; use axum::{error_handling::HandleErrorLayer, routing::IntoMakeService, BoxError};
use sqlx::SqlitePool; use sqlx::SqlitePool;
#[macro_use] #[macro_use]
extern crate justerror; extern crate justerror;
@ -10,12 +10,14 @@ pub mod test_utils;
/// app /// app
pub use db::get_db_pool; pub use db::get_db_pool;
pub mod import_utils; pub mod import_utils;
pub use users::User; pub use users::User;
pub use watches::{ShowKind, Watch, WatchQuest}; pub use watches::{ShowKind, Watch, WatchQuest};
pub type WWRouter = axum::Router<SqlitePool>; pub type WWRouter = axum::Router<SqlitePool>;
// everything else is private to the crate // everything else is private to the crate
mod auth;
mod db; mod db;
mod generic_handlers; mod generic_handlers;
mod login; mod login;
@ -26,17 +28,16 @@ mod util;
mod watches; mod watches;
// things we want in the crate namespace // things we want in the crate namespace
use auth::AuthSession;
use optional_optional_user::OptionalOptionalUser; use optional_optional_user::OptionalOptionalUser;
use templates::*; use templates::*;
use watches::templates::*; use watches::templates::*;
type AuthContext =
axum_login::extractors::AuthContext<julid::Julid, User, axum_login::SqliteStore<User>>;
/// Returns the router to be used as a service or test object, you do you. /// Returns the router to be used as a service or test object, you do you.
pub async fn app(db_pool: sqlx::SqlitePool, secret: &[u8]) -> IntoMakeService<axum::Router> { pub async fn app(db_pool: sqlx::SqlitePool) -> IntoMakeService<axum::Router> {
use axum::{middleware, routing::get};
// don't bother bringing handlers into the whole crate namespace // don't bother bringing handlers into the whole crate namespace
use auth::*;
use axum::{middleware, routing::get};
use generic_handlers::{handle_slash, handle_slash_redir}; use generic_handlers::{handle_slash, handle_slash_redir};
use login::{get_login, get_logout, post_login, post_logout}; use login::{get_login, get_logout, post_login, post_logout};
use signup::{get_create_user, get_signup_success, post_create_user}; use signup::{get_create_user, get_signup_success, post_create_user};
@ -46,23 +47,25 @@ pub async fn app(db_pool: sqlx::SqlitePool, secret: &[u8]) -> IntoMakeService<ax
post_add_watch_quest, post_add_watch_quest,
}; };
let (session_layer, auth_layer) = { let auth_layer = {
let session_layer = db::session_layer(db_pool.clone(), secret).await; let sessions = session_layer(db_pool.clone()).await;
let auth_layer = db::auth_layer(db_pool.clone(), secret).await; let store = AuthStore::new(db_pool.clone());
(session_layer, auth_layer) tower::ServiceBuilder::new()
.layer(HandleErrorLayer::new(|_: BoxError| async {
http::StatusCode::BAD_REQUEST
}))
.layer(axum_login::AuthManagerLayerBuilder::new(store, sessions).build())
}; };
let css_dir = std::env::current_dir() let css_dir = std::env::current_dir()
.unwrap() .unwrap()
.join("templates") .join("templates")
.join("css"); .join("css");
let css_svc = ServeDir::new(css_dir.as_path());
axum::Router::new() axum::Router::new()
.route("/", get(handle_slash).post(handle_slash)) .route("/", get(handle_slash).post(handle_slash))
.nest_service( .nest_service("/css", css_svc)
"/css",
ServeDir::new(css_dir.as_path()).append_index_html_on_directories(false),
)
.route("/signup", get(get_create_user).post(post_create_user)) .route("/signup", get(get_create_user).post(post_create_user))
.route("/signup_success/:id", get(get_signup_success)) .route("/signup_success/:id", get(get_signup_success))
.route("/login", get(get_login).post(post_login)) .route("/login", get(get_login).post(post_login))
@ -82,7 +85,6 @@ pub async fn app(db_pool: sqlx::SqlitePool, secret: &[u8]) -> IntoMakeService<ax
users::handle_update_last_seen, users::handle_update_last_seen,
)) ))
.layer(auth_layer) .layer(auth_layer)
.layer(session_layer)
.with_state(db_pool) .with_state(db_pool)
.into_make_service() .into_make_service()
} }

View file

@ -11,7 +11,7 @@ use axum::{
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::SqlitePool; use sqlx::SqlitePool;
use crate::{AuthContext, LoginPage, LogoutPage, LogoutSuccessPage, User}; use crate::{AuthSession, LoginPage, LogoutPage, LogoutSuccessPage, User};
//-************************************************************************ //-************************************************************************
// Constants // Constants
@ -41,6 +41,7 @@ impl IntoResponse for LoginError {
) )
.into_response(), .into_response(),
LoginErrorKind::Unknown => (StatusCode::OK, "Not successful.").into_response(), LoginErrorKind::Unknown => (StatusCode::OK, "Not successful.").into_response(),
// we don't say it's a bad password, we just silently fail
_ => (StatusCode::OK, format!("{self}")).into_response(), _ => (StatusCode::OK, format!("{self}")).into_response(),
} }
} }
@ -60,7 +61,7 @@ pub struct LoginPostForm {
/// Handle login queries /// Handle login queries
#[axum::debug_handler] #[axum::debug_handler]
pub async fn post_login( pub async fn post_login(
mut auth: AuthContext, mut auth: AuthSession,
State(pool): State<SqlitePool>, State(pool): State<SqlitePool>,
Form(login): Form<LoginPostForm>, Form(login): Form<LoginPostForm>,
) -> Result<impl IntoResponse, LoginError> { ) -> Result<impl IntoResponse, LoginError> {
@ -98,11 +99,15 @@ pub async fn get_logout() -> impl IntoResponse {
LogoutPage LogoutPage
} }
pub async fn post_logout(mut auth: AuthContext) -> impl IntoResponse { pub async fn post_logout(mut auth: AuthSession) -> impl IntoResponse {
if auth.current_user.is_some() { match auth.logout() {
auth.logout().await; Ok(_) => LogoutSuccessPage.into_response(),
Err(e) => {
tracing::debug!("{e}");
let e: LoginError = LoginErrorKind::Internal.into();
e.into_response()
}
} }
LogoutSuccessPage
} }
//-************************************************************************ //-************************************************************************
@ -131,7 +136,7 @@ mod test {
rt.block_on(async { rt.block_on(async {
let s = server_with_pool(&db).await; let s = server_with_pool(&db).await;
let resp = s.get("/login").await; let resp = s.get("/login").await;
let body = std::str::from_utf8(resp.bytes()).unwrap().to_string(); let body = std::str::from_utf8(resp.as_bytes()).unwrap().to_string();
assert_eq!(body, LoginPage::default().to_string()); assert_eq!(body, LoginPage::default().to_string());
}) })
} }
@ -215,7 +220,7 @@ mod test {
rt.block_on(async { rt.block_on(async {
let s = server_with_pool(&db).await; let s = server_with_pool(&db).await;
let resp = s.get("/logout").await; let resp = s.get("/logout").await;
let body = std::str::from_utf8(resp.bytes()).unwrap().to_string(); let body = std::str::from_utf8(resp.as_bytes()).unwrap().to_string();
assert_eq!(body, LogoutPage.to_string()); assert_eq!(body, LogoutPage.to_string());
}) })
} }
@ -232,7 +237,7 @@ mod test {
let s = server_with_pool(&db).await; let s = server_with_pool(&db).await;
let resp = s.post("/logout").await; let resp = s.post("/logout").await;
resp.assert_status_ok(); resp.assert_status_ok();
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
let default = LogoutSuccessPage.to_string(); let default = LogoutSuccessPage.to_string();
assert_eq!(body, &default); assert_eq!(body, &default);
}) })
@ -263,11 +268,11 @@ mod test {
let logged_in = MainPage { user: Some(user) }.to_string(); let logged_in = MainPage { user: Some(user) }.to_string();
let main_page = s.get("/").await; let main_page = s.get("/").await;
let body = std::str::from_utf8(main_page.bytes()).unwrap(); let body = std::str::from_utf8(main_page.as_bytes()).unwrap();
assert_eq!(&logged_in, body); assert_eq!(&logged_in, body);
let resp = s.post("/logout").await; let resp = s.post("/logout").await;
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
let default = LogoutSuccessPage.to_string(); let default = LogoutSuccessPage.to_string();
assert_eq!(body, &default); assert_eq!(body, &default);
}) })

View file

@ -1,6 +1,5 @@
use std::net::SocketAddr; use std::net::SocketAddr;
use rand::{thread_rng, RngCore};
use tokio::signal; use tokio::signal;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
use what2watch::get_db_pool; use what2watch::get_db_pool;
@ -21,24 +20,16 @@ fn main() {
.build() .build()
.unwrap(); .unwrap();
let secret = { let app = rt.block_on(what2watch::app(pool.clone()));
let mut bytes = [0u8; 64];
let mut rng = thread_rng();
rng.fill_bytes(&mut bytes);
bytes
};
let app = rt.block_on(what2watch::app(pool.clone(), &secret));
rt.block_on(async { rt.block_on(async {
let addr: SocketAddr = ([0, 0, 0, 0], 3000).into(); let addr: SocketAddr = ([0, 0, 0, 0], 3000).into();
tracing::debug!("binding to {addr:?}"); tracing::debug!("binding to {addr:?}");
axum::Server::bind(&addr) let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
.serve(app) axum::serve(listener, app).await.unwrap();
.with_graceful_shutdown(shutdown_signal()) //.with_graceful_shutdown(shutdown_signal()) // removed in 0.7 because of upstream dep changes
.await
.unwrap_or_default();
}); });
rt.block_on(pool.close()); rt.block_on(pool.close());

View file

@ -235,7 +235,7 @@ mod test {
let server = server_with_pool(&pool).await; let server = server_with_pool(&pool).await;
let resp = server.get("/signup").await; let resp = server.get("/signup").await;
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
let expected = SignupPage::default().to_string(); let expected = SignupPage::default().to_string();
assert_eq!(&expected, body); assert_eq!(&expected, body);
}); });
@ -265,7 +265,7 @@ mod test {
let path = format!("/signup_success/{id}"); let path = format!("/signup_success/{id}");
let resp = server.get(&path).expect_success().await; let resp = server.get(&path).expect_success().await;
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
let expected = SignupSuccessPage(user).to_string(); let expected = SignupSuccessPage(user).to_string();
assert_eq!(&expected, body); assert_eq!(&expected, body);
}); });
@ -310,7 +310,7 @@ mod test {
let user = User::try_get("bad_user", &pool).await; let user = User::try_get("bad_user", &pool).await;
assert!(user.is_err()); assert!(user.is_err());
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
let expected = CreateUserError(CreateUserErrorKind::PasswordMismatch).to_string(); let expected = CreateUserError(CreateUserErrorKind::PasswordMismatch).to_string();
assert_eq!(&expected, body); assert_eq!(&expected, body);
}); });
@ -336,7 +336,7 @@ mod test {
let user = User::try_get("bad_user", &pool).await; let user = User::try_get("bad_user", &pool).await;
assert!(user.is_err()); assert!(user.is_err());
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
let expected = CreateUserError(CreateUserErrorKind::BadPassword).to_string(); let expected = CreateUserError(CreateUserErrorKind::BadPassword).to_string();
assert_eq!(&expected, body); assert_eq!(&expected, body);
}); });
@ -362,7 +362,7 @@ mod test {
let user = User::try_get("bad_user", &pool).await; let user = User::try_get("bad_user", &pool).await;
assert!(user.is_err()); assert!(user.is_err());
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
let expected = CreateUserError(CreateUserErrorKind::BadPassword).to_string(); let expected = CreateUserError(CreateUserErrorKind::BadPassword).to_string();
assert_eq!(&expected, body); assert_eq!(&expected, body);
}); });
@ -396,7 +396,7 @@ mod test {
let user = User::try_get("bad_user", &pool).await; let user = User::try_get("bad_user", &pool).await;
assert!(user.is_err()); assert!(user.is_err());
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
let expected = CreateUserError(CreateUserErrorKind::BadPassword).to_string(); let expected = CreateUserError(CreateUserErrorKind::BadPassword).to_string();
assert_eq!(&expected, body); assert_eq!(&expected, body);
}); });
@ -422,7 +422,7 @@ mod test {
let user = User::try_get("bad_user", &pool).await; let user = User::try_get("bad_user", &pool).await;
assert!(user.is_err()); assert!(user.is_err());
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
let expected = CreateUserError(CreateUserErrorKind::BadUsername).to_string(); let expected = CreateUserError(CreateUserErrorKind::BadUsername).to_string();
assert_eq!(&expected, body); assert_eq!(&expected, body);
}); });
@ -448,7 +448,7 @@ mod test {
let user = User::try_get("bad_user", &pool).await; let user = User::try_get("bad_user", &pool).await;
assert!(user.is_err()); assert!(user.is_err());
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
let expected = CreateUserError(CreateUserErrorKind::BadUsername).to_string(); let expected = CreateUserError(CreateUserErrorKind::BadUsername).to_string();
assert_eq!(&expected, body); assert_eq!(&expected, body);
}); });
@ -483,7 +483,7 @@ mod test {
assert_eq!(resp.status_code(), StatusCode::OK); assert_eq!(resp.status_code(), StatusCode::OK);
let expected = CreateUserError(CreateUserErrorKind::AlreadyExists).to_string(); let expected = CreateUserError(CreateUserErrorKind::AlreadyExists).to_string();
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
assert_eq!(&expected, body); assert_eq!(&expected, body);
}); });
} }
@ -508,7 +508,7 @@ mod test {
let user = User::try_get("bad_user", &pool).await; let user = User::try_get("bad_user", &pool).await;
assert!(user.is_err()); assert!(user.is_err());
let body = std::str::from_utf8(resp.bytes()).unwrap(); let body = std::str::from_utf8(resp.as_bytes()).unwrap();
let expected = CreateUserError(CreateUserErrorKind::BadDisplayname).to_string(); let expected = CreateUserError(CreateUserErrorKind::BadDisplayname).to_string();
assert_eq!(&expected, body); assert_eq!(&expected, body);
}); });

View file

@ -8,8 +8,6 @@ use crate::User;
pub const FORM_CONTENT_TYPE: &str = "application/x-www-form-urlencoded"; pub const FORM_CONTENT_TYPE: &str = "application/x-www-form-urlencoded";
pub async fn server_with_pool(pool: &SqlitePool) -> TestServer { pub async fn server_with_pool(pool: &SqlitePool) -> TestServer {
let secret = [0u8; 64];
let user = get_test_user(); let user = get_test_user();
insert_user_with_id(&user, pool).await; insert_user_with_id(&user, pool).await;
@ -19,7 +17,7 @@ pub async fn server_with_pool(pool: &SqlitePool) -> TestServer {
.unwrap_or_default(); .unwrap_or_default();
assert!(r == 1); assert!(r == 1);
let app = crate::app(pool.clone(), &secret).await; let app = crate::app(pool.clone()).await;
let config = TestServerConfig { let config = TestServerConfig {
save_cookies: true, save_cookies: true,

View file

@ -13,7 +13,7 @@ use julid::Julid;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::SqlitePool; use sqlx::SqlitePool;
use crate::AuthContext; use crate::auth::AuthSession;
const USERNAME_QUERY: &str = "select * from users where username = $1"; const USERNAME_QUERY: &str = "select * from users where username = $1";
const LAST_SEEN_QUERY: &str = "update users set last_seen = (select unixepoch()) where id = $1"; const LAST_SEEN_QUERY: &str = "update users set last_seen = (select unixepoch()) where id = $1";
@ -94,11 +94,11 @@ impl User {
pub async fn handle_update_last_seen( pub async fn handle_update_last_seen(
State(pool): State<SqlitePool>, State(pool): State<SqlitePool>,
auth: AuthContext, auth: AuthSession,
request: Request, request: Request,
next: Next, next: Next,
) -> impl IntoResponse { ) -> impl IntoResponse {
if let Some(user) = auth.current_user { if let Some(user) = auth.user {
if let Some(then) = user.last_seen { if let Some(then) = user.last_seen {
let now = SystemTime::now() let now = SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)

View file

@ -10,7 +10,7 @@ use sqlx::{query, query_as, query_scalar, SqlitePool};
use super::templates::{AddNewWatchPage, GetWatchPage, SearchWatchesPage}; use super::templates::{AddNewWatchPage, GetWatchPage, SearchWatchesPage};
use crate::{ use crate::{
util::{empty_string_as_none, year_to_epoch}, util::{empty_string_as_none, year_to_epoch},
AuthContext, MyWatchesPage, ShowKind, Watch, WatchQuest, AuthSession, MyWatchesPage, ShowKind, Watch, WatchQuest,
}; };
//-************************************************************************ //-************************************************************************
@ -104,10 +104,8 @@ pub struct PostAddExistingWatch {
// handlers // handlers
//-************************************************************************ //-************************************************************************
pub async fn get_add_new_watch(auth: AuthContext) -> impl IntoResponse { pub async fn get_add_new_watch(auth: AuthSession) -> impl IntoResponse {
AddNewWatchPage { AddNewWatchPage { user: auth.user }
user: auth.current_user,
}
} }
struct QuestQuest { struct QuestQuest {
@ -118,11 +116,11 @@ struct QuestQuest {
/// Add a Watch to your watchlist (side effects system-add) /// Add a Watch to your watchlist (side effects system-add)
pub async fn post_add_new_watch( pub async fn post_add_new_watch(
auth: AuthContext, auth: AuthSession,
State(pool): State<SqlitePool>, State(pool): State<SqlitePool>,
Form(form): Form<PostAddNewWatch>, Form(form): Form<PostAddNewWatch>,
) -> Result<impl IntoResponse, WatchAddError> { ) -> Result<impl IntoResponse, WatchAddError> {
if let Some(user) = auth.current_user { if let Some(user) = auth.user {
{ {
let release_date = year_to_epoch(form.year.as_deref()); let release_date = year_to_epoch(form.year.as_deref());
let watch = Watch { let watch = Watch {
@ -195,7 +193,7 @@ async fn add_new_watch_impl(
/// Add a Watch to your watchlist by selecting it with a checkbox /// Add a Watch to your watchlist by selecting it with a checkbox
pub async fn post_add_watch_quest( pub async fn post_add_watch_quest(
_auth: AuthContext, _auth: AuthSession,
State(_pool): State<SqlitePool>, State(_pool): State<SqlitePool>,
Form(_form): Form<PostAddExistingWatch>, Form(_form): Form<PostAddExistingWatch>,
) -> impl IntoResponse { ) -> impl IntoResponse {
@ -218,7 +216,7 @@ pub async fn _add_watch_quest_impl(pool: &SqlitePool, quest: &WatchQuest) -> Res
/// A single Watch /// A single Watch
pub async fn get_watch( pub async fn get_watch(
auth: AuthContext, auth: AuthSession,
watch: Option<Path<String>>, watch: Option<Path<String>>,
State(pool): State<SqlitePool>, State(pool): State<SqlitePool>,
) -> impl IntoResponse { ) -> impl IntoResponse {
@ -234,13 +232,13 @@ pub async fn get_watch(
GetWatchPage { GetWatchPage {
watch, watch,
user: auth.current_user, user: auth.user,
} }
} }
/// everything the user has saved /// everything the user has saved
pub async fn get_watches(auth: AuthContext, State(pool): State<SqlitePool>) -> impl IntoResponse { pub async fn get_watches(auth: AuthSession, State(pool): State<SqlitePool>) -> impl IntoResponse {
let user = auth.current_user; let user = auth.user;
let watches: Vec<Watch> = if (user).is_some() { let watches: Vec<Watch> = if (user).is_some() {
query_as(GET_SAVED_WATCHES_QUERY) query_as(GET_SAVED_WATCHES_QUERY)
.bind(user.as_ref().unwrap().id) .bind(user.as_ref().unwrap().id)
@ -255,11 +253,11 @@ pub async fn get_watches(auth: AuthContext, State(pool): State<SqlitePool>) -> i
} }
pub async fn get_search_watch( pub async fn get_search_watch(
auth: AuthContext, auth: AuthSession,
State(pool): State<SqlitePool>, State(pool): State<SqlitePool>,
search: Query<SearchQuery>, search: Query<SearchQuery>,
) -> impl IntoResponse { ) -> impl IntoResponse {
let user = auth.current_user; let user = auth.user;
let (search_string, qstring) = if search.0 != EMPTY_SEARCH_QUERY_STRUCT { let (search_string, qstring) = if search.0 != EMPTY_SEARCH_QUERY_STRUCT {
let s = search.0; let s = search.0;