72 lines
2.5 KiB
Rust
72 lines
2.5 KiB
Rust
mod template;
|
|
mod route;
|
|
|
|
use std::sync::Arc;
|
|
use crate::app::State;
|
|
use warp::{Filter, Rejection, Reply};
|
|
use std::convert::Infallible;
|
|
use warp::http::StatusCode;
|
|
use std::borrow::Cow;
|
|
use self::route::*;
|
|
|
|
pub async fn start_web(state: Arc<State>) {
|
|
let cookie_state = Arc::clone(&state);
|
|
let authed = warp::cookie("access_token")
|
|
.or(warp::header("x-api-key"))
|
|
.unify()
|
|
.and_then(move |access_token: String| {
|
|
let state = Arc::clone(&cookie_state);
|
|
async move {
|
|
if access_token == state.user_config.bot.access_token {
|
|
Ok(())
|
|
} else {
|
|
Err(warp::reject::custom(CustomRejection::InvalidAccessToken))
|
|
}
|
|
}
|
|
})
|
|
.untuple_one()
|
|
.and(
|
|
commands_routes(Arc::clone(&state))
|
|
.or(redemptions_routes(Arc::clone(&state)))
|
|
.or(livesplit_routes(Arc::clone(&state)))
|
|
);
|
|
|
|
let unauthed = access_token_routes();
|
|
|
|
let routes = authed.or(unauthed).recover(handle_rejection);
|
|
|
|
warp::serve(routes)
|
|
.run(([0, 0, 0, 0], 8000))
|
|
.await;
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
enum CustomRejection {
|
|
InvalidAccessToken,
|
|
InvalidForm,
|
|
TwitchError,
|
|
}
|
|
|
|
impl warp::reject::Reject for CustomRejection {}
|
|
|
|
async fn handle_rejection(err: Rejection) -> Result<impl Reply, Infallible> {
|
|
let (code, message) = if err.is_not_found() {
|
|
(StatusCode::NOT_FOUND, Cow::from("404 - Not Found"))
|
|
} else if let Some(custom) = err.find::<CustomRejection>() {
|
|
match custom {
|
|
CustomRejection::InvalidAccessToken => (StatusCode::UNAUTHORIZED, Cow::from("invalid access token")),
|
|
CustomRejection::InvalidForm => (StatusCode::BAD_REQUEST, Cow::from("invalid form submission")),
|
|
CustomRejection::TwitchError => (StatusCode::INTERNAL_SERVER_ERROR, Cow::from("twitch error")),
|
|
// CustomRejection::Askama(e) => (StatusCode::INTERNAL_SERVER_ERROR, Cow::from(format!("templating error: {:#?}", e))),
|
|
}
|
|
} else if let Some(e) = err.find::<warp::reject::MissingCookie>() {
|
|
(StatusCode::BAD_REQUEST, Cow::from(format!("missing `{}` cookie", e.name())))
|
|
} else if let Some(e) = err.find::<warp::reject::InvalidHeader>() {
|
|
(StatusCode::BAD_REQUEST, Cow::from(format!("missing `{}` header", e.name())))
|
|
} else {
|
|
(StatusCode::INTERNAL_SERVER_ERROR, Cow::from(format!("unhandled error: {:#?}", err)))
|
|
};
|
|
|
|
Ok(warp::reply::with_status(message, code))
|
|
}
|