diff options
Diffstat (limited to 'src/routes.rs')
-rw-r--r-- | src/routes.rs | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/src/routes.rs b/src/routes.rs new file mode 100644 index 0000000..3d76ab1 --- /dev/null +++ b/src/routes.rs @@ -0,0 +1,219 @@ +use hyper::{Body, Method, Request, Response}; +use serde::Deserialize; +use serde_urlencoded; +use sqlx::sqlite::SqlitePool; +use std::collections::HashMap; +use std::convert::Infallible; +use tera::Tera; +use url::form_urlencoded; + +use crate::controller; +use crate::controller::wallet::Wallet; +use crate::db; +use crate::model::config::Config; +use crate::model::user::User; + +pub async fn routes( + config: Config, + pool: SqlitePool, + assets: HashMap<String, String>, + templates: Tera, + request: Request<Body>, +) -> Result<Response<Body>, Infallible> { + let method = request.method(); + let uri = request.uri(); + let path = &uri.path().split('/').collect::<Vec<&str>>()[1..]; + + let response = match (method, path) { + (&Method::GET, ["login"]) => { + controller::login::page(&assets, &templates, None).await + } + (&Method::POST, ["login"]) => { + controller::login::login( + config, + &assets, + &templates, + body_form(request).await, + pool, + ) + .await + } + (&Method::GET, ["assets", _, file]) => { + controller::utils::file(&format!("assets/{}", file)).await + } + _ => match connected_user(&pool, &request).await { + Some(user) => { + let wallet = Wallet { + pool, + assets, + templates, + user, + }; + authenticated_routes(config, wallet, request).await + } + None => controller::utils::redirect("/login"), + }, + }; + + Ok(response) +} + +async fn connected_user( + pool: &SqlitePool, + request: &Request<Body>, +) -> Option<User> { + let cookie = request.headers().get("COOKIE")?.to_str().ok()?; + let mut xs = cookie.split('='); + xs.next(); + let login_token = xs.next()?; + db::users::get_by_login_token(&pool, login_token.to_string()).await +} + +async fn authenticated_routes( + config: Config, + wallet: Wallet, + request: Request<Body>, +) -> Response<Body> { + let method = request.method(); + let uri = request.uri(); + let path = &uri.path().split('/').collect::<Vec<&str>>()[1..]; + let query = uri.query(); + + match (method, path) { + (&Method::GET, [""]) => { + controller::payments::table(&wallet, parse_query(query)).await + } + (&Method::GET, ["payment"]) => { + controller::payments::create_form(&wallet, parse_query(query)).await + } + (&Method::POST, ["payment", "create"]) => { + controller::payments::create( + &wallet, + parse_query(query), + body_form(request).await, + ) + .await + } + (&Method::GET, ["payment", "category"]) => { + controller::payments::search_category(&wallet, parse_query(query)) + .await + } + (&Method::GET, ["payment", id]) => { + controller::payments::update_form( + parse_id(id), + &wallet, + parse_query(query), + ) + .await + } + (&Method::POST, ["payment", id, "update"]) => { + controller::payments::update( + parse_id(id), + &wallet, + parse_query(query), + body_form(request).await, + ) + .await + } + (&Method::POST, ["payment", id, "delete"]) => { + controller::payments::delete( + parse_id(id), + &wallet, + parse_query(query), + ) + .await + } + (&Method::GET, ["incomes"]) => { + controller::incomes::table(&wallet, parse_query(query)).await + } + (&Method::GET, ["income"]) => { + controller::incomes::create_form(&wallet, parse_query(query)).await + } + (&Method::POST, ["income", "create"]) => { + controller::incomes::create( + &wallet, + parse_query(query), + body_form(request).await, + ) + .await + } + (&Method::GET, ["income", id]) => { + controller::incomes::update_form( + parse_id(id), + &wallet, + parse_query(query), + ) + .await + } + (&Method::POST, ["income", id, "update"]) => { + controller::incomes::update( + parse_id(id), + &wallet, + parse_query(query), + body_form(request).await, + ) + .await + } + (&Method::POST, ["income", id, "delete"]) => { + controller::incomes::delete( + parse_id(id), + &wallet, + parse_query(query), + ) + .await + } + (&Method::GET, ["categories"]) => { + controller::categories::table(&wallet, parse_query(query)).await + } + (&Method::GET, ["category"]) => { + controller::categories::create_form(&wallet).await + } + (&Method::POST, ["category", "create"]) => { + controller::categories::create(&wallet, body_form(request).await) + .await + } + (&Method::GET, ["category", id]) => { + controller::categories::update_form(parse_id(id), &wallet).await + } + (&Method::POST, ["category", id, "update"]) => { + controller::categories::update( + parse_id(id), + &wallet, + body_form(request).await, + ) + .await + } + (&Method::POST, ["category", id, "delete"]) => { + controller::categories::delete(parse_id(id), &wallet).await + } + (&Method::GET, ["balance"]) => controller::balance::get(&wallet).await, + (&Method::GET, ["statistics"]) => { + controller::statistics::get(&wallet).await + } + (&Method::POST, ["logout"]) => { + controller::login::logout(config, &wallet).await + } + _ => controller::error::error( + &wallet, + "Page introuvable", + "La page que recherchez n’existe pas.", + ), + } +} + +fn parse_query<'a, T: Deserialize<'a>>(query: Option<&'a str>) -> T { + serde_urlencoded::from_str(query.unwrap_or("")).unwrap() +} + +async fn body_form(request: Request<Body>) -> HashMap<String, String> { + match hyper::body::to_bytes(request).await { + Ok(bytes) => form_urlencoded::parse(bytes.as_ref()) + .into_owned() + .collect::<HashMap<String, String>>(), + Err(_) => HashMap::new(), + } +} + +fn parse_id(str: &str) -> i64 { + str.parse::<i64>().unwrap() +} |