use rocket::{
form::{Context, Form},
http::{Cookie, CookieJar},
response::{Flash, Redirect},
Route, State,
};
use rocket_dyn_templates::Template;
use crate::database::Database;
use crate::models::users::User;
#[get("/users/new", rank = 1)]
fn new_already_user(_user: User) -> Redirect {
Redirect::to("/")
}
#[get("/users/new", rank = 2)]
fn new() -> Template {
Template::render("users/new", &Context::default())
}
#[derive(FromForm)]
struct NewUser {
#[field(validate = len(..20))]
pub user_name: String,
#[field(validate = len(3..))]
pub email: String,
#[field(validate = len(6..64))]
pub password: String,
}
#[post("/users", data = "<user>")]
async fn create(
db: &State<Database>,
cookie: &CookieJar<'_>,
user: Form<NewUser>,
) -> Result<Flash<Redirect>, Flash<Redirect>> {
match User::create(
db,
user.user_name.clone(),
user.password.clone(),
user.email.clone(),
)
.await
{
Ok(new_user) => {
set_user_cookie(cookie, new_user);
return Ok(Flash::success(Redirect::to("/"), "Signed up succesfully"));
}
Err(_e) => Err(Flash::error(
Redirect::to("/users/new"),
"Something went wrong",
)), }
}
#[derive(FromForm)]
struct SignIn {
#[field(validate = len(..20))]
pub user_name: String,
#[field(validate = len(6..64))]
pub password: String,
}
#[get("/users/sign_in")]
async fn get_sign_in() -> Template {
Template::render("users/sign_in", &Context::default())
}
#[post("/users/sign_in", data = "<user>")]
async fn sign_in(
db: &State<Database>,
jar: &CookieJar<'_>,
user: Form<SignIn>,
) -> Result<Flash<Redirect>, Flash<Redirect>> {
match User::authenticate(db, user.user_name.clone(), user.password.clone()).await {
Ok(u) => match u {
Some(u2) => {
set_user_cookie(jar, u2);
return Ok(Flash::success(Redirect::to("/"), "Signed in!"));
}
None => return Err(Flash::error(Redirect::to("./sign_in"), "Error signing in")),
},
Err(_e) => {
return Err(Flash::error(
Redirect::to("./sign_in"),
"SQL Error signing in",
))
}
}
}
static COOKIE_USER_ID_KEY: &str = "user_id";
#[get("/users/sign_out")]
fn sign_out(jar: &CookieJar<'_>) -> Flash<Redirect> {
jar.remove_private(Cookie::named(COOKIE_USER_ID_KEY));
Flash::success(Redirect::to("/"), "Signed out succesfully")
}
fn set_user_cookie(jar: &CookieJar<'_>, user: User) {
jar.add_private(Cookie::new(COOKIE_USER_ID_KEY, user.id.to_string()))
}
pub fn routes() -> Vec<Route> {
routes![
new,
new_already_user,
create,
get_sign_in,
sign_in,
sign_out
]
}