141 lines
4.4 KiB
Rust
141 lines
4.4 KiB
Rust
use axum::{
|
|
middleware,
|
|
routing::{get, post, IntoMakeService},
|
|
};
|
|
use axum_login::AuthManagerLayerBuilder;
|
|
use sqlx::SqlitePool;
|
|
#[macro_use]
|
|
extern crate justerror;
|
|
|
|
/// Some public interfaces for interacting with the database outside of the web
|
|
/// app
|
|
pub use db::get_db_pool;
|
|
pub mod conf;
|
|
pub mod imdb_utils;
|
|
pub mod import_utils;
|
|
pub mod misc_util;
|
|
|
|
pub use conf::*;
|
|
pub use signup::Invitation;
|
|
pub use stars::*;
|
|
pub use users::User;
|
|
pub use watches::{ShowKind, Watch, WatchQuest};
|
|
|
|
pub type WWRouter = axum::Router<SqlitePool>;
|
|
pub type WatchDate = chrono::DateTime<chrono::Utc>;
|
|
|
|
// everything else is private to the crate
|
|
mod auth;
|
|
mod db;
|
|
mod generic_handlers;
|
|
mod login;
|
|
mod search;
|
|
mod signup;
|
|
mod stars;
|
|
mod templates;
|
|
mod users;
|
|
mod watches;
|
|
|
|
// things we want in the crate namespace
|
|
use auth::AuthSession;
|
|
use optional_optional_user::OptionalOptionalUser;
|
|
use templates::*;
|
|
use watches::templates::*;
|
|
|
|
/// Returns the router to be used as a service or test object, you do you.
|
|
pub async fn app(db_pool: sqlx::SqlitePool) -> IntoMakeService<axum::Router> {
|
|
// don't bother bringing handlers into the whole crate namespace
|
|
use auth::*;
|
|
use generic_handlers::{handle_slash, handle_slash_redir};
|
|
use login::{get_login, get_logout, post_login, post_logout};
|
|
use search::get_search_watch;
|
|
use signup::handlers::{get_create_user, get_signup_success, post_create_user};
|
|
use tower_http::services::ServeDir;
|
|
use watches::handlers::{
|
|
edit_watch_quest, get_add_new_watch, get_watch, get_watch_status, get_watches,
|
|
post_add_new_watch, post_add_watch_quest,
|
|
};
|
|
|
|
let conf = crate::conf::Config::get();
|
|
tracing::info!("Using config: {conf:#?}");
|
|
|
|
let auth_layer = {
|
|
let session_layer = session_layer(db_pool.clone()).await;
|
|
let store = AuthStore::new(db_pool.clone());
|
|
AuthManagerLayerBuilder::new(store, session_layer).build()
|
|
};
|
|
|
|
let assets_dir = std::env::current_dir().unwrap().join("assets");
|
|
let assets_svc = ServeDir::new(assets_dir.as_path());
|
|
|
|
axum::Router::new()
|
|
.route("/", get(handle_slash).post(handle_slash))
|
|
.nest_service("/assets", assets_svc)
|
|
.route("/signup", post(post_create_user))
|
|
.route("/signup/:invitation", get(get_create_user))
|
|
.route("/signup_success/:user", get(get_signup_success))
|
|
.route("/login", get(get_login).post(post_login))
|
|
.route("/logout", get(get_logout).post(post_logout))
|
|
.route("/watches", get(get_watches))
|
|
.route("/watch", get(get_watch))
|
|
.route("/watch/:watch", get(get_watch))
|
|
.route("/watch/status/:watch", get(get_watch_status))
|
|
.route("/quest/edit", post(edit_watch_quest))
|
|
.route("/title-search", get(get_search_watch))
|
|
.route("/add", get(get_add_new_watch).post(post_add_new_watch))
|
|
.route(
|
|
"/add/watch",
|
|
get(get_search_watch).post(post_add_watch_quest),
|
|
)
|
|
.fallback(handle_slash_redir)
|
|
.layer(middleware::from_fn_with_state(
|
|
db_pool.clone(),
|
|
users::handle_update_last_seen,
|
|
))
|
|
.layer(auth_layer)
|
|
.with_state(db_pool)
|
|
.into_make_service()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub mod test_utils;
|
|
|
|
//-************************************************************************
|
|
// tests for the proc macro for optional user
|
|
//-************************************************************************
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::{signup::templates::SignupSuccessPage, MainPage, OptionalOptionalUser, User};
|
|
|
|
#[test]
|
|
fn main_page_has_optional_user() {
|
|
assert!(MainPage::default().has_optional_user());
|
|
assert!(MainPage::default().has_user());
|
|
}
|
|
|
|
#[test]
|
|
fn signup_success_has_no_optional_user() {
|
|
assert!(!SignupSuccessPage::default().has_optional_user());
|
|
}
|
|
|
|
#[test]
|
|
fn user_is_not_optional() {
|
|
#[derive(Default, OptionalOptionalUser)]
|
|
struct TestThing {
|
|
user: User,
|
|
}
|
|
assert!(!TestThing::default().has_optional_user());
|
|
assert!(TestThing::default().has_mandatory_user());
|
|
assert!(TestThing::default().has_user());
|
|
}
|
|
|
|
#[test]
|
|
fn user_is_not_user() {
|
|
#[derive(Default, OptionalOptionalUser)]
|
|
struct TestThing {
|
|
user: Option<bool>,
|
|
}
|
|
assert!(!TestThing::default().has_optional_user());
|
|
assert!(!TestThing::default().has_user());
|
|
}
|
|
}
|