From 57a5577cf4946c8420db1ea485b9a69cd8e98ed3 Mon Sep 17 00:00:00 2001 From: Kilerd Chan Date: Fri, 19 Apr 2019 00:42:32 +0800 Subject: [PATCH] feat: implement remember me --- Cargo.toml | 1 + src/main.rs | 7 ++++-- src/models/user.rs | 6 +---- src/routers/admin.rs | 55 ++++++++++++++++++++++++++------------------ 4 files changed, 40 insertions(+), 29 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9381dfa..c1dc5fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,4 @@ futures = "0.1.26" http = "0.1.17" rand = "0.6.5" pretty_env_logger = "0.3.0" +time = "0.1.42" diff --git a/src/main.rs b/src/main.rs index d9c5c59..95dfcd5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,7 @@ use rand::prelude::*; use std::rc::Rc; use std::sync::Arc; use tera::compile_templates; +use time::Duration; mod guard; mod models; @@ -60,7 +61,8 @@ fn main() -> std::io::Result<()> { .wrap(IdentityService::new( CookieIdentityPolicy::new(&random_cookie_key) .name("auth-cookie") - .secure(true), + .secure(false) + .max_age(Duration::days(3)), )) .service(routers::article::homepage) .service(routers::article::single_article) @@ -72,7 +74,8 @@ fn main() -> std::io::Result<()> { .service( web::scope("/admin/") .service(routers::admin::admin_panel) - .service(routers::admin::admin_login), + .service(routers::admin::admin_login) + .service(routers::admin::admin_authentication), ) // .service(routers::article::get_article_by_url) }) diff --git a/src/models/user.rs b/src/models/user.rs index 4a70966..bada3f3 100644 --- a/src/models/user.rs +++ b/src/models/user.rs @@ -26,11 +26,7 @@ impl User { let mut hasher = Sha3::sha3_256(); hasher.input_str(password); let result = hasher.result_str(); - if self.password.eq(&result) { - true - } else { - false - } + self.password.eq(&result) } pub fn password_generate(password: &str) -> String { diff --git a/src/routers/admin.rs b/src/routers/admin.rs index 8029255..fa1748a 100644 --- a/src/routers/admin.rs +++ b/src/routers/admin.rs @@ -30,10 +30,18 @@ use crate::models::CRUD; use crate::pg_pool::Pool; use crate::routers::RubbleResponder; use actix_web::middleware::identity::Identity; -use actix_web::{get, web, Either, HttpResponse, Responder}; +use actix_web::web::Form; +use actix_web::{get, post, web, Either, HttpResponse, Responder}; +use serde::Deserialize; use std::sync::Arc; use tera::{Context, Tera}; +#[derive(Deserialize)] +struct LoginForm { + pub username: String, + pub password: String, +} + #[get("/admin")] pub fn redirect_to_admin_panel() -> impl Responder { RubbleResponder::Redirect("/admin/panel".into()) @@ -72,27 +80,30 @@ pub fn admin_login(id: Identity, tera: web::Data>) -> impl Responder { None => RubbleResponder::Html(tera.render("admin/login.html", &Context::new()).unwrap()), } } -// -// -//#[post("/login", data = "")] -//pub fn admin_authentication(user: Form, conn: DbConn, mut cookies: Cookies) -> Result { -// use crate::schema::{users, users::dsl::*}; -// -// let fetched = users::table.filter(username.eq(&user.username)).first::(&*conn); -// if fetched.is_err() { -// return Err(Status::Unauthorized); -// } -// let fetch_user: User = fetched.unwrap(); -// if !fetch_user.authenticated(user.password.as_str()) { -// return Err(Status::Unauthorized); -// } -// -// cookies.add_private(Cookie::new("LOG_SESSION", fetch_user.username)); -// cookies.add_private(Cookie::new("LOG_ID", fetch_user.id.to_string())); -// cookies.add_private(Cookie::new("LOG_ADMIN", "1")); -// -// Ok(Redirect::to("/admin")) -//} + +#[post("/login")] +pub fn admin_authentication( + id: Identity, + user: Form, + conn: web::Data, +) -> impl Responder { + let connection = conn.get().unwrap(); + + let fetched_user = User::find_by_username(&connection, &user.username); + + match fetched_user { + Ok(login_user) => { + if login_user.authenticated(&user.password) { + id.remember(login_user.username); + RubbleResponder::Redirect("/admin/panel".into()) + } else { + // TODO flash message or throw unauthorized + RubbleResponder::Redirect("/admin/login".into()) + } + } + Err(_) => RubbleResponder::Redirect("/admin/login".into()), + } +} // // //#[get("/")]