From 84bffc5f72910370c61532aae297027fb7e3a35a Mon Sep 17 00:00:00 2001 From: Fabrice Bellamy <12b@distrilab.fr> Date: Tue, 22 Oct 2024 23:21:11 +0200 Subject: [PATCH] implement auth login with a JWT cookie --- nixin_farm_ssr/assets/views/home/index.html | 5 +- nixin_farm_ssr/assets/views/home/login.html | 2 +- .../assets/views/home/register.html | 17 +++++ nixin_farm_ssr/config/development.yaml | 3 + nixin_farm_ssr/src/controllers/home.rs | 63 ++++++++++++++++++- nixin_farm_ssr/src/views/home.rs | 2 +- 6 files changed, 86 insertions(+), 6 deletions(-) diff --git a/nixin_farm_ssr/assets/views/home/index.html b/nixin_farm_ssr/assets/views/home/index.html index decca6a..99ac1b1 100644 --- a/nixin_farm_ssr/assets/views/home/index.html +++ b/nixin_farm_ssr/assets/views/home/index.html @@ -8,7 +8,10 @@ Login
NixiN -

Index

+

+ Index +

+ hello user {{user.name}}
diff --git a/nixin_farm_ssr/assets/views/home/login.html b/nixin_farm_ssr/assets/views/home/login.html index 01e75f2..f01699c 100644 --- a/nixin_farm_ssr/assets/views/home/login.html +++ b/nixin_farm_ssr/assets/views/home/login.html @@ -34,7 +34,7 @@ Login
-
+
diff --git a/nixin_farm_ssr/assets/views/home/register.html b/nixin_farm_ssr/assets/views/home/register.html index e69de29..22a7978 100644 --- a/nixin_farm_ssr/assets/views/home/register.html +++ b/nixin_farm_ssr/assets/views/home/register.html @@ -0,0 +1,17 @@ +{% extends "base.html" %} + +{% block title %} +Login +{% endblock title %} + +{% block content %} +
+
+ NixiN +

+ Register a new account +

+
+ +
+{% endblock content %} \ No newline at end of file diff --git a/nixin_farm_ssr/config/development.yaml b/nixin_farm_ssr/config/development.yaml index 0cf43c6..1aad416 100644 --- a/nixin_farm_ssr/config/development.yaml +++ b/nixin_farm_ssr/config/development.yaml @@ -146,3 +146,6 @@ auth: secret: jECGaGSsMtQmKyYyGuk7 # Token expiration time in seconds expiration: 604800 # 7 days + location: + from: Cookie + name: token diff --git a/nixin_farm_ssr/src/controllers/home.rs b/nixin_farm_ssr/src/controllers/home.rs index ee2e963..fea84a3 100644 --- a/nixin_farm_ssr/src/controllers/home.rs +++ b/nixin_farm_ssr/src/controllers/home.rs @@ -2,8 +2,18 @@ #![allow(clippy::unnecessary_struct_initialization)] #![allow(clippy::unused_async)] use loco_rs::prelude::*; -use axum::debug_handler; -use axum::{extract::State, Json}; + +use axum::{ + debug_handler, + extract::State, + extract::Query, + response::{IntoResponse, Redirect}, + http::StatusCode, + Json, + Form}; +use axum_extra::extract::cookie::{CookieJar, Cookie}; + +use serde::{Deserialize, Serialize}; use loco_rs::{ app::AppContext, controller::middleware, @@ -11,7 +21,10 @@ use loco_rs::{ }; use crate::{ - models::users, + models::{ + users, + //users::{LoginParams, RegisterParams}, + }, views, controllers::middleware::auth_no_error, }; @@ -36,8 +49,52 @@ pub async fn home( } } +#[derive(Debug, Serialize, Deserialize)] +pub struct LoginParams { + pub email: Option, + pub password: Option, +} + +/// Creates a user login and returns a token +#[debug_handler] +pub async fn login( + auth: auth_no_error::JWTWithUserOpt, + //ViewEngine(v): ViewEngine, + State(ctx): State, + jar: CookieJar, + Form(params): Form) -> Result<(CookieJar, Redirect), StatusCode> { + println!("Auth: {:?}",auth); + println!("Form parameters: {:?}",params); + println!("Cookie jar: {:?}",jar); + + match params { + LoginParams{email: Some(email), password: Some(password)} => { + let user = users::Model::find_by_email(&ctx.db, &email).await + .or_else(|_| Err(StatusCode::UNAUTHORIZED))?; + let valid = user.verify_password(&password); + if !valid { + return Err(StatusCode::UNAUTHORIZED); + } + let jwt_secret = ctx.config.get_jwt_config() + .or_else(|_| Err(StatusCode::UNAUTHORIZED))?; + let token = user + .generate_jwt(&jwt_secret.secret, &jwt_secret.expiration) + .or_else(|_| Err(StatusCode::UNAUTHORIZED))?; + Ok(( + // the updated jar must be returned for the changes + // to be included in the response + jar.add(Cookie::new("token", token)), + Redirect::to("/"),)) + } + _ => { + Err(StatusCode::UNAUTHORIZED) + } + } +} + pub fn routes() -> Routes { Routes::new() //.prefix("homes") .add("/", get(home)) + .add("/login", post(login)) } diff --git a/nixin_farm_ssr/src/views/home.rs b/nixin_farm_ssr/src/views/home.rs index f59bc05..7619e9e 100644 --- a/nixin_farm_ssr/src/views/home.rs +++ b/nixin_farm_ssr/src/views/home.rs @@ -17,6 +17,6 @@ pub fn login(v: &impl ViewRenderer) -> Result { /// /// When there is an issue with rendering the view. pub fn index(v: &impl ViewRenderer, user: &users::Model) -> Result { - format::render().view(v, "server/show.html", data!({"user": user})) + format::render().view(v, "home/index.html", data!({"user": user})) }