You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
209 lines
5.7 KiB
209 lines
5.7 KiB
pub mod forms;
|
|
pub mod db;
|
|
|
|
use bcrypt::{
|
|
hash,
|
|
verify,
|
|
DEFAULT_COST
|
|
};
|
|
use rocket::{
|
|
form::Form,
|
|
response::Redirect,
|
|
State
|
|
};
|
|
use forms::{
|
|
UserLoginForm,
|
|
NewUserForm,
|
|
NewListForm,
|
|
PermsForm,
|
|
};
|
|
use db::{
|
|
List,
|
|
Notes,
|
|
Result,
|
|
add_permission,
|
|
get_user_from_email,
|
|
get_user_lists,
|
|
get_user_lists_from_perms,
|
|
User,
|
|
};
|
|
|
|
#[macro_use] extern crate rocket;
|
|
use rocket_dyn_templates::{Template, context};
|
|
use rocket_db_pools::{
|
|
Database,
|
|
Connection,
|
|
sqlx::{
|
|
self,
|
|
Row,
|
|
},
|
|
};
|
|
use rocket::{
|
|
serde::{
|
|
Serialize
|
|
},
|
|
http::{
|
|
Cookie,
|
|
CookieJar,
|
|
},
|
|
};
|
|
|
|
#[get("/hello/<name>/<age>")]
|
|
async fn hello(name: &str, age: u8) -> String {
|
|
format!("Hello, {} year old named {}!", age, name)
|
|
}
|
|
|
|
#[get("/")]
|
|
async fn home() -> Template {
|
|
Template::render("index", context!{})
|
|
}
|
|
#[get("/create")]
|
|
async fn create() -> Template {
|
|
Template::render("new", context!{})
|
|
}
|
|
|
|
#[post("/new", data="<user>")]
|
|
async fn new_user(user: Form<NewUserForm<'_>>, mut db: Connection<Notes>) -> Result<String> {
|
|
let check_exists = sqlx::query!("SELECT id FROM users WHERE username = $1 OR email = $2", user.username, user.email)
|
|
.fetch_optional(&mut *db)
|
|
.await?;
|
|
if check_exists.is_some() {
|
|
return Ok(format!("This account already exists!"));
|
|
}
|
|
let hashed_pass = match hash(user.password, DEFAULT_COST) {
|
|
Ok(pass) => pass,
|
|
Err(e) => panic!("Could not hash a password! {}", e)
|
|
};
|
|
sqlx::query!("INSERT INTO users (username,password,email) VALUES ($1, $2, $3)", user.username, hashed_pass, user.email)
|
|
.execute(&mut *db)
|
|
.await?;
|
|
Ok(format!("Thanks, {}, for creating an account on our service.", user.username))
|
|
}
|
|
|
|
#[post("/login", data="<user>")]
|
|
async fn login(user: Form<UserLoginForm<'_>>, mut db: Connection<Notes>, cookies: &CookieJar<'_>) -> Result<String> {
|
|
match cookies.get_private("user_uuid") {
|
|
Some(crumb) => println!("UUID: {:?}", crumb.value()),
|
|
_ => {}
|
|
};
|
|
let result = sqlx::query!("SELECT * FROM users WHERE username=$1", user.username)
|
|
.fetch_optional(&mut *db)
|
|
.await?;
|
|
let success = match result {
|
|
Some(ref db_user) => verify(&user.password, &db_user.password).unwrap(),
|
|
_ => false,
|
|
};
|
|
if success {
|
|
cookies.add_private(Cookie::new("user_uuid", result.unwrap().uuid));
|
|
Ok(format!("Yay! Thanks for logging in to our service!"))
|
|
} else {
|
|
Ok(format!("Incorrect login!"))
|
|
}
|
|
}
|
|
|
|
#[post("/list", data="<new_list>")]
|
|
async fn new_list(mut db: Connection<Notes>, user: User, new_list: Form<NewListForm<'_>>) -> Result<String> {
|
|
sqlx::query!("INSERT INTO list (owner_id, name) VALUES ($1, $2)", user.id, new_list.name)
|
|
.execute(&mut *db)
|
|
.await?;
|
|
Ok(format!("You added a new list: {}", new_list.name))
|
|
}
|
|
#[post("/list", data="<new_list>", rank=2)]
|
|
async fn new_list_not_logged_in(new_list: Form<NewListForm<'_>>) -> Redirect {
|
|
Redirect::to(uri!(home))
|
|
}
|
|
|
|
#[get("/lists")]
|
|
async fn show_list(mut db: Connection<Notes>, user: User) -> Result<Template> {
|
|
Ok(Template::render("show_lists", context!{
|
|
lists: get_user_lists(&mut db, user.id).await?,
|
|
perm_lists: get_user_lists_from_perms(&mut db, user.id).await?
|
|
}))
|
|
}
|
|
#[get("/lists", rank=2)]
|
|
async fn show_list_not_logged_in() -> Redirect {
|
|
Redirect::to(uri!(home))
|
|
}
|
|
|
|
#[get("/new/list")]
|
|
async fn new_list_form(_user: User) -> Template {
|
|
Template::render("new_list", context!{})
|
|
}
|
|
#[get("/new/list", rank=2)]
|
|
async fn new_list_form_not_logged_in() -> Redirect {
|
|
Redirect::to(uri!(home))
|
|
}
|
|
|
|
#[post("/perms", data="<perms>")]
|
|
async fn new_perms(perms: Form<PermsForm<'_>>, user: User, mut db: Connection<Notes>) -> Result<String> {
|
|
let perm_user = match get_user_from_email(&mut db, perms.user_email.to_string()).await? {
|
|
Some(u) => {
|
|
if u.id == user.id { return Ok(format!("You may not grant yourself a permission.")); } else { u }
|
|
},
|
|
None => return Ok(format!("Permission is added.")),
|
|
};
|
|
match add_permission(&mut db, perm_user.id, perms.list_id, perms.perm).await {
|
|
Err(_) => Ok(format!("There was an error adding this permission.")),
|
|
Ok(_) => Ok(format!("Permission is added.")),
|
|
}
|
|
}
|
|
#[post("/perms", data="<perms>", rank=2)]
|
|
async fn new_perms_not_logged_in(perms: Form<PermsForm<'_>>) -> Redirect {
|
|
Redirect::to(uri!(home))
|
|
}
|
|
|
|
#[get("/new/perms")]
|
|
async fn add_perms_form(mut db: Connection<Notes>, user: User) -> Result<Template> {
|
|
Ok(Template::render("new_perms", context!{
|
|
lists: get_user_lists(&mut db, user.id).await?
|
|
}))
|
|
}
|
|
#[get("/new/perms", rank=2)]
|
|
async fn add_perms_form_not_logged_in() -> Redirect {
|
|
Redirect::to(uri!(home))
|
|
}
|
|
|
|
#[get("/logout")]
|
|
async fn logout(mut db: Connection<Notes>, cookies: &CookieJar<'_>) -> Result<String> {
|
|
let uuid = cookies.get_private("user_uuid");
|
|
if uuid.is_none() {
|
|
return Ok(format!("You aren't logged in, lol!"));
|
|
}
|
|
cookies.remove_private(Cookie::named("user_uuid"));
|
|
let actual_uuid = uuid.unwrap();
|
|
let result = sqlx::query!("SELECT * FROM users WHERE uuid = $1", actual_uuid.value())
|
|
.fetch_optional(&mut *db)
|
|
.await?;
|
|
if let Some(user) = result {
|
|
Ok(format!("User '{}', logged out.", user.username))
|
|
} else {
|
|
Ok(format!("We don't know what happened..."))
|
|
}
|
|
}
|
|
|
|
#[launch]
|
|
fn rocket() -> _ {
|
|
rocket::build()
|
|
.attach(Template::fairing())
|
|
.attach(Notes::init())
|
|
.mount("/", routes![
|
|
hello,
|
|
home,
|
|
login,
|
|
new_user,
|
|
create,
|
|
logout
|
|
])
|
|
.mount("/new", routes![
|
|
new_list, new_list_not_logged_in,
|
|
new_perms, new_perms_not_logged_in,
|
|
])
|
|
.mount("/show", routes![
|
|
show_list, show_list_not_logged_in
|
|
])
|
|
.mount("/forms", routes![
|
|
add_perms_form, add_perms_form_not_logged_in,
|
|
new_list_form, new_list_form_not_logged_in
|
|
])
|
|
}
|