mirror of
https://github.com/shiroyashik/sculptor.git
synced 2025-12-06 13:01:12 +03:00
Added a feature to create temporary users
- Token verification simplified
This commit is contained in:
parent
4bd9a2ab2e
commit
7594e3d615
7 changed files with 60 additions and 45 deletions
38
src/auth.rs
38
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<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) {
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue