From 7594e3d61529253e63490174fa9fa1f4c20eb709 Mon Sep 17 00:00:00 2001 From: shiroyashik Date: Tue, 18 Jun 2024 16:01:23 +0300 Subject: [PATCH] Added a feature to create temporary users - Token verification simplified --- src/auth.rs | 38 +++++++++++++++++++++++++++++--------- src/config.rs | 22 ++++++++++++++-------- src/main.rs | 6 +++++- src/profile.rs | 2 +- src/ws/http.rs | 32 +++++++++----------------------- src/ws/mod.rs | 2 +- src/ws/websocket.rs | 3 +-- 7 files changed, 60 insertions(+), 45 deletions(-) diff --git a/src/auth.rs b/src/auth.rs index 21e5649..faf1f3d 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -3,12 +3,7 @@ use std::{str::FromStr, sync::Arc}; use crate::utils::*; use anyhow::anyhow; use axum::{ - async_trait, debug_handler, - extract::{FromRequestParts, Query, State}, - http::{request::Parts, StatusCode}, - response::{IntoResponse, Response}, - routing::get, - Router, + async_trait, debug_handler, extract::{FromRequestParts, Query, State}, http::{request::Parts, StatusCode}, response::{IntoResponse, Response}, routing::{get, post}, Json, Router }; use dashmap::DashMap; use ring::digest::{self, digest}; @@ -24,6 +19,11 @@ pub fn router() -> Router { .route("/verify", get(verify)) } +pub fn router_v1() -> Router { + Router::new() + .route("/create", post(create_user)) +} + // Web #[derive(Deserialize)] struct Id { @@ -83,7 +83,10 @@ async fn verify( } } -pub async fn status(Token(token): Token, State(state): State) -> Response { +pub async fn status( + Token(token): Token, + State(state): State +) -> Response { match token { Some(token) => { if state.user_manager.is_authenticated(&token) { @@ -98,6 +101,21 @@ pub async fn status(Token(token): Token, State(state): State) -> Respo } } } + +pub async fn create_user( + Token(token): Token, + State(state): State, + Json(json): Json +) -> Response { + debug!("Json: {json:?}"); + match state.config.lock().await.clone().verify_token(&token) { + Ok(_) => {}, + Err(e) => return e, + } + + state.user_manager.insert_user(json.uuid, json); + (StatusCode::OK, "ok".to_string()).into_response() +} // Web End // It's an extractor that pulls a token from the Header. @@ -126,6 +144,7 @@ where // End Extractor #[derive(Debug, Clone, PartialEq, Deserialize)] +#[serde(rename_all = "lowercase")] pub enum AuthSystem { Internal, ElyBy, @@ -233,7 +252,8 @@ pub struct UManager { registered: Arc>, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct Userinfo { pub username: String, pub uuid: Uuid, @@ -278,7 +298,7 @@ impl UManager { pub fn is_authenticated(&self, token: &String) -> bool { self.authenticated.contains_key(token) } - pub fn is_registered(&self, uuid: &Uuid) -> bool { + pub fn _is_registered(&self, uuid: &Uuid) -> bool { self.registered.contains_key(uuid) } pub fn remove(&self, uuid: &Uuid) { diff --git a/src/config.rs b/src/config.rs index 4ab2978..a851277 100644 --- a/src/config.rs +++ b/src/config.rs @@ -14,17 +14,23 @@ pub struct Config { } impl Config { - pub fn verify_token(&self, suspicious: &str) -> bool { + pub fn verify_token(&self, suspicious: &Option) -> Result { + use axum::{http::StatusCode, response::IntoResponse}; match &self.token { - Some(t) => { - if t == suspicious { - true - } else { - false + Some(token) => { + match suspicious { + Some(suspicious) => { + if token == suspicious { + return Ok((StatusCode::OK, "ok".to_string()).into_response()) + } else { + return Err((StatusCode::UNAUTHORIZED, "wrong token".to_string()).into_response()) + } + }, + None => return Err((StatusCode::UNAUTHORIZED, "unauthorized".to_string()).into_response()) } }, - None => false - } + None => return Err((StatusCode::LOCKED, "token doesnt defined".to_string()).into_response()), + } } } diff --git a/src/main.rs b/src/main.rs index 3f24c15..53625bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -94,9 +94,13 @@ async fn main() -> Result<()> { } }); + let v1 = Router::new() + .nest("/", ws::http2ws_router()) + .nest("/user", api_auth::router_v1()); + let api = Router::new() .nest("//auth", api_auth::router()) - .nest("/v1", ws::http_router()) + .nest("/v1", v1) .route("/limits", get(api_info::limits)) .route("/version", get(api_info::version)) .route("/motd", get(api_info::motd)) diff --git a/src/profile.rs b/src/profile.rs index 73c5815..07fc760 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -4,7 +4,7 @@ use axum::{ extract::{Path, State}, Json, }; -use tracing::{debug, warn}; +use tracing::debug; use serde_json::{json, Value}; use tokio::{ fs, diff --git a/src/ws/http.rs b/src/ws/http.rs index 4770781..5860f1b 100644 --- a/src/ws/http.rs +++ b/src/ws/http.rs @@ -27,15 +27,9 @@ async fn verify( Token(token): Token, State(state): State, ) -> Response { - match token { - Some(t) => { - if !state.config.lock().await.verify_token(&t) { - return (StatusCode::UNAUTHORIZED, "wrong token".to_string()).into_response() - } - }, - None => return (StatusCode::UNAUTHORIZED, "unauthorized".to_string()).into_response(), - } - (StatusCode::OK, "ok".to_string()).into_response() + state.config.lock().await.clone() + .verify_token(&token) + .unwrap_or_else(|x| x) } async fn raw( @@ -45,13 +39,9 @@ async fn raw( body: String, ) -> Response { debug!(body = body); - match token { - Some(t) => { - if !state.config.lock().await.verify_token(&t) { - return (StatusCode::UNAUTHORIZED, "wrong token".to_string()).into_response() - } - }, - None => return (StatusCode::UNAUTHORIZED, "unauthorized".to_string()).into_response(), + match state.config.lock().await.clone().verify_token(&token) { + Ok(_) => {}, + Err(e) => return e, } let payload = match hex::decode(body) { Ok(v) => v, @@ -85,13 +75,9 @@ async fn sub_raw( body: String, ) -> Response { debug!(body = body); - match token { - Some(t) => { - if !state.config.lock().await.verify_token(&t) { - return (StatusCode::UNAUTHORIZED, "wrong token".to_string()).into_response() - } - }, - None => return (StatusCode::UNAUTHORIZED, "unauthorized".to_string()).into_response(), + match state.config.lock().await.clone().verify_token(&token) { + Ok(_) => {}, + Err(e) => return e, } let payload = match hex::decode(body) { Ok(v) => v, diff --git a/src/ws/mod.rs b/src/ws/mod.rs index 270230d..ace8544 100644 --- a/src/ws/mod.rs +++ b/src/ws/mod.rs @@ -5,4 +5,4 @@ mod http; pub use types::C2SMessage; pub use types::S2CMessage; pub use websocket::handler; -pub use http::router as http_router; \ No newline at end of file +pub use http::router as http2ws_router; \ No newline at end of file diff --git a/src/ws/websocket.rs b/src/ws/websocket.rs index 72fd068..e835f97 100644 --- a/src/ws/websocket.rs +++ b/src/ws/websocket.rs @@ -27,7 +27,6 @@ pub async fn handler(ws: WebSocketUpgrade, State(state): State) -> Res #[derive(Debug, Clone)] struct WSUser { username: String, - token: String, uuid: Uuid, } @@ -87,7 +86,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) { match state.user_manager.get(&token) { // The principle is simple: if there is no token in authenticated, then it's "dirty hacker" :D Some(t) => { //username = t.username.clone(); - owner = Some(WSUser { username: t.username.clone(), token, uuid: t.uuid }); + owner = Some(WSUser { username: t.username.clone(), uuid: t.uuid }); state.session.insert(t.uuid, mtx.clone()); msg = Message::Binary(S2CMessage::Auth.to_vec()); match state.broadcasts.get(&t.uuid) {