Compare commits
No commits in common. "9ad50fd4f0628c84b90026a44d5761d884dd5e92" and "cb49ba0e8d6b82e2cfa43938eb5bd6850810edbd" have entirely different histories.
9ad50fd4f0
...
cb49ba0e8d
@ -1 +0,0 @@
|
|||||||
DATABASE_URL=sqlite://./db.sqlite
|
|
3
backend/.gitignore
vendored
3
backend/.gitignore
vendored
@ -1,4 +1 @@
|
|||||||
/target
|
/target
|
||||||
db.sqlite
|
|
||||||
.env
|
|
||||||
|
|
||||||
|
1469
backend/Cargo.lock
generated
1469
backend/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -4,12 +4,5 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
argon2 = "0.5.3"
|
rocket = "0.5.1"
|
||||||
env_logger = "0.11.6"
|
|
||||||
log = "0.4.22"
|
|
||||||
rocket = { version = "0.5.1", features = ["json", "secrets"] }
|
|
||||||
rocket_db_pools = { version = "0.2.0", features = ["sqlx_sqlite"] }
|
|
||||||
serde = { version = "1.0.217", features = ["derive"] }
|
|
||||||
serde_json = "1.0.134"
|
|
||||||
sqlx = { version = "0.7", features = ["macros", "migrate"] }
|
|
||||||
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
[default.databases.main]
|
|
||||||
url = "./db.sqlite"
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
|||||||
-- Add migration script here
|
|
||||||
DROP TABLE monke;
|
|
@ -1,6 +0,0 @@
|
|||||||
-- Add migration script here
|
|
||||||
CREATE TABLE monke (
|
|
||||||
monke_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
monke_name TEXT NOT NULL,
|
|
||||||
monke_password TEXT NOT NULL
|
|
||||||
);
|
|
@ -1,67 +1,12 @@
|
|||||||
use rocket::{
|
|
||||||
fairing,
|
|
||||||
http::Status,
|
|
||||||
request::{FromRequest, Outcome},
|
|
||||||
Request, Rocket,
|
|
||||||
};
|
|
||||||
use rocket_db_pools::sqlx::{self};
|
|
||||||
use rocket_db_pools::Database;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
|
|
||||||
mod modules;
|
|
||||||
|
|
||||||
// so i was trying out claude.ai, and as a joke i talked to it as monke,
|
|
||||||
// and it answered like monke. so i thought it would be funny to,
|
|
||||||
// instead of plain, boring "User", just use "Monke" :D
|
|
||||||
|
|
||||||
/// Stores info about a Monke
|
|
||||||
struct Monke {
|
|
||||||
pub monke_id: usize,
|
|
||||||
pub monke_name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Database)]
|
|
||||||
#[database("main")]
|
|
||||||
pub struct MainDb(sqlx::SqlitePool);
|
|
||||||
|
|
||||||
#[rocket::async_trait]
|
|
||||||
impl<'r> FromRequest<'r> for Monke {
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
|
||||||
// monke get cookies from request
|
|
||||||
let cookies = request.cookies();
|
|
||||||
|
|
||||||
// monke look for auth cookie
|
|
||||||
match cookies.get_private("monke_session") {
|
|
||||||
Some(cookie) => {
|
|
||||||
let auth_db = request.rocket().state::<MainDb>().unwrap();
|
|
||||||
|
|
||||||
// in real app, monke validate token here
|
|
||||||
if cookie.value().is_empty() {
|
|
||||||
Outcome::Error((Status::Unauthorized, ()))
|
|
||||||
} else {
|
|
||||||
Outcome::Success(Monke {
|
|
||||||
monke_id: cookie.value().parse().unwrap(),
|
|
||||||
monke_name: "Test".into(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => Outcome::Error((Status::Unauthorized, ())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
fn index() -> &'static str {
|
fn index() -> &'static str {
|
||||||
"Hello, world!"
|
"Hello, world!"
|
||||||
}
|
}
|
||||||
|
|
||||||
#[launch]
|
#[launch]
|
||||||
async fn rocket() -> _ {
|
fn rocket() -> _ {
|
||||||
rocket::build()
|
rocket::build().mount("/", routes![index])
|
||||||
.attach(MainDb::init())
|
|
||||||
.mount("/api", routes![index, modules::auth::login])
|
|
||||||
}
|
}
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
use argon2::{password_hash, Argon2, PasswordHash, PasswordVerifier};
|
|
||||||
use rocket::{
|
|
||||||
http::{CookieJar, Status},
|
|
||||||
serde::json::Json,
|
|
||||||
};
|
|
||||||
use rocket_db_pools::Connection;
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
use crate::MainDb;
|
|
||||||
|
|
||||||
const COOKIE_INDEX: &'static str = "monke_secret";
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
pub struct LoginCredentials {
|
|
||||||
username: String,
|
|
||||||
password: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
type ApiResponse = Json<Result<(), String>>;
|
|
||||||
|
|
||||||
#[post("/login", data = "<credentials>")]
|
|
||||||
pub async fn login(
|
|
||||||
credentials: Json<LoginCredentials>,
|
|
||||||
mut db: Connection<MainDb>,
|
|
||||||
cookies: &CookieJar<'_>,
|
|
||||||
) -> (Status, ApiResponse) {
|
|
||||||
// check them db
|
|
||||||
let result = sqlx::query!(
|
|
||||||
"SELECT * FROM monke WHERE monke_name=?",
|
|
||||||
credentials.username
|
|
||||||
)
|
|
||||||
.fetch_one(&mut **db)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let result = match result {
|
|
||||||
Ok(r) => r,
|
|
||||||
Err(sqlx::Error::RowNotFound) => {
|
|
||||||
return (Status::BadRequest, Json(Err("Invalid credentials".into())));
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("error fetching db: {:?}", e);
|
|
||||||
|
|
||||||
return (
|
|
||||||
Status::InternalServerError,
|
|
||||||
Json(Err("Server error".into())),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// check them credentials
|
|
||||||
let parsed_hash = match PasswordHash::new(&result.monke_password) {
|
|
||||||
Ok(r) => r,
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("argon2 hash parse error: {:?}", e);
|
|
||||||
return (
|
|
||||||
Status::InternalServerError,
|
|
||||||
Json(Err(String::from("Server error"))),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
match Argon2::default().verify_password(credentials.password.as_bytes(), &parsed_hash) {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(password_hash::Error::Password) => {
|
|
||||||
return (
|
|
||||||
Status::BadRequest,
|
|
||||||
Json(Err(String::from("Invalid credentials"))),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("error verifying argon2 password: {:?}", e);
|
|
||||||
return (
|
|
||||||
Status::InternalServerError,
|
|
||||||
Json(Err(String::from("Server error"))),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// create cookie
|
|
||||||
cookies.add_private((COOKIE_INDEX, result.monke_id.to_string()));
|
|
||||||
|
|
||||||
// send ok
|
|
||||||
return (Status::Ok, Json(Ok(())));
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
pub mod auth;
|
|
Loading…
Reference in New Issue
Block a user