mock auth
This commit is contained in:
parent
2d0956251b
commit
d38f8891f5
73
backend/Cargo.lock
generated
73
backend/Cargo.lock
generated
@ -110,6 +110,7 @@ dependencies = [
|
|||||||
"prost-types",
|
"prost-types",
|
||||||
"rocket",
|
"rocket",
|
||||||
"rocket_prost_responder_derive",
|
"rocket_prost_responder_derive",
|
||||||
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -124,6 +125,12 @@ version = "2.10.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.24.0"
|
version = "1.24.0"
|
||||||
@ -656,6 +663,16 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
@ -1920,6 +1937,17 @@ version = "0.9.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.18.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.3.4",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "valuable"
|
name = "valuable"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -1953,6 +1981,51 @@ dependencies = [
|
|||||||
"wit-bindgen",
|
"wit-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.106"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.106"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.106"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.106"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows"
|
name = "windows"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
|
|||||||
@ -9,6 +9,7 @@ prost-types = "0.14.1"
|
|||||||
rocket = { git = "https://github.com/rwf2/Rocket", rev = "504efef179622df82ba1dbd37f2e0d9ed2b7c9e4" }
|
rocket = { git = "https://github.com/rwf2/Rocket", rev = "504efef179622df82ba1dbd37f2e0d9ed2b7c9e4" }
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
rocket_prost_responder_derive = { path = "rocket_prost_responder_derive" }
|
rocket_prost_responder_derive = { path = "rocket_prost_responder_derive" }
|
||||||
|
uuid = { version = "1.10.0", features = ["v4"] }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
prost-build = "0.14.1"
|
prost-build = "0.14.1"
|
||||||
|
|||||||
89
backend/src/auth.rs
Normal file
89
backend/src/auth.rs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
use rocket::State;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use uuid::Uuid;
|
||||||
|
use crate::items;
|
||||||
|
use crate::proto_utils::Proto;
|
||||||
|
|
||||||
|
pub struct AuthState {
|
||||||
|
// Map token -> username
|
||||||
|
tokens: Mutex<HashMap<String, String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthState {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tokens: Mutex::new(HashMap::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/login", data = "<request>")]
|
||||||
|
pub fn login(
|
||||||
|
state: &State<AuthState>,
|
||||||
|
request: Proto<items::LoginRequest>,
|
||||||
|
) -> items::LoginResponse {
|
||||||
|
let req = request.into_inner();
|
||||||
|
// Simple mock authentication: allow any non-empty username/password
|
||||||
|
if !req.username.is_empty() && !req.password.is_empty() {
|
||||||
|
let token = Uuid::new_v4().to_string();
|
||||||
|
let mut tokens = state.tokens.lock().unwrap();
|
||||||
|
tokens.insert(token.clone(), req.username);
|
||||||
|
|
||||||
|
items::LoginResponse {
|
||||||
|
token,
|
||||||
|
success: true,
|
||||||
|
message: "Login successful".to_string(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
items::LoginResponse {
|
||||||
|
token: "".to_string(),
|
||||||
|
success: false,
|
||||||
|
message: "Invalid credentials".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/logout", data = "<request>")]
|
||||||
|
pub fn logout(
|
||||||
|
state: &State<AuthState>,
|
||||||
|
request: Proto<items::LogoutRequest>,
|
||||||
|
) -> items::LogoutResponse {
|
||||||
|
let req = request.into_inner();
|
||||||
|
let mut tokens = state.tokens.lock().unwrap();
|
||||||
|
|
||||||
|
if tokens.remove(&req.token).is_some() {
|
||||||
|
items::LogoutResponse {
|
||||||
|
success: true,
|
||||||
|
message: "Logged out successfully".to_string(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
items::LogoutResponse {
|
||||||
|
success: false,
|
||||||
|
message: "Invalid token".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/get_auth_status", data = "<request>")]
|
||||||
|
pub fn get_auth_status(
|
||||||
|
state: &State<AuthState>,
|
||||||
|
request: Proto<items::AuthStatusRequest>,
|
||||||
|
) -> items::AuthStatusResponse {
|
||||||
|
let req = request.into_inner();
|
||||||
|
let tokens = state.tokens.lock().unwrap();
|
||||||
|
|
||||||
|
if let Some(username) = tokens.get(&req.token) {
|
||||||
|
items::AuthStatusResponse {
|
||||||
|
authenticated: true,
|
||||||
|
username: username.clone(),
|
||||||
|
message: "Authenticated".to_string(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
items::AuthStatusResponse {
|
||||||
|
authenticated: false,
|
||||||
|
username: "".to_string(),
|
||||||
|
message: "Not authenticated".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,9 @@ pub mod items {
|
|||||||
include!(concat!(env!("OUT_DIR"), "/items.rs"));
|
include!(concat!(env!("OUT_DIR"), "/items.rs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod auth;
|
||||||
|
mod proto_utils;
|
||||||
|
|
||||||
#[get("/<name>")]
|
#[get("/<name>")]
|
||||||
fn get_user(user_list: &rocket::State<Vec<items::Person>>, name: String) -> Option<items::Person> {
|
fn get_user(user_list: &rocket::State<Vec<items::Person>>, name: String) -> Option<items::Person> {
|
||||||
user_list.iter().find(|user| user.name == name).cloned()
|
user_list.iter().find(|user| user.name == name).cloned()
|
||||||
@ -53,6 +56,7 @@ fn rocket() -> _ {
|
|||||||
min_players: 1,
|
min_players: 1,
|
||||||
max_players: 90,
|
max_players: 90,
|
||||||
price: 0,
|
price: 0,
|
||||||
|
remote_id: 0,
|
||||||
}),
|
}),
|
||||||
would_play: true,
|
would_play: true,
|
||||||
}],
|
}],
|
||||||
@ -60,7 +64,12 @@ fn rocket() -> _ {
|
|||||||
|
|
||||||
rocket::build()
|
rocket::build()
|
||||||
.manage(user_list)
|
.manage(user_list)
|
||||||
|
.manage(auth::AuthState::new())
|
||||||
.mount("/api", routes![get_users, get_user])
|
.mount("/api", routes![get_users, get_user])
|
||||||
|
.mount(
|
||||||
|
"/auth",
|
||||||
|
routes![auth::login, auth::logout, auth::get_auth_status],
|
||||||
|
)
|
||||||
.mount("/", routes![index_fallback])
|
.mount("/", routes![index_fallback])
|
||||||
.mount("/", FileServer::new("../frontend/dist"))
|
.mount("/", FileServer::new("../frontend/dist"))
|
||||||
}
|
}
|
||||||
|
|||||||
50
backend/src/proto_utils.rs
Normal file
50
backend/src/proto_utils.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use rocket::data::{Data, FromData, Outcome, ToByteUnit};
|
||||||
|
use rocket::http::{Status, ContentType};
|
||||||
|
use rocket::Request;
|
||||||
|
use prost::Message;
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
|
pub struct Proto<T>(pub T);
|
||||||
|
|
||||||
|
impl<T> Proto<T> {
|
||||||
|
pub fn into_inner(self) -> T {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Deref for Proto<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DerefMut for Proto<T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rocket::async_trait]
|
||||||
|
impl<'r, T: Message + Default> FromData<'r> for Proto<T> {
|
||||||
|
type Error = String;
|
||||||
|
|
||||||
|
async fn from_data(req: &'r Request<'_>, data: Data<'r>) -> Outcome<'r, Self> {
|
||||||
|
if req.content_type() != Some(&ContentType::new("application", "protobuf")) {
|
||||||
|
return Outcome::Forward((data, Status::NotFound));
|
||||||
|
}
|
||||||
|
|
||||||
|
let limit = req.limits().get("protobuf").unwrap_or(1.mebibytes());
|
||||||
|
let bytes = match data.open(limit).into_bytes().await {
|
||||||
|
Ok(bytes) if bytes.is_complete() => bytes.into_inner(),
|
||||||
|
Ok(_) => return Outcome::Error((Status::PayloadTooLarge, "Payload too large".into())),
|
||||||
|
Err(e) => return Outcome::Error((Status::InternalServerError, e.to_string())),
|
||||||
|
};
|
||||||
|
|
||||||
|
match T::decode(&bytes[..]) {
|
||||||
|
Ok(msg) => Outcome::Success(Proto(msg)),
|
||||||
|
Err(e) => Outcome::Error((Status::UnprocessableEntity, e.to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -19,6 +19,7 @@ message Game {
|
|||||||
uint32 min_players = 4;
|
uint32 min_players = 4;
|
||||||
uint32 max_players = 5;
|
uint32 max_players = 5;
|
||||||
uint32 price = 6;
|
uint32 price = 6;
|
||||||
|
uint64 remote_id = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Source {
|
enum Source {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user