Skip to content

Commit

Permalink
Added a feature to create temporary users
Browse files Browse the repository at this point in the history
- Token verification simplified
  • Loading branch information
shiroyashik committed Jun 18, 2024
1 parent 4bd9a2a commit 7594e3d
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 45 deletions.
38 changes: 29 additions & 9 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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 {
Expand Down Expand Up @@ -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) {
Expand All @@ -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.
Expand Down Expand Up @@ -126,6 +144,7 @@ where
// End Extractor

#[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum AuthSystem {
Internal,
ElyBy,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down
22 changes: 14 additions & 8 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,23 @@ 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
} 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()),
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion src/profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
32 changes: 9 additions & 23 deletions src/ws/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/ws/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
3 changes: 1 addition & 2 deletions src/ws/websocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 7594e3d

Please sign in to comment.