rocket_base_app/src/main.rs
#[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])
}