i broke everything oh no
This commit is contained in:
parent
26de7b3cc4
commit
2843aec125
8 changed files with 170 additions and 216 deletions
248
Cargo.lock
generated
248
Cargo.lock
generated
|
@ -141,9 +141,11 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum-core",
|
"axum-core",
|
||||||
|
"axum-macros",
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"headers",
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
@ -184,6 +186,18 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum-macros"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.38",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.69"
|
version = "0.3.69"
|
||||||
|
@ -293,28 +307,6 @@ dependencies = [
|
||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chrono-tz"
|
|
||||||
version = "0.8.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f1369bc6b9e9a7dfdae2055f6ec151fe9c554a9d23d357c0237cee2e25eaabb7"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
"chrono-tz-build",
|
|
||||||
"phf",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chrono-tz-build"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e2f5ebdc942f57ed96d560a6d1a459bae5851102a25d5bf89dc04ae453e31ecf"
|
|
||||||
dependencies = [
|
|
||||||
"parse-zoneinfo",
|
|
||||||
"phf",
|
|
||||||
"phf_codegen",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.4.6"
|
version = "4.4.6"
|
||||||
|
@ -437,21 +429,6 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "deunicode"
|
|
||||||
version = "0.4.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "71dbf1bf89c23e9cd1baf5e654f622872655f195b36588dc9dc38f7eda30758c"
|
|
||||||
dependencies = [
|
|
||||||
"deunicode 1.4.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "deunicode"
|
|
||||||
version = "1.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6a1abaf4d861455be59f64fd2b55606cb151fce304ede7165f410243ce96bde6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.7"
|
version = "0.10.7"
|
||||||
|
@ -672,17 +649,6 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "globwalk"
|
|
||||||
version = "0.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 1.3.2",
|
|
||||||
"ignore",
|
|
||||||
"walkdir",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "handlebars"
|
name = "handlebars"
|
||||||
version = "4.4.0"
|
version = "4.4.0"
|
||||||
|
@ -718,6 +684,30 @@ dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "headers"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"bytes",
|
||||||
|
"headers-core",
|
||||||
|
"http",
|
||||||
|
"httpdate",
|
||||||
|
"mime",
|
||||||
|
"sha1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "headers-core"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
|
||||||
|
dependencies = [
|
||||||
|
"http",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
@ -806,15 +796,6 @@ version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "humansize"
|
|
||||||
version = "2.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
|
|
||||||
dependencies = [
|
|
||||||
"libm",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "0.14.27"
|
version = "0.14.27"
|
||||||
|
@ -871,23 +852,6 @@ dependencies = [
|
||||||
"unicode-normalization",
|
"unicode-normalization",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ignore"
|
|
||||||
version = "0.4.20"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492"
|
|
||||||
dependencies = [
|
|
||||||
"globset",
|
|
||||||
"lazy_static",
|
|
||||||
"log",
|
|
||||||
"memchr",
|
|
||||||
"regex",
|
|
||||||
"same-file",
|
|
||||||
"thread_local",
|
|
||||||
"walkdir",
|
|
||||||
"winapi-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "imgboard"
|
name = "imgboard"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -898,10 +862,10 @@ dependencies = [
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"eyre",
|
"eyre",
|
||||||
"handlebars",
|
"handlebars",
|
||||||
|
"headers",
|
||||||
"rust-embed",
|
"rust-embed",
|
||||||
"serde",
|
"serde",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"tera",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -1178,15 +1142,6 @@ dependencies = [
|
||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parse-zoneinfo"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41"
|
|
||||||
dependencies = [
|
|
||||||
"regex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
|
@ -1253,44 +1208,6 @@ dependencies = [
|
||||||
"sha2",
|
"sha2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf"
|
|
||||||
version = "0.11.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
|
||||||
dependencies = [
|
|
||||||
"phf_shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_codegen"
|
|
||||||
version = "0.11.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
|
|
||||||
dependencies = [
|
|
||||||
"phf_generator",
|
|
||||||
"phf_shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_generator"
|
|
||||||
version = "0.11.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
|
||||||
dependencies = [
|
|
||||||
"phf_shared",
|
|
||||||
"rand",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_shared"
|
|
||||||
version = "0.11.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
|
|
||||||
dependencies = [
|
|
||||||
"siphasher",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
|
@ -1703,12 +1620,6 @@ dependencies = [
|
||||||
"rand_core",
|
"rand_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "siphasher"
|
|
||||||
version = "0.3.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -1718,15 +1629,6 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "slug"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373"
|
|
||||||
dependencies = [
|
|
||||||
"deunicode 0.4.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
|
@ -2055,28 +1957,6 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tera"
|
|
||||||
version = "1.19.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8"
|
|
||||||
dependencies = [
|
|
||||||
"chrono",
|
|
||||||
"chrono-tz",
|
|
||||||
"globwalk",
|
|
||||||
"humansize",
|
|
||||||
"lazy_static",
|
|
||||||
"percent-encoding",
|
|
||||||
"pest",
|
|
||||||
"pest_derive",
|
|
||||||
"rand",
|
|
||||||
"regex",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"slug",
|
|
||||||
"unic-segment",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.49"
|
version = "1.0.49"
|
||||||
|
@ -2284,56 +2164,6 @@ version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
|
checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unic-char-property"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
|
|
||||||
dependencies = [
|
|
||||||
"unic-char-range",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unic-char-range"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unic-common"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unic-segment"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23"
|
|
||||||
dependencies = [
|
|
||||||
"unic-ucd-segment",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unic-ucd-segment"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700"
|
|
||||||
dependencies = [
|
|
||||||
"unic-char-property",
|
|
||||||
"unic-char-range",
|
|
||||||
"unic-ucd-version",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unic-ucd-version"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
|
|
||||||
dependencies = [
|
|
||||||
"unic-common",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.13"
|
version = "0.3.13"
|
||||||
|
|
|
@ -6,16 +6,16 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = { version = "0.6.20", features = ["tracing"] }
|
axum = { version = "0.6.20", features = ["tracing", "macros", "headers"] }
|
||||||
chrono = { version = "0.4.31", features = ["serde"] }
|
chrono = { version = "0.4.31", features = ["serde"] }
|
||||||
clap = { version = "4.4.6", features = ["derive", "env"] }
|
clap = { version = "4.4.6", features = ["derive", "env"] }
|
||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
eyre = "0.6.8"
|
eyre = "0.6.8"
|
||||||
handlebars = { version = "4.4.0", features = ["rust-embed", "dir_source"] }
|
handlebars = { version = "4.4.0", features = ["rust-embed", "dir_source"] }
|
||||||
|
headers = "0.3.9"
|
||||||
rust-embed = "8.0.0"
|
rust-embed = "8.0.0"
|
||||||
serde = { version = "1.0.189", features = ["derive"] }
|
serde = { version = "1.0.189", features = ["derive"] }
|
||||||
sqlx = { version = "0.7.2", features = ["runtime-tokio", "tls-rustls", "postgres", "macros", "migrate", "chrono"] }
|
sqlx = { version = "0.7.2", features = ["runtime-tokio", "tls-rustls", "postgres", "macros", "migrate", "chrono"] }
|
||||||
tera = "1.19.1"
|
|
||||||
tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread"] }
|
||||||
tower-http = { version = "0.4.4", features = ["trace"] }
|
tower-http = { version = "0.4.4", features = ["trace"] }
|
||||||
tracing = "0.1.39"
|
tracing = "0.1.39"
|
||||||
|
|
49
src/extractor.rs
Normal file
49
src/extractor.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use axum::{
|
||||||
|
async_trait,
|
||||||
|
extract::{FromRef, FromRequestParts},
|
||||||
|
http::{request::Parts, StatusCode},
|
||||||
|
RequestPartsExt, TypedHeader,
|
||||||
|
};
|
||||||
|
use headers::Cookie;
|
||||||
|
use tracing::error;
|
||||||
|
|
||||||
|
use crate::{model::user::User, state::AppState};
|
||||||
|
|
||||||
|
pub struct ExtractUserToken(pub Option<User>);
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<S> FromRequestParts<S> for ExtractUserToken
|
||||||
|
where
|
||||||
|
AppState: FromRef<S>,
|
||||||
|
S: Send + Sync,
|
||||||
|
{
|
||||||
|
type Rejection = (StatusCode, &'static str);
|
||||||
|
|
||||||
|
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
|
||||||
|
let state = match parts.extract_with_state::<AppState, _>(state).await {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(why) => {
|
||||||
|
error!("Getting state: {}", why);
|
||||||
|
return Err((StatusCode::INTERNAL_SERVER_ERROR, "Internal server error"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let cookie = match parts.extract::<TypedHeader<Cookie>>().await {
|
||||||
|
Ok(cookie) => cookie,
|
||||||
|
Err(err) => {
|
||||||
|
error!("Getting cookie header: {}", err);
|
||||||
|
return Ok(ExtractUserToken(None));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let user = match cookie.get("imgboard-token") {
|
||||||
|
Some(_token) => {
|
||||||
|
// TODO: get from token
|
||||||
|
None
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(ExtractUserToken(user))
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod extractor;
|
||||||
pub mod model;
|
pub mod model;
|
||||||
pub mod pages;
|
pub mod pages;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
|
@ -20,7 +21,7 @@ use crate::state::AppState;
|
||||||
use crate::templates::handlebars;
|
use crate::templates::handlebars;
|
||||||
|
|
||||||
use crate::pages::index::index;
|
use crate::pages::index::index;
|
||||||
use crate::pages::user::get_user;
|
use crate::pages::user::{get_user, get_user_new};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
|
@ -53,6 +54,7 @@ async fn main() -> Result<()> {
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(index))
|
.route("/", get(index))
|
||||||
.route("/users/:id", get(get_user))
|
.route("/users/:id", get(get_user))
|
||||||
|
.route("/users/new", get(get_user_new))
|
||||||
.layer(TraceLayer::new_for_http())
|
.layer(TraceLayer::new_for_http())
|
||||||
.with_state(state);
|
.with_state(state);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Serialize for Role {
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
serializer.serialize_str(match self {
|
serializer.serialize_str(match self {
|
||||||
Role::Viewer => "viwer",
|
Role::Viewer => "viewer",
|
||||||
Role::Editor => "editor",
|
Role::Editor => "editor",
|
||||||
Role::Manager => "manager",
|
Role::Manager => "manager",
|
||||||
Role::Admin => "admin",
|
Role::Admin => "admin",
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
use std::sync::Arc;
|
use std::{collections::BTreeMap, sync::Arc};
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
};
|
};
|
||||||
use sqlx::query_as;
|
use sqlx::{query, query_as};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
model::user::User,
|
extractor::ExtractUserToken,
|
||||||
|
model::user::{Role, User},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
templates::{Page, PageData},
|
templates::{Page, PageData},
|
||||||
};
|
};
|
||||||
|
@ -38,3 +39,50 @@ pub async fn get_user(
|
||||||
.render("error.hbs", &PageData { user: Some(user) }),
|
.render("error.hbs", &PageData { user: Some(user) }),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_user_new(
|
||||||
|
State(state): State<Arc<AppState>>,
|
||||||
|
ExtractUserToken(user): ExtractUserToken,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
if user.is_some()
|
||||||
|
&& match user.as_ref().unwrap().role {
|
||||||
|
Role::Viewer => false,
|
||||||
|
Role::Editor => false,
|
||||||
|
Role::Manager => false,
|
||||||
|
Role::Admin => true,
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Admins can create accounts
|
||||||
|
// Handlebars expects *some* value when rendering a template, so just pass an empty BTreeMap
|
||||||
|
let map = BTreeMap::<&str, &str>::new();
|
||||||
|
return Page::new(state.hbs.render("new_user.hbs", &map));
|
||||||
|
} else if user.is_some() {
|
||||||
|
// No permissions to create account
|
||||||
|
return Page::new(
|
||||||
|
state
|
||||||
|
.hbs
|
||||||
|
.render::<PageData>("error.hbs", &Default::default()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Else, let the user create a new account if no accounts exist yet
|
||||||
|
|
||||||
|
let count = match query!(r#"SELECT COUNT(id) FROM users"#)
|
||||||
|
.fetch_one(&state.pool)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(r) => r.count.unwrap_or(0),
|
||||||
|
Err(why) => {
|
||||||
|
error!("Getting user count: {}", why);
|
||||||
|
return Page::new(
|
||||||
|
state
|
||||||
|
.hbs
|
||||||
|
.render::<PageData>("error.hbs", &Default::default()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut map = BTreeMap::new();
|
||||||
|
map.insert("count", count);
|
||||||
|
|
||||||
|
Page::new(state.hbs.render("new_user.hbs", &map))
|
||||||
|
}
|
||||||
|
|
15
src/state.rs
15
src/state.rs
|
@ -1,6 +1,21 @@
|
||||||
|
use axum::{extract::{FromRef, FromRequestParts}, async_trait, http::request::Parts};
|
||||||
use sqlx::{postgres::Postgres, Pool};
|
use sqlx::{postgres::Postgres, Pool};
|
||||||
|
|
||||||
|
#[derive(Clone, FromRef)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub pool: Pool<Postgres>,
|
pub pool: Pool<Postgres>,
|
||||||
pub hbs: handlebars::Handlebars<'static>,
|
pub hbs: handlebars::Handlebars<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<S> FromRequestParts<S> for AppState
|
||||||
|
where
|
||||||
|
Self: FromRef<S>,
|
||||||
|
S: Send + Sync,
|
||||||
|
{
|
||||||
|
type Rejection = &'static str;
|
||||||
|
|
||||||
|
async fn from_request_parts(_parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
|
||||||
|
Ok(Self::from_ref(state))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
10
templates/new_user.hbs
Normal file
10
templates/new_user.hbs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{{#*inline "page"}}
|
||||||
|
<h1>New user</h1>
|
||||||
|
<form method="POST">
|
||||||
|
<label>Username <input type="text" name="username" /></label>
|
||||||
|
<label>Password <input type="password" name="password" /></label>
|
||||||
|
<label>Confirm password <input type="password" name="password2" /></label>
|
||||||
|
<input type="submit" value="Create account" />
|
||||||
|
</form>
|
||||||
|
{{/inline}}
|
||||||
|
{{> root.hbs}}
|
Loading…
Reference in a new issue