diff options
Diffstat (limited to 'src/handlers')
-rw-r--r-- | src/handlers/auth.rs | 117 | ||||
-rw-r--r-- | src/handlers/mod.rs | 24 | ||||
-rw-r--r-- | src/handlers/nets.rs | 50 |
3 files changed, 0 insertions, 191 deletions
diff --git a/src/handlers/auth.rs b/src/handlers/auth.rs deleted file mode 100644 index ab72bc8..0000000 --- a/src/handlers/auth.rs +++ /dev/null @@ -1,117 +0,0 @@ -use std::sync::Arc; - -use axum::{response::{IntoResponse, Html, Redirect}, Form, Extension}; -use axum_extra::extract::{PrivateCookieJar, cookie::Cookie}; -use serde::Deserialize; -use sqlx::{query, query_as, pool::PoolConnection, Postgres}; -use tracing::{debug, instrument}; -use crate::{errors::ServiceError, State, models::DbUser}; -use chrono::prelude::*; - -#[derive(Deserialize, Debug)] -pub struct RegisterForm { - pub email: String, - pub prefname: String, - pub password: String, - #[serde(rename="password-confirm")] - pub password_confirm: String -} - -#[derive(Deserialize)] -pub struct LoginForm { - pub email: String, - pub password: String, -} - -pub async fn login() -> impl IntoResponse { - let mut buf = Vec::new(); - crate::templates::login_html(&mut buf).unwrap(); - - Html(buf) -} - -pub async fn login_post(Form(login): Form<LoginForm>, state: Extension<Arc<State>>, jar: PrivateCookieJar) -> Result<(PrivateCookieJar, Redirect), ServiceError> { - let mut conn = state.conn.acquire().await?; - - let user: DbUser = query_as("SELECT * FROM users WHERE email=$1").bind(login.email) - .fetch_one(&mut conn) - .await?; - - if bcrypt::verify(login.password, &user.pw_hash)? { - debug!("Logged in ID {} (email {})", user.id, user.email); - query("UPDATE users SET last_login=$1 WHERE id=$2").bind(Utc::now()).bind(user.id.clone()) - .execute(&mut conn) - .await?; - - let updated_jar = jar.add(Cookie::build("user-id", user.id.clone()) - .path("/") - .finish()); - - Ok((updated_jar, Redirect::to("/"))) - } else { - let updated_jar = jar; - Ok((updated_jar, Redirect::to("/dash/auth/login"))) - } -} - -pub async fn register() -> impl IntoResponse { - let mut buf = Vec::new(); - crate::templates::register_html(&mut buf).unwrap(); - - Html(buf) -} - -pub async fn register_post(Form(reg): Form<RegisterForm>, state: Extension<Arc<State>>) -> impl IntoResponse { - if reg.password_confirm == reg.password { - let hash = match bcrypt::hash(reg.password, bcrypt::DEFAULT_COST) { - Ok(h) => h, - Err(e) => { - return Err(ServiceError::NotAuthorized); - } - }; - - let mut conn = state.conn.acquire().await?; - let ulid = ulid::Ulid::new(); - - query("INSERT INTO users (id, email, pref_name, pw_hash, last_login) VALUES ($1, $2, $3, $4, $5)").bind(ulid.to_string()).bind(reg.email.clone()).bind(reg.prefname).bind(hash).bind(Utc::now()) - .execute(&mut conn) - .await?; - - } - - Ok(Redirect::to("/dash/auth/login")) -} - -pub async fn logout_post(jar: PrivateCookieJar) -> Result<(PrivateCookieJar, Redirect), ServiceError> { - if let Some(id) = jar.get("user-id") { - debug!("Found user {}", id); - - let updated_jar = jar.remove(id); - - Ok((updated_jar, Redirect::to("/dash/auth/login"))) - } else { - Ok((jar, Redirect::to("/"))) - } -} - -#[instrument] -pub async fn get_user_or_403(jar: PrivateCookieJar, conn: &mut PoolConnection<Postgres>) -> Result<DbUser, ServiceError> { - debug!("Starting middleware get_user_or_403"); - debug!("Displaying all cookies"); - for c in jar.iter() { - debug!("{}={}", c.name(), c.value()); - } - if let Some(id) = jar.get("user-id") { - debug!("Found user {}", id); - - let user: DbUser = query_as("SELECT * FROM users WHERE id=$1").bind(id.value()) - .fetch_one(conn) - .await?; - - Ok(user) - - } else { - debug!("No user found"); - Err(ServiceError::NotAuthorized) - } -} diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs deleted file mode 100644 index 24db540..0000000 --- a/src/handlers/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -use axum::{Router, routing::{get, post}}; - -pub mod auth; -mod nets; - -pub async fn gen_routers() -> Router { - - Router::new() - .nest("/auth", auth_routes().await) - .nest("/nets", net_routes().await) -} - -async fn auth_routes() -> Router { - - Router::new() - .route("/login", get(auth::login).post(auth::login_post)) - .route("/register", get(auth::register).post(auth::register_post)) - .route("/logout", post(auth::logout_post)) -} - -async fn net_routes() -> Router { - Router::new() - .route("/new", get(nets::new).post(nets::new_post)) -} diff --git a/src/handlers/nets.rs b/src/handlers/nets.rs deleted file mode 100644 index 6010787..0000000 --- a/src/handlers/nets.rs +++ /dev/null @@ -1,50 +0,0 @@ -use std::sync::Arc; - -use axum::{Extension, Form}; -use axum::response::{Html, IntoResponse, Redirect}; -use axum_extra::extract::PrivateCookieJar; -use sqlx::query; -use sqlx::types::ipnetwork::IpNetwork; -use serde::Deserialize; - -use crate::State; - -use crate::errors::{HtmlResult, ServiceError}; - -use super::auth::get_user_or_403; - -#[derive(Deserialize)] -pub struct NewNetForm { - pub subnet: String, - pub description: String, -} - -pub async fn new(jar: PrivateCookieJar, state: Extension<Arc<State>>) -> Result<Html<Vec<u8>>, ServiceError> { - let mut conn = state.conn.acquire().await?; - - let _ = get_user_or_403(jar, &mut conn).await?; - - let mut buf = Vec::new(); - crate::templates::new_net_html(&mut buf).unwrap(); - - Ok(Html(buf)) -} - -pub async fn new_post(Form(new): Form<NewNetForm>, jar: PrivateCookieJar, state: Extension<Arc<State>>) -> Result<Redirect, ServiceError> { - let mut conn = state.conn.acquire().await?; - - let _ = get_user_or_403(jar, &mut conn).await?; - - let id = ulid::Ulid::new(); - - let cidr: IpNetwork = match new.subnet.parse() { - Ok(c) => c, - Err(e) => { - return Err(ServiceError::Parse(e.to_string())); - } - }; - - query("INSERT INTO networks (subnet, description, id) VALUES ($1, $2, $3)").bind(cidr).bind(new.description).bind(id.to_string()).execute(&mut conn).await?; - - Ok(Redirect::to("/")) -} |