Added a feature to create temporary users

- Token verification simplified
This commit is contained in:
Shiroyasha 2024-06-18 16:01:23 +03:00
parent 4bd9a2ab2e
commit 7594e3d615
Signed by: shiroyashik
GPG key ID: E4953D3940D7860A
7 changed files with 60 additions and 45 deletions

View file

@ -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<AppState> {
.route("/verify", get(verify))
}
pub fn router_v1() -> Router<AppState> {
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<AppState>) -> Response {
pub async fn status(
Token(token): Token,
State(state): State<AppState>
) -> 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<AppState>) -> Respo
}
}
}
pub async fn create_user(
Token(token): Token,
State(state): State<AppState>,
Json(json): Json<Userinfo>
) -> 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<DashMap<Uuid, Userinfo>>,
}
#[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) {

View file

@ -14,16 +14,22 @@ pub struct Config {
}
impl Config {
pub fn verify_token(&self, suspicious: &str) -> bool {
pub fn verify_token(&self, suspicious: &Option<String>) -> Result<axum::response::Response, axum::response::Response> {
use axum::{http::StatusCode, response::IntoResponse};
match &self.token {
Some(t) => {
if t == suspicious {
true
Some(token) => {
match suspicious {
Some(suspicious) => {
if token == suspicious {
return Ok((StatusCode::OK, "ok".to_string()).into_response())
} else {
false
return Err((StatusCode::UNAUTHORIZED, "wrong token".to_string()).into_response())
}
},
None => false
None => return Err((StatusCode::UNAUTHORIZED, "unauthorized".to_string()).into_response())
}
},
None => return Err((StatusCode::LOCKED, "token doesnt defined".to_string()).into_response()),
}
}
}

View file

@ -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))

View file

@ -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,

View file

@ -27,15 +27,9 @@ async fn verify(
Token(token): Token,
State(state): State<AppState>,
) -> 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,

View file

@ -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;
pub use http::router as http2ws_router;

View file

@ -27,7 +27,6 @@ pub async fn handler(ws: WebSocketUpgrade, State(state): State<AppState>) -> 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) {