rocket_base_app/src/main.rs


Home Back
#[macro_use]
extern crate rocket;
use minijinja::{Environment, context};
use rocket::form::Form;
use rocket::http::CookieJar;
use rocket::http::Status;
use rocket::response::Redirect;
use rocket::response::content::RawHtml;
use rocket::response::status::Custom;

use std::fs;
mod session;
mod templates;

use bcrypt::{hash, verify};

pub fn hash_password(plain: &str) -> Result<String, bcrypt::BcryptError> {
    hash(plain, 4)
}

pub fn verify_password(plain: &str, hashed: &str) -> Result<bool, bcrypt::BcryptError> {
    verify(plain, hashed)
}

/* Check user/password only one time, then set in the session json logged=true */
pub fn auth(cookie: &CookieJar<'_>, username: String, password: String) -> bool {
    // Build a user table in memory for tests
    struct User {
        user: String,
        pass: String,
    }

    let users = vec![
        User {
            user: "fabio".to_string(),
            pass: hash_password("secret").unwrap(),
        },
        User {
            user: "altro".to_string(),
            pass: hash_password("secret2").unwrap(),
        },
    ];

    match cookie.get(session::COOKIE_NAME) {
        Some(_c) => (),
        None => {
            eprintln!("Error on get cookie");
            return false;
        }
    }

    for x in users.iter() {
        if x.user == username && verify_password(&password, &x.pass).unwrap_or_else(|_| false) {
            session::set_session(
                cookie,
                session::COOKIE_NAME.to_string(),
                "logged".to_string(),
                "true".to_string(),
            )
            .unwrap();
            return true;
        }
    }

    return false;
}

#[get("/home", format = "text/html")]
fn home(cookie: &CookieJar<'_>) -> RawHtml<&'static str> {
    let logged = session::get_session(
        cookie,
        session::COOKIE_NAME.to_string(),
        "logged".to_string(),
    )
    .unwrap_or_else(|_| "err".to_string());

    if logged != "true" {
        return RawHtml("Not logged!<br><a href=\"/login_form\">Please login</a>");
    }
    RawHtml("<h2>Home</h2><p>You are logged</p><p><a href=\"/logout\">Logout</a></p>")
}

#[get("/login_form")]
fn login_form() -> Custom<RawHtml<String>> {
    let title = "Page title";
    let sub_title = "Subtitle etc...";
    //let html = include_str!("../views/home.html"); //includo la stringa a cmpile time
    let html =
        fs::read_to_string("views/login.html").unwrap_or_else(|_| "Template assente".to_string());

    let mut env = Environment::new();
    env.add_template("login.html", html.as_str()).unwrap();
    let template = env.get_template("login.html").unwrap();
    let res = template
        .render(context!(title => title,sub_title=> sub_title))
        .unwrap();

    Custom(Status::Accepted, RawHtml(res))
}

#[derive(FromForm)]
struct FormAuth {
    username: String,
    password: String,
}
#[post("/login", data = "<form>")]
fn login(cookie: &CookieJar<'_>, form: Form<FormAuth>) -> Custom<RawHtml<String>> {
    let data = form.into_inner();
    let username = &data.username;
    let password = &data.password;

    match cookie.get(session::COOKIE_NAME) {
        Some(c) => {
            session::set_session(
                cookie,
                session::COOKIE_NAME.to_string(),
                "username".to_string(),
                username.to_string(),
            )
            .unwrap_or_else(|_| "err".to_string());

            session::set_expire_session(c.value(), session::EXPIRE_SESSION_SECS).unwrap();

            if !auth(cookie, username.to_string(), password.to_string()) {
                let res =
                    "<h3>Not logged</h3><br><a href=\"/login_form\">Please login</a>".to_string();
                return Custom(Status::Accepted, RawHtml(res));
            }

            let res = format!(
                "<h3>Se sei qui sei loggato, il valore del tuo cookie di sessione รจ : {}</h3><p><a href=\"/logout\">Logout</a></p>",
                c.value()
            )
            .to_string();
            Custom(Status::Accepted, RawHtml(res))
        }
        None => {
            let res = "<h3>Cookie non impostato!</h3><br><a href=\"/login_form\">Please login</a>"
                .to_string();
            Custom(Status::Accepted, RawHtml(res))
        }
    }
}

#[get("/logout")]
fn logout(jar: &CookieJar<'_>) -> Redirect {
    match jar.get(session::COOKIE_NAME) {
        Some(c) => {
            println!("Cerco di eleiminare da valkey: {}", c.value().to_string());
            session::del_session(&c.value().to_string()).unwrap();
        }
        None => {
            eprintln!(
                "In function logout : cookie {} not present. ",
                session::COOKIE_NAME
            );
        }
    }

    Redirect::to(uri!(home))
}

#[get("/template")]
fn template() -> Custom<RawHtml<String>> {
    //let res = template_embed!("views/home.html", context!(title => "A beatifull title!"));
    let res = templates::template_load("views/home.html", context!(title => "A caldo!"));

    Custom(
        Status::Accepted,
        RawHtml(res.unwrap_or_else(|_| "Error on load template file!".to_string())),
    )
}

#[launch]
fn rocket() -> _ {
    rocket::build().mount("/", routes![home, login, logout, login_form, template])
}

Powered by Code, a simple repository browser by Fabio Di Matteo