Mercurial > lbo > hg > analyrics
changeset 0:3f4f2ba2da92
Initial commit
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Fri, 08 Jul 2022 20:19:14 -0700 |
parents | |
children | b587a4c37254 |
files | .hgignore Cargo.toml Rocket.toml index.html login.html schema_sqlite.sql src/main.rs |
diffstat | 7 files changed, 127 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Fri Jul 08 20:19:14 2022 -0700 @@ -0,0 +1,4 @@ +^target/ +Cargo.lock +^\w+.sqlite.* +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Cargo.toml Fri Jul 08 20:19:14 2022 -0700 @@ -0,0 +1,11 @@ +[package] +name = "analyrics" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rocket = { version = "0.5.0-rc.2", features = ["secrets"] } +rocket_db_pools = { version = "0.1.0-rc.2", features = ["sqlx_sqlite"] } +tokio = { version = "1.19.2", features = ["fs"] }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Rocket.toml Fri Jul 08 20:19:14 2022 -0700 @@ -0,0 +1,2 @@ +[default.databases.sqlite_main] +url = "/home/lbo/dev/rust/analyrics/dev.sqlite"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/index.html Fri Jul 08 20:19:14 2022 -0700 @@ -0,0 +1,8 @@ +<html> + <head> + <title>Analyrics Login</title> + </head> + <body> + Welcome to anaLyrics. + </body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/login.html Fri Jul 08 20:19:14 2022 -0700 @@ -0,0 +1,8 @@ +<html> + <head> + <title>Analyrics Login</title> + </head> + <body> + + </body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/schema_sqlite.sql Fri Jul 08 20:19:14 2022 -0700 @@ -0,0 +1,8 @@ + +DROP TABLE IF EXISTS users; +CREATE TABLE users ( + id INTEGER PRIMARY KEY, + username VARCHAR(64), + name VARCHAR(64), + password_hash VARCHAR(128) +);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main.rs Fri Jul 08 20:19:14 2022 -0700 @@ -0,0 +1,86 @@ +#[macro_use] +use rocket::{self}; + +use rocket::form::{Form}; +use rocket::http::{Cookie, CookieJar, Header, Status}; +use rocket::response::{self, Flash, Redirect, Responder, Response}; +use rocket::request::{self, FlashMessage}; + +use rocket_db_pools::sqlx; +use rocket_db_pools::{Connection, Database}; + +use std::io; +use std::path::Path; + +use tokio::fs::{self, File}; + +// TO DO: use other databases? +#[derive(Database)] +#[database("sqlite_main")] +struct ConfigDB(sqlx::SqlitePool); + +const USER_ID_COOKIE_KEY: &str = "user_id"; + +async fn asset<P: AsRef<Path>>(p: P) -> io::Result<File> { + fs::OpenOptions::new().read(true).open(p).await +} + +#[derive(Responder)] +enum LoginResponse { + // use templates later. + #[response(status = 200, content_type = "html")] + Ok { body: File }, + #[response(status = 302, content_type = "html")] + LoggedInAlready { redirect: Redirect }, +} + +#[derive(Responder)] +#[response(content_type = "text", status = 500)] +struct InternalServerError { + body: String, +} + +#[rocket::get("/login")] +async fn route_login_form<'r>( + cookies: &CookieJar<'_>, +) -> Result<LoginResponse, InternalServerError> { + if let Some(cookie) = cookies.get_private(USER_ID_COOKIE_KEY) { + println!("Logged in as {}", cookie.value()); + Ok(LoginResponse::LoggedInAlready { + redirect: Redirect::to(rocket::uri!("/")), + }) + } else { + Ok(LoginResponse::Ok { + body: asset("login.html").await.unwrap(), + }) + } +} + +#[derive(rocket::FromForm)] +struct LoginForm { + username: String, + password: String, +} + +#[rocket::post("/login", data = "<login>")] +async fn route_login_post(cookies: &CookieJar<'_>, login: Form<LoginForm>) -> Flash<Redirect> { + // TO DO: look up user in database. + let c = Cookie::new(USER_ID_COOKIE_KEY, login.username.clone()); + cookies.add_private(c); + Flash::success(Redirect::to(rocket::uri!("/")), "Successfully logged in.") +} + +#[rocket::get("/")] +async fn route_index(flash: Option<FlashMessage<'_>>) -> response::content::RawHtml<File> { + if let Some(flash) = flash { + println!("Flash message: {}: {}", flash.kind(), flash.message()); + } + response::content::RawHtml(asset("index.html").await.unwrap()) +} + +#[rocket::launch] +fn rocketmain() -> _ { + rocket::build() + .attach(ConfigDB::init()) + .mount("/", rocket::routes![route_index, route_login_form, route_login_post]) +}