Started working on user authentication
This commit is contained in:
44
.sqlx/query-606364c79e0990deb07dfbe6c32b3d302d083ec5333f3a5ce04113c38a041100.json
generated
Normal file
44
.sqlx/query-606364c79e0990deb07dfbe6c32b3d302d083ec5333f3a5ce04113c38a041100.json
generated
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT * FROM users WHERE username = $1",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "uuid",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "username",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hash",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "email",
|
||||||
|
"ordinal": 4,
|
||||||
|
"type_info": "Text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "606364c79e0990deb07dfbe6c32b3d302d083ec5333f3a5ce04113c38a041100"
|
||||||
|
}
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "api-server"
|
name = "api-server"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = "4.9.0"
|
actix-web = "4.9.0"
|
||||||
serde = "1.0.218"
|
serde = "1.0.218"
|
||||||
serde_json = "1.0.140"
|
serde_json = "1.0.140"
|
||||||
sqlx = "0.8.3"
|
sqlx = { version = "0.8.3", features = ["sqlite", "sqlx-macros"] }
|
||||||
|
jsonwebtoken = "9.3.1"
|
||||||
|
uuid = "1.15.1"
|
||||||
|
argon2 = "0.6.0-pre.1"
|
||||||
BIN
database.db
Normal file
BIN
database.db
Normal file
Binary file not shown.
41
migrations/20250310175116_tables.sql
Normal file
41
migrations/20250310175116_tables.sql
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
-- Add migration script here
|
||||||
|
CREATE TABLE users (
|
||||||
|
'id' INTEGER PRIMARY KEY NOT NULL ,
|
||||||
|
'uuid' TEXT UNIQUE NOT NULL,
|
||||||
|
'username' TEXT NOT NULL,
|
||||||
|
'hash' TEXT NOT NULL,
|
||||||
|
'email' TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE inventories (
|
||||||
|
'id' INTEGER PRIMARY KEY NOT NULL ,
|
||||||
|
'uuid' TEXT UNIQUE NOT NULL,
|
||||||
|
'user' INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY ('user') REFERENCES users ('id')
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE user_items (
|
||||||
|
'id' INTEGER PRIMARY KEY NOT NULL ,
|
||||||
|
'uuid' TEXT UNIQUE NOT NULL,
|
||||||
|
'inventory' INTEGER NOT NULL,
|
||||||
|
'item' INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY ('inventory') REFERENCES inventories ('id'),
|
||||||
|
FOREIGN KEY ('item') REFERENCES items ('id')
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE items (
|
||||||
|
'id' INTEGER PRIMARY KEY NOT NULL ,
|
||||||
|
'uuid' TEXT UNIQUE NOT NULL,
|
||||||
|
'name' TEXT NOT NULL,
|
||||||
|
'rarity' INTEGER NOT NULL,
|
||||||
|
'image' TEXT NOT NULL,
|
||||||
|
'case' INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY ('case') REFERENCES cases ('id')
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE cases (
|
||||||
|
'id' INTEGER PRIMARY KEY NOT NULL ,
|
||||||
|
'uuid' TEXT UNIQUE NOT NULL,
|
||||||
|
'name' TEXT NOT NULL,
|
||||||
|
'image' TEXT NOT NULL
|
||||||
|
);
|
||||||
25
src/main.rs
25
src/main.rs
@@ -1,3 +1,24 @@
|
|||||||
fn main() {
|
mod users;
|
||||||
println!("Hello, world!");
|
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use users::*;
|
||||||
|
|
||||||
|
use actix_web::{App, HttpServer};
|
||||||
|
use actix_web::web::Data;
|
||||||
|
use sqlx::sqlite::SqlitePool;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct AppState {
|
||||||
|
database: SqlitePool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_web::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
let pool = SqlitePool::connect("sqlite:database.db").await.expect("Could not connect to db");
|
||||||
|
let app_state = Data::new(AppState { database: pool });
|
||||||
|
HttpServer::new(move || {
|
||||||
|
App::new()
|
||||||
|
.service(login)
|
||||||
|
.app_data(app_state.clone())
|
||||||
|
}).bind(("127.0.0.1", 8000))?.run().await
|
||||||
}
|
}
|
||||||
|
|||||||
46
src/users.rs
Normal file
46
src/users.rs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
use actix_web::web::Data;
|
||||||
|
use actix_web::{post, HttpResponse, Responder};
|
||||||
|
use argon2::password_hash::{SaltString, rand_core::OsRng, PasswordHash, PasswordVerifier, PasswordHasher};
|
||||||
|
use argon2::Argon2;
|
||||||
|
use sqlx::{query, query_as};
|
||||||
|
use crate::AppState;
|
||||||
|
|
||||||
|
struct UserLogin {
|
||||||
|
username: String,
|
||||||
|
password: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct User {
|
||||||
|
id: i64,
|
||||||
|
uuid: String,
|
||||||
|
username: String,
|
||||||
|
hash: String,
|
||||||
|
email: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/login")]
|
||||||
|
async fn login(user_login: Data<UserLogin>, app_state: Data<AppState>) -> impl Responder {
|
||||||
|
// Verify that the password is correct
|
||||||
|
let argon2 = Argon2::default();
|
||||||
|
let user = query_as!(User, "SELECT * FROM users WHERE username = $1", user_login.username).fetch_one(&app_state.database).await;
|
||||||
|
if user.is_err() {
|
||||||
|
return HttpResponse::BadRequest();
|
||||||
|
}
|
||||||
|
let user = user.unwrap();
|
||||||
|
let hash = PasswordHash::new(&user.hash);
|
||||||
|
if hash.is_err() {
|
||||||
|
return HttpResponse::BadRequest();
|
||||||
|
}
|
||||||
|
if argon2.verify_password(user_login.password.as_bytes(), &hash.unwrap()).is_err() {
|
||||||
|
return HttpResponse::BadRequest();
|
||||||
|
}
|
||||||
|
// Create the JWT
|
||||||
|
|
||||||
|
// Send the JWT as cookie
|
||||||
|
HttpResponse::Ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/logout")]
|
||||||
|
async fn logout(_token: Data<String>) -> impl Responder {
|
||||||
|
HttpResponse::Ok()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user