use axum-oidc

This commit is contained in:
Paul Zinselmeyer 2023-11-03 19:48:48 +01:00
parent 70b0da40dc
commit ee2c7355f6
Signed by: pfzetto
GPG key ID: 4EEF46A5B276E648
3 changed files with 152 additions and 250 deletions

304
Cargo.lock generated
View file

@ -17,41 +17,6 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aead"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
dependencies = [
"crypto-common",
"generic-array",
]
[[package]]
name = "aes"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]]
name = "aes-gcm"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
dependencies = [
"aead",
"aes",
"cipher",
"ctr",
"ghash",
"subtle",
]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "1.1.2" version = "1.1.2"
@ -82,7 +47,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"axum", "axum",
"axum-htmx", "axum-htmx",
"axum_oidc", "axum-oidc",
"dotenvy", "dotenvy",
"env_logger", "env_logger",
"futures-util", "futures-util",
@ -95,7 +60,9 @@ dependencies = [
"tokio", "tokio",
"tokio-util", "tokio-util",
"toml", "toml",
"tower",
"tower-http", "tower-http",
"tower-sessions",
] ]
[[package]] [[package]]
@ -165,28 +132,6 @@ dependencies = [
"tower-service", "tower-service",
] ]
[[package]]
name = "axum-extra"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a93e433be9382c737320af3924f7d5fc6f89c155cf2bf88949d8f5126fab283f"
dependencies = [
"axum",
"axum-core",
"bytes",
"cookie",
"futures-util",
"http",
"http-body",
"mime",
"pin-project-lite",
"serde",
"tokio",
"tower",
"tower-layer",
"tower-service",
]
[[package]] [[package]]
name = "axum-htmx" name = "axum-htmx"
version = "0.4.0" version = "0.4.0"
@ -197,19 +142,21 @@ dependencies = [
] ]
[[package]] [[package]]
name = "axum_oidc" name = "axum-oidc"
version = "0.1.0" version = "0.0.0"
source = "git+https://git2.zettoit.eu/pfz4/axum_oidc#3b9438d1f3cf58c1edb9f503aea4e6d7783194d2"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum", "axum",
"axum-extra", "axum-core",
"jsonwebtoken", "futures-util",
"http",
"openidconnect", "openidconnect",
"reqwest", "reqwest",
"serde", "serde",
"serde_json",
"thiserror", "thiserror",
"tower-layer",
"tower-service",
"tower-sessions",
] ]
[[package]] [[package]]
@ -332,16 +279,6 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "cipher"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"inout",
]
[[package]] [[package]]
name = "color_quant" name = "color_quant"
version = "1.1.0" version = "1.1.0"
@ -360,11 +297,7 @@ version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24"
dependencies = [ dependencies = [
"aes-gcm",
"base64 0.21.5",
"percent-encoding", "percent-encoding",
"rand",
"subtle",
"time", "time",
"version_check", "version_check",
] ]
@ -413,19 +346,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [ dependencies = [
"generic-array", "generic-array",
"rand_core",
"typenum", "typenum",
] ]
[[package]]
name = "ctr"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
dependencies = [
"cipher",
]
[[package]] [[package]]
name = "curve25519-dalek" name = "curve25519-dalek"
version = "4.1.1" version = "4.1.1"
@ -489,6 +412,19 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "dashmap"
version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
dependencies = [
"cfg-if",
"hashbrown 0.14.2",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]] [[package]]
name = "der" name = "der"
version = "0.7.8" version = "0.7.8"
@ -679,6 +615,20 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "futures"
version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.29" version = "0.3.29"
@ -686,6 +636,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink",
] ]
[[package]] [[package]]
@ -732,6 +683,7 @@ dependencies = [
"futures-core", "futures-core",
"futures-io", "futures-io",
"futures-macro", "futures-macro",
"futures-sink",
"futures-task", "futures-task",
"memchr", "memchr",
"pin-project-lite", "pin-project-lite",
@ -763,16 +715,6 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "ghash"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40"
dependencies = [
"opaque-debug",
"polyval",
]
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.28.0" version = "0.28.0"
@ -1019,15 +961,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "inout"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "ipnet" name = "ipnet"
version = "2.9.0" version = "2.9.0"
@ -1075,20 +1008,6 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "jsonwebtoken"
version = "8.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378"
dependencies = [
"base64 0.21.5",
"pem",
"ring 0.16.20",
"serde",
"serde_json",
"simple_asn1",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -1124,6 +1043,7 @@ checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"scopeguard", "scopeguard",
"serde",
] ]
[[package]] [[package]]
@ -1198,17 +1118,6 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "num-bigint"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-bigint-dig" name = "num-bigint-dig"
version = "0.8.4" version = "0.8.4"
@ -1313,12 +1222,6 @@ version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]] [[package]]
name = "openidconnect" name = "openidconnect"
version = "3.4.0" version = "3.4.0"
@ -1407,15 +1310,6 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "pem"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8"
dependencies = [
"base64 0.13.1",
]
[[package]] [[package]]
name = "pem-rfc7468" name = "pem-rfc7468"
version = "0.7.0" version = "0.7.0"
@ -1490,18 +1384,6 @@ version = "3.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8"
[[package]]
name = "polyval"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb"
dependencies = [
"cfg-if",
"cpufeatures",
"opaque-debug",
"universal-hash",
]
[[package]] [[package]]
name = "powerfmt" name = "powerfmt"
version = "0.2.0" version = "0.2.0"
@ -1678,21 +1560,6 @@ dependencies = [
"subtle", "subtle",
] ]
[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
dependencies = [
"cc",
"libc",
"once_cell",
"spin 0.5.2",
"untrusted 0.7.1",
"web-sys",
"winapi",
]
[[package]] [[package]]
name = "ring" name = "ring"
version = "0.17.5" version = "0.17.5"
@ -1703,7 +1570,7 @@ dependencies = [
"getrandom", "getrandom",
"libc", "libc",
"spin 0.9.8", "spin 0.9.8",
"untrusted 0.9.0", "untrusted",
"windows-sys", "windows-sys",
] ]
@ -1762,7 +1629,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c"
dependencies = [ dependencies = [
"log", "log",
"ring 0.17.5", "ring",
"rustls-webpki", "rustls-webpki",
"sct", "sct",
] ]
@ -1782,8 +1649,8 @@ version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [ dependencies = [
"ring 0.17.5", "ring",
"untrusted 0.9.0", "untrusted",
] ]
[[package]] [[package]]
@ -1848,8 +1715,8 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [ dependencies = [
"ring 0.17.5", "ring",
"untrusted 0.9.0", "untrusted",
] ]
[[package]] [[package]]
@ -2012,18 +1879,6 @@ dependencies = [
"rand_core", "rand_core",
] ]
[[package]]
name = "simple_asn1"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085"
dependencies = [
"num-bigint",
"num-traits",
"thiserror",
"time",
]
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.9" version = "0.4.9"
@ -2308,6 +2163,23 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "tower-cookies"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40f38d941a2ffd8402b36e02ae407637a9caceb693aaf2edc910437db0f36984"
dependencies = [
"async-trait",
"axum-core",
"cookie",
"futures-util",
"http",
"parking_lot",
"pin-project-lite",
"tower-layer",
"tower-service",
]
[[package]] [[package]]
name = "tower-http" name = "tower-http"
version = "0.4.4" version = "0.4.4"
@ -2345,6 +2217,28 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tower-sessions"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e45e0577e58fe796e44d3f531d26af3454caf8a1b0434f85bc835e8821d61986"
dependencies = [
"async-trait",
"axum-core",
"dashmap",
"futures",
"http",
"parking_lot",
"serde",
"serde_json",
"thiserror",
"time",
"tower-cookies",
"tower-layer",
"tower-service",
"uuid",
]
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.40" version = "0.1.40"
@ -2407,22 +2301,6 @@ dependencies = [
"tinyvec", "tinyvec",
] ]
[[package]]
name = "universal-hash"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
dependencies = [
"crypto-common",
"subtle",
]
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]] [[package]]
name = "untrusted" name = "untrusted"
version = "0.9.0" version = "0.9.0"
@ -2441,6 +2319,16 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "uuid"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc"
dependencies = [
"getrandom",
"serde",
]
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"

View file

@ -14,7 +14,7 @@ tokio = { version = "1.33", features = ["full"] }
tokio-util = "0.7" tokio-util = "0.7"
futures-util = "0.3" futures-util = "0.3"
axum = { version = "0.6", features = ["multipart"] } axum = { version = "0.6", features = ["multipart"] }
axum_oidc = { git="https://git2.zettoit.eu/pfz4/axum_oidc" } axum-oidc = "0.1.0"
axum-htmx = "0.4" axum-htmx = "0.4"
tower-http = { version= "0.4", features = ["fs"] } tower-http = { version= "0.4", features = ["fs"] }
sailfish = "0.8" sailfish = "0.8"
@ -22,3 +22,5 @@ serde = "1.0"
toml = "0.8" toml = "0.8"
rand = "0.8" rand = "0.8"
qrcode = "0.12" qrcode = "0.12"
tower = "0.4.13"
tower-sessions = "0.4.1"

View file

@ -8,17 +8,22 @@ use std::{
use axum::{ use axum::{
async_trait, async_trait,
body::HttpBody,
error_handling::HandleErrorLayer,
extract::{FromRef, Multipart, Path, Query, State}, extract::{FromRef, Multipart, Path, Query, State},
http::Uri, http::{Request, StatusCode, Uri},
response::{ response::{
sse::{Event, KeepAlive}, sse::{Event, KeepAlive},
Html, IntoResponse, Redirect, Sse, Html, IntoResponse, Redirect, Sse,
}, },
routing::get, routing::get,
Form, Router, BoxError, Form, Router,
}; };
use axum_htmx::{HxRedirect, HxRequest}; use axum_htmx::{HxRedirect, HxRequest};
use axum_oidc::oidc::{self, EmptyAdditionalClaims, OidcApplication, OidcExtractor}; use axum_oidc::{
error::MiddlewareError, EmptyAdditionalClaims, OidcAuthLayer, OidcClaims, OidcClient,
OidcLoginLayer,
};
use futures_util::Stream; use futures_util::Stream;
use game::Game; use game::Game;
use garbage_collector::{start_gc, GarbageCollectorItem}; use garbage_collector::{start_gc, GarbageCollectorItem};
@ -28,7 +33,9 @@ use sailfish::TemplateOnce;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use stream::{PlayerBroadcastStream, ViewerBroadcastStream}; use stream::{PlayerBroadcastStream, ViewerBroadcastStream};
use tokio::sync::RwLock; use tokio::sync::RwLock;
use tower::{Layer, ServiceBuilder};
use tower_http::services::ServeDir; use tower_http::services::ServeDir;
use tower_sessions::{cookie::SameSite, Expiry, MemoryStore, SessionManagerLayer};
use crate::error::Error; use crate::error::Error;
@ -45,16 +52,9 @@ mod question;
pub struct AppState { pub struct AppState {
games: Arc<RwLock<HashMap<String, Game>>>, games: Arc<RwLock<HashMap<String, Game>>>,
game_expiry: Arc<RwLock<BinaryHeap<GarbageCollectorItem>>>, game_expiry: Arc<RwLock<BinaryHeap<GarbageCollectorItem>>>,
oidc_application: OidcApplication<EmptyAdditionalClaims>,
application_base: String, application_base: String,
} }
impl FromRef<AppState> for OidcApplication<EmptyAdditionalClaims> {
fn from_ref(input: &AppState) -> Self {
input.oidc_application.clone()
}
}
#[tokio::main] #[tokio::main]
pub async fn main() { pub async fn main() {
dotenvy::dotenv().ok(); dotenvy::dotenv().ok();
@ -70,18 +70,34 @@ pub async fn main() {
.map(|x| x.to_owned()) .map(|x| x.to_owned())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let oidc_application = OidcApplication::<EmptyAdditionalClaims>::create( let session_store = MemoryStore::default();
application_base let session_service = ServiceBuilder::new()
.parse() .layer(HandleErrorLayer::new(|_: BoxError| async {
.expect("valid APPLICATION_BASE url"), StatusCode::BAD_REQUEST
}))
.layer(SessionManagerLayer::new(session_store).with_same_site(SameSite::Lax));
let oidc_login_service = ServiceBuilder::new()
.layer(HandleErrorLayer::new(|e: MiddlewareError| async {
e.into_response()
}))
.layer(OidcLoginLayer::<EmptyAdditionalClaims>::new());
let oidc_auth_service = ServiceBuilder::new()
.layer(HandleErrorLayer::new(|e: MiddlewareError| async {
e.into_response()
}))
.layer(
OidcAuthLayer::<EmptyAdditionalClaims>::discover_client(
Uri::from_maybe_shared(application_base.clone()).expect("valid APPLICATION_BASE"),
issuer.to_string(), issuer.to_string(),
client_id.to_string(), client_id.to_string(),
client_secret.to_owned(), client_secret.to_owned(),
scopes.clone(), scopes.clone(),
oidc::Key::generate(),
) )
.await .await
.expect("Oidc Authentication Client"); .expect("OIDC Client"),
);
let game_expiry: Arc<RwLock<BinaryHeap<GarbageCollectorItem>>> = let game_expiry: Arc<RwLock<BinaryHeap<GarbageCollectorItem>>> =
Arc::new(RwLock::new(BinaryHeap::new())); Arc::new(RwLock::new(BinaryHeap::new()));
@ -92,18 +108,20 @@ pub async fn main() {
let app_state = AppState { let app_state = AppState {
games, games,
game_expiry, game_expiry,
oidc_application,
application_base, application_base,
}; };
let app = Router::new() let app = Router::new()
.route("/", get(handle_index).post(handle_create)) .route("/", get(handle_index).post(handle_create))
.route("/:id", get(handle_player).post(handle_player_answer))
.route("/:id/events", get(sse_player))
.route("/:id/view", get(handle_view).post(handle_view_next)) .route("/:id/view", get(handle_view).post(handle_view_next))
.route("/:id/view/events", get(sse_view)) .route("/:id/view/events", get(sse_view))
.layer(oidc_login_service)
.route("/:id", get(handle_player).post(handle_player_answer))
.route("/:id/events", get(sse_player))
.nest_service("/static", ServeDir::new("static")) .nest_service("/static", ServeDir::new("static"))
.with_state(app_state); .with_state(app_state)
.layer(oidc_auth_service)
.layer(session_service);
axum::Server::bind(&"[::]:8080".parse().expect("valid listen address")) axum::Server::bind(&"[::]:8080".parse().expect("valid listen address"))
.serve(app.into_make_service()) .serve(app.into_make_service())
@ -111,15 +129,13 @@ pub async fn main() {
.expect("axum server"); .expect("axum server");
} }
pub async fn handle_index( pub async fn handle_index() -> HandlerResult<impl IntoResponse> {
oidc_extractor: OidcExtractor<EmptyAdditionalClaims>,
) -> HandlerResult<impl IntoResponse> {
Ok(Html(IndexTemplate {}.render_once()?)) Ok(Html(IndexTemplate {}.render_once()?))
} }
pub async fn handle_create( pub async fn handle_create(
State(state): State<AppState>, State(state): State<AppState>,
oidc_extractor: OidcExtractor<EmptyAdditionalClaims>, OidcClaims(claims): OidcClaims<EmptyAdditionalClaims>,
mut body: Multipart, mut body: Multipart,
) -> HandlerResult<impl IntoResponse> { ) -> HandlerResult<impl IntoResponse> {
let mut quiz: Option<Quiz> = None; let mut quiz: Option<Quiz> = None;
@ -137,11 +153,7 @@ pub async fn handle_create(
.map(char::from) .map(char::from)
.collect(); .collect();
let game = Game::new( let game = Game::new(game_id.clone(), claims.subject().to_string(), quiz);
game_id.clone(),
oidc_extractor.claims.subject().to_string(),
quiz,
);
let mut games = state.games.write().await; let mut games = state.games.write().await;
@ -159,12 +171,12 @@ pub async fn handle_view(
Path(id): Path<String>, Path(id): Path<String>,
State(state): State<AppState>, State(state): State<AppState>,
HxRequest(htmx): HxRequest, HxRequest(htmx): HxRequest,
oidc_extractor: OidcExtractor<EmptyAdditionalClaims>, OidcClaims(claims): OidcClaims<EmptyAdditionalClaims>,
) -> HandlerResult<impl IntoResponse> { ) -> HandlerResult<impl IntoResponse> {
let games = state.games.read().await; let games = state.games.read().await;
let game = games.get(&id).ok_or(Error::NotFound)?; let game = games.get(&id).ok_or(Error::NotFound)?;
if game.owner != oidc_extractor.claims.subject().to_string() { if game.owner != claims.subject().to_string() {
return Err(Error::Forbidden); return Err(Error::Forbidden);
} }
@ -175,12 +187,12 @@ pub async fn handle_view_next(
Path(id): Path<String>, Path(id): Path<String>,
State(state): State<AppState>, State(state): State<AppState>,
HxRequest(htmx): HxRequest, HxRequest(htmx): HxRequest,
oidc_extractor: OidcExtractor<EmptyAdditionalClaims>, OidcClaims(claims): OidcClaims<EmptyAdditionalClaims>,
) -> HandlerResult<impl IntoResponse> { ) -> HandlerResult<impl IntoResponse> {
let mut games = state.games.write().await; let mut games = state.games.write().await;
let game = games.get_mut(&id).ok_or(Error::NotFound)?; let game = games.get_mut(&id).ok_or(Error::NotFound)?;
if game.owner != oidc_extractor.claims.subject().to_string() { if game.owner != claims.subject().to_string() {
return Err(Error::Forbidden); return Err(Error::Forbidden);
} }
@ -192,12 +204,12 @@ pub async fn handle_view_next(
pub async fn sse_view( pub async fn sse_view(
Path(id): Path<String>, Path(id): Path<String>,
State(state): State<AppState>, State(state): State<AppState>,
oidc_extractor: OidcExtractor<EmptyAdditionalClaims>, OidcClaims(claims): OidcClaims<EmptyAdditionalClaims>,
) -> HandlerResult<Sse<impl Stream<Item = Result<Event, Error>>>> { ) -> HandlerResult<Sse<impl Stream<Item = Result<Event, Error>>>> {
let games = state.games.read().await; let games = state.games.read().await;
let game = games.get(&id).ok_or(Error::NotFound)?; let game = games.get(&id).ok_or(Error::NotFound)?;
if game.owner != oidc_extractor.claims.subject().to_string() { if game.owner != claims.subject().to_string() {
return Err(Error::Forbidden); return Err(Error::Forbidden);
} }