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 crate::utils::*;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use axum::{
|
use axum::{
|
||||||
async_trait, debug_handler,
|
async_trait, debug_handler, extract::{FromRequestParts, Query, State}, http::{request::Parts, StatusCode}, response::{IntoResponse, Response}, routing::{get, post}, Json, Router
|
||||||
extract::{FromRequestParts, Query, State},
|
|
||||||
http::{request::Parts, StatusCode},
|
|
||||||
response::{IntoResponse, Response},
|
|
||||||
routing::get,
|
|
||||||
Router,
|
|
||||||
};
|
};
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use ring::digest::{self, digest};
|
use ring::digest::{self, digest};
|
||||||
|
|
@ -24,6 +19,11 @@ pub fn router() -> Router<AppState> {
|
||||||
.route("/verify", get(verify))
|
.route("/verify", get(verify))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn router_v1() -> Router<AppState> {
|
||||||
|
Router::new()
|
||||||
|
.route("/create", post(create_user))
|
||||||
|
}
|
||||||
|
|
||||||
// Web
|
// Web
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Id {
|
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 {
|
match token {
|
||||||
Some(token) => {
|
Some(token) => {
|
||||||
if state.user_manager.is_authenticated(&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
|
// Web End
|
||||||
|
|
||||||
// It's an extractor that pulls a token from the Header.
|
// It's an extractor that pulls a token from the Header.
|
||||||
|
|
@ -126,6 +144,7 @@ where
|
||||||
// End Extractor
|
// End Extractor
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum AuthSystem {
|
pub enum AuthSystem {
|
||||||
Internal,
|
Internal,
|
||||||
ElyBy,
|
ElyBy,
|
||||||
|
|
@ -233,7 +252,8 @@ pub struct UManager {
|
||||||
registered: Arc<DashMap<Uuid, Userinfo>>,
|
registered: Arc<DashMap<Uuid, Userinfo>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Userinfo {
|
pub struct Userinfo {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub uuid: Uuid,
|
pub uuid: Uuid,
|
||||||
|
|
@ -278,7 +298,7 @@ impl UManager {
|
||||||
pub fn is_authenticated(&self, token: &String) -> bool {
|
pub fn is_authenticated(&self, token: &String) -> bool {
|
||||||
self.authenticated.contains_key(token)
|
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)
|
self.registered.contains_key(uuid)
|
||||||
}
|
}
|
||||||
pub fn remove(&self, uuid: &Uuid) {
|
pub fn remove(&self, uuid: &Uuid) {
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,22 @@ pub struct Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
match &self.token {
|
||||||
Some(t) => {
|
Some(token) => {
|
||||||
if t == suspicious {
|
match suspicious {
|
||||||
true
|
Some(suspicious) => {
|
||||||
} else {
|
if token == suspicious {
|
||||||
false
|
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()
|
let api = Router::new()
|
||||||
.nest("//auth", api_auth::router())
|
.nest("//auth", api_auth::router())
|
||||||
.nest("/v1", ws::http_router())
|
.nest("/v1", v1)
|
||||||
.route("/limits", get(api_info::limits))
|
.route("/limits", get(api_info::limits))
|
||||||
.route("/version", get(api_info::version))
|
.route("/version", get(api_info::version))
|
||||||
.route("/motd", get(api_info::motd))
|
.route("/motd", get(api_info::motd))
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
Json,
|
Json,
|
||||||
};
|
};
|
||||||
use tracing::{debug, warn};
|
use tracing::debug;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
fs,
|
fs,
|
||||||
|
|
|
||||||
|
|
@ -27,15 +27,9 @@ async fn verify(
|
||||||
Token(token): Token,
|
Token(token): Token,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Response {
|
) -> Response {
|
||||||
match token {
|
state.config.lock().await.clone()
|
||||||
Some(t) => {
|
.verify_token(&token)
|
||||||
if !state.config.lock().await.verify_token(&t) {
|
.unwrap_or_else(|x| x)
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn raw(
|
async fn raw(
|
||||||
|
|
@ -45,13 +39,9 @@ async fn raw(
|
||||||
body: String,
|
body: String,
|
||||||
) -> Response {
|
) -> Response {
|
||||||
debug!(body = body);
|
debug!(body = body);
|
||||||
match token {
|
match state.config.lock().await.clone().verify_token(&token) {
|
||||||
Some(t) => {
|
Ok(_) => {},
|
||||||
if !state.config.lock().await.verify_token(&t) {
|
Err(e) => return e,
|
||||||
return (StatusCode::UNAUTHORIZED, "wrong token".to_string()).into_response()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => return (StatusCode::UNAUTHORIZED, "unauthorized".to_string()).into_response(),
|
|
||||||
}
|
}
|
||||||
let payload = match hex::decode(body) {
|
let payload = match hex::decode(body) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
|
|
@ -85,13 +75,9 @@ async fn sub_raw(
|
||||||
body: String,
|
body: String,
|
||||||
) -> Response {
|
) -> Response {
|
||||||
debug!(body = body);
|
debug!(body = body);
|
||||||
match token {
|
match state.config.lock().await.clone().verify_token(&token) {
|
||||||
Some(t) => {
|
Ok(_) => {},
|
||||||
if !state.config.lock().await.verify_token(&t) {
|
Err(e) => return e,
|
||||||
return (StatusCode::UNAUTHORIZED, "wrong token".to_string()).into_response()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => return (StatusCode::UNAUTHORIZED, "unauthorized".to_string()).into_response(),
|
|
||||||
}
|
}
|
||||||
let payload = match hex::decode(body) {
|
let payload = match hex::decode(body) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,4 @@ mod http;
|
||||||
pub use types::C2SMessage;
|
pub use types::C2SMessage;
|
||||||
pub use types::S2CMessage;
|
pub use types::S2CMessage;
|
||||||
pub use websocket::handler;
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
struct WSUser {
|
struct WSUser {
|
||||||
username: String,
|
username: String,
|
||||||
token: String,
|
|
||||||
uuid: Uuid,
|
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
|
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) => {
|
Some(t) => {
|
||||||
//username = t.username.clone();
|
//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());
|
state.session.insert(t.uuid, mtx.clone());
|
||||||
msg = Message::Binary(S2CMessage::Auth.to_vec());
|
msg = Message::Binary(S2CMessage::Auth.to_vec());
|
||||||
match state.broadcasts.get(&t.uuid) {
|
match state.broadcasts.get(&t.uuid) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue