mirror of
https://github.com/shiroyashik/sculptor.git
synced 2025-12-06 13:01:12 +03:00
The user system has been refactored
This commit is contained in:
parent
3d64d60b2b
commit
703a2727e7
6 changed files with 149 additions and 87 deletions
|
|
@ -44,13 +44,16 @@ motd = """
|
||||||
maxAvatarSize = 100000
|
maxAvatarSize = 100000
|
||||||
maxAvatars = 10
|
maxAvatars = 10
|
||||||
|
|
||||||
# Shiroyashik
|
|
||||||
[advancedUsers.66004548-4de5-49de-bade-9c3933d8eb97]
|
[advancedUsers.66004548-4de5-49de-bade-9c3933d8eb97]
|
||||||
|
username = "Shiroyashik"
|
||||||
|
authSystem = "elyby"
|
||||||
special = [0,0,0,1,0,0] # 6
|
special = [0,0,0,1,0,0] # 6
|
||||||
pride = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] # 25
|
pride = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] # 25
|
||||||
|
|
||||||
# Your nickname here
|
# Your nickname here
|
||||||
# [advancedUsers.your uuid here]
|
# [advancedUsers.your uuid here]
|
||||||
|
# username = "Bot"
|
||||||
|
# authSystem = "mojang" # can be: mojang, elyby, internal (cant be authenticated)
|
||||||
# special = [0,1,0,0,0,0] # and set badges what you want! :D
|
# special = [0,1,0,0,0,0] # and set badges what you want! :D
|
||||||
# pride = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
# pride = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
||||||
|
|
||||||
|
|
|
||||||
108
src/auth.rs
108
src/auth.rs
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::{str::FromStr, sync::Arc};
|
||||||
|
|
||||||
use crate::utils::*;
|
use crate::utils::*;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use axum::{
|
use axum::{
|
||||||
|
|
@ -8,6 +10,7 @@ use axum::{
|
||||||
routing::get,
|
routing::get,
|
||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
|
use dashmap::DashMap;
|
||||||
use ring::digest::{self, digest};
|
use ring::digest::{self, digest};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tracing::{debug, error, info, trace};
|
use tracing::{debug, error, info, trace};
|
||||||
|
|
@ -35,8 +38,8 @@ async fn id(
|
||||||
) -> String {
|
) -> String {
|
||||||
let server_id =
|
let server_id =
|
||||||
hex::encode(&digest(&digest::SHA1_FOR_LEGACY_USE_ONLY, &rand()).as_ref()[0..20]);
|
hex::encode(&digest(&digest::SHA1_FOR_LEGACY_USE_ONLY, &rand()).as_ref()[0..20]);
|
||||||
let state = state.pending;
|
let state = state.user_manager;
|
||||||
state.insert(server_id.clone(), query.username);
|
state.pending_insert(server_id.clone(), query.username);
|
||||||
server_id
|
server_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,7 +55,7 @@ async fn verify(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Response {
|
) -> Response {
|
||||||
let server_id = query.id.clone();
|
let server_id = query.id.clone();
|
||||||
let username = state.pending.remove(&server_id).unwrap().1; // TODO: Add error check
|
let username = state.user_manager.pending_remove(&server_id).unwrap().1; // TODO: Add error check
|
||||||
let userinfo = match has_joined(&server_id, &username).await {
|
let userinfo = match has_joined(&server_id, &username).await {
|
||||||
Ok(d) => d,
|
Ok(d) => d,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
@ -62,14 +65,15 @@ async fn verify(
|
||||||
};
|
};
|
||||||
if let Some((uuid, auth_system)) = userinfo {
|
if let Some((uuid, auth_system)) = userinfo {
|
||||||
info!("[Authentication] {username} logged in using {auth_system:?}");
|
info!("[Authentication] {username} logged in using {auth_system:?}");
|
||||||
let authenticated = state.authenticated;
|
let authenticated = state.user_manager;
|
||||||
authenticated.insert(
|
authenticated.insert(
|
||||||
uuid,
|
uuid,
|
||||||
server_id.clone(),
|
server_id.clone(),
|
||||||
crate::Userinfo {
|
Userinfo {
|
||||||
username,
|
username,
|
||||||
uuid,
|
uuid,
|
||||||
auth_system,
|
auth_system,
|
||||||
|
token: Some(server_id.clone()),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
(StatusCode::OK, server_id.to_string()).into_response()
|
(StatusCode::OK, server_id.to_string()).into_response()
|
||||||
|
|
@ -82,7 +86,7 @@ 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.authenticated.contains_token(&token) {
|
if state.user_manager.is_authenticated(&token) {
|
||||||
(StatusCode::OK, "ok".to_string()).into_response()
|
(StatusCode::OK, "ok".to_string()).into_response()
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -121,9 +125,9 @@ where
|
||||||
}
|
}
|
||||||
// End Extractor
|
// End Extractor
|
||||||
|
|
||||||
// Work with external APIs
|
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum AuthSystem {
|
pub enum AuthSystem {
|
||||||
|
Internal,
|
||||||
ElyBy,
|
ElyBy,
|
||||||
Mojang,
|
Mojang,
|
||||||
}
|
}
|
||||||
|
|
@ -131,21 +135,37 @@ pub enum AuthSystem {
|
||||||
impl ToString for AuthSystem {
|
impl ToString for AuthSystem {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
|
AuthSystem::Internal => String::from("internal"),
|
||||||
AuthSystem::ElyBy => String::from("elyby"),
|
AuthSystem::ElyBy => String::from("elyby"),
|
||||||
AuthSystem::Mojang => String::from("mojang"),
|
AuthSystem::Mojang => String::from("mojang"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for AuthSystem {
|
||||||
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s {
|
||||||
|
"internal" => Ok(Self::Internal),
|
||||||
|
"elyby" => Ok(Self::ElyBy),
|
||||||
|
"mojang" => Ok(Self::Mojang),
|
||||||
|
_ => Err(anyhow!("No auth system called: {s}"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AuthSystem {
|
impl AuthSystem {
|
||||||
fn get_url(&self) -> String {
|
fn get_url(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
|
AuthSystem::Internal => panic!("Can't get internal URL!"),
|
||||||
AuthSystem::ElyBy => String::from("http://minecraft.ely.by/session/hasJoined"),
|
AuthSystem::ElyBy => String::from("http://minecraft.ely.by/session/hasJoined"),
|
||||||
AuthSystem::Mojang => String::from("https://sessionserver.mojang.com/session/minecraft/hasJoined"),
|
AuthSystem::Mojang => String::from("https://sessionserver.mojang.com/session/minecraft/hasJoined"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Work with external APIs
|
||||||
/// Get UUID from JSON response
|
/// Get UUID from JSON response
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_id_json(json: &serde_json::Value) -> anyhow::Result<Uuid> {
|
fn get_id_json(json: &serde_json::Value) -> anyhow::Result<Uuid> {
|
||||||
|
|
@ -199,11 +219,71 @@ pub async fn has_joined(
|
||||||
} else {
|
} else {
|
||||||
panic!("Impossible error!")
|
panic!("Impossible error!")
|
||||||
}
|
}
|
||||||
// FOR DELETE
|
|
||||||
// tokio::select! {
|
|
||||||
// Ok(res) = tokio::spawn(fetch_json(AuthSystem::ElyBy, server_id, username)) => {Ok(res)},
|
|
||||||
// Ok(res) = tokio::spawn(fetch_json(AuthSystem::Mojang, server_id, username)) => {Ok(res)},
|
|
||||||
// else => {Err(anyhow!("Something went wrong in external apis request process"))}
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
// End of work with external APIs
|
// End of work with external APIs
|
||||||
|
|
||||||
|
// User manager
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct UManager {
|
||||||
|
/// Users with incomplete authentication
|
||||||
|
pending: Arc<DashMap<String, String>>, // <SHA1 serverId, USERNAME> TODO: Add automatic purge
|
||||||
|
/// Authenticated users
|
||||||
|
authenticated: Arc<DashMap<String, Uuid>>, // <SHA1 serverId, Userinfo> NOTE: In the future, try it in a separate LockRw branch
|
||||||
|
/// Registered users
|
||||||
|
registered: Arc<DashMap<Uuid, Userinfo>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Userinfo {
|
||||||
|
pub username: String,
|
||||||
|
pub uuid: Uuid,
|
||||||
|
pub auth_system: AuthSystem,
|
||||||
|
pub token: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UManager {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
pending: Arc::new(DashMap::new()),
|
||||||
|
registered: Arc::new(DashMap::new()),
|
||||||
|
authenticated: Arc::new(DashMap::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn pending_insert(&self, server_id: String, username: String) {
|
||||||
|
self.pending.insert(server_id, username);
|
||||||
|
}
|
||||||
|
pub fn pending_remove(&self, server_id: &str) -> std::option::Option<(std::string::String, std::string::String)> {
|
||||||
|
self.pending.remove(server_id)
|
||||||
|
}
|
||||||
|
pub fn insert(&self, uuid: Uuid, token: String, userinfo: Userinfo) -> Option<Userinfo> {
|
||||||
|
self.authenticated.insert(token, uuid);
|
||||||
|
self.registered.insert(uuid, userinfo)
|
||||||
|
}
|
||||||
|
pub fn insert_user(&self, uuid: Uuid, userinfo: Userinfo) -> Option<Userinfo> {
|
||||||
|
self.registered.insert(uuid, userinfo)
|
||||||
|
}
|
||||||
|
pub fn get(
|
||||||
|
&self,
|
||||||
|
token: &String,
|
||||||
|
) -> Option<dashmap::mapref::one::Ref<'_, Uuid, Userinfo>> {
|
||||||
|
let uuid = self.authenticated.get(token)?;
|
||||||
|
self.registered.get(uuid.value())
|
||||||
|
}
|
||||||
|
pub fn get_by_uuid(
|
||||||
|
&self,
|
||||||
|
uuid: &Uuid,
|
||||||
|
) -> Option<dashmap::mapref::one::Ref<'_, Uuid, Userinfo>> {
|
||||||
|
self.registered.get(uuid)
|
||||||
|
}
|
||||||
|
pub fn is_authenticated(&self, token: &String) -> bool {
|
||||||
|
self.authenticated.contains_key(token)
|
||||||
|
}
|
||||||
|
pub fn is_registered(&self, uuid: &Uuid) -> bool {
|
||||||
|
self.registered.contains_key(uuid)
|
||||||
|
}
|
||||||
|
pub fn remove(&self, uuid: &Uuid) {
|
||||||
|
let token = self.registered.remove(uuid).unwrap().1.token.unwrap();
|
||||||
|
self.authenticated.remove(&token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// End of User manager
|
||||||
81
src/main.rs
81
src/main.rs
|
|
@ -3,6 +3,7 @@ use axum::{
|
||||||
extract::DefaultBodyLimit, middleware::from_extractor, routing::{delete, get, post, put}, Router
|
extract::DefaultBodyLimit, middleware::from_extractor, routing::{delete, get, post, put}, Router
|
||||||
};
|
};
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
|
use utils::collect_advanced_users;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::{broadcast, Mutex};
|
use tokio::sync::{broadcast, Mutex};
|
||||||
use tower_http::trace::TraceLayer;
|
use tower_http::trace::TraceLayer;
|
||||||
|
|
@ -15,7 +16,7 @@ use ws::handler;
|
||||||
|
|
||||||
// API: Auth
|
// API: Auth
|
||||||
mod auth;
|
mod auth;
|
||||||
use auth as api_auth;
|
use auth::{self as api_auth, UManager};
|
||||||
|
|
||||||
// API: Server info
|
// API: Server info
|
||||||
mod info;
|
mod info;
|
||||||
|
|
@ -31,64 +32,17 @@ mod utils;
|
||||||
// Config
|
// Config
|
||||||
mod config;
|
mod config;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Userinfo {
|
|
||||||
username: String,
|
|
||||||
uuid: Uuid,
|
|
||||||
auth_system: api_auth::AuthSystem,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
struct Authenticated {
|
|
||||||
user_data: DashMap<String, Userinfo>,
|
|
||||||
uuid: DashMap<Uuid, String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Authenticated {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
user_data: DashMap::new(),
|
|
||||||
uuid: DashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn insert(&self, uuid: Uuid, token: String, userinfo: Userinfo) -> Option<Userinfo> {
|
|
||||||
self.uuid.insert(uuid, token.clone());
|
|
||||||
self.user_data.insert(token, userinfo)
|
|
||||||
}
|
|
||||||
pub fn get(
|
|
||||||
&self,
|
|
||||||
token: &String,
|
|
||||||
) -> Option<dashmap::mapref::one::Ref<'_, std::string::String, Userinfo>> {
|
|
||||||
self.user_data.get(token)
|
|
||||||
}
|
|
||||||
pub fn get_by_uuid(
|
|
||||||
&self,
|
|
||||||
uuid: &Uuid,
|
|
||||||
) -> Option<dashmap::mapref::one::Ref<'_, std::string::String, Userinfo>> {
|
|
||||||
if let Some(token) = self.uuid.get(uuid) {
|
|
||||||
self.user_data.get(&token.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn contains_token(&self, token: &String) -> bool {
|
|
||||||
self.user_data.contains_key(token)
|
|
||||||
}
|
|
||||||
pub fn remove(&self, uuid: &Uuid) {
|
|
||||||
let token = self.uuid.remove(uuid).unwrap().1;
|
|
||||||
self.user_data.remove(&token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
// Users with incomplete authentication
|
/// Users with incomplete authentication
|
||||||
pending: Arc<DashMap<String, String>>, // <SHA1 serverId, USERNAME>
|
//pending: Arc<DashMap<String, String>>, // <SHA1 serverId, USERNAME>
|
||||||
// Authenticated users
|
/// Authenticated users
|
||||||
authenticated: Arc<Authenticated>, // <SHA1 serverId, Userinfo> NOTE: In the future, try it in a separate LockRw branch
|
//authenticated: Arc<Authenticated>, // <SHA1 serverId, Userinfo> NOTE: In the future, try it in a separate LockRw branch
|
||||||
// Ping broadcasts for WebSocket connections
|
/// User manager
|
||||||
|
user_manager: Arc<UManager>,
|
||||||
|
/// Ping broadcasts for WebSocket connections
|
||||||
broadcasts: Arc<DashMap<Uuid, broadcast::Sender<Vec<u8>>>>,
|
broadcasts: Arc<DashMap<Uuid, broadcast::Sender<Vec<u8>>>>,
|
||||||
// Current configuration
|
/// Current configuration
|
||||||
config: Arc<Mutex<config::Config>>,
|
config: Arc<Mutex<config::Config>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,25 +71,32 @@ async fn main() -> Result<()> {
|
||||||
|
|
||||||
// State
|
// State
|
||||||
let state = AppState {
|
let state = AppState {
|
||||||
pending: Arc::new(DashMap::new()),
|
user_manager: Arc::new(UManager::new()),
|
||||||
authenticated: Arc::new(Authenticated::new()),
|
|
||||||
broadcasts: Arc::new(DashMap::new()),
|
broadcasts: Arc::new(DashMap::new()),
|
||||||
config: config,
|
config: config,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Automatic update of configuration while the server is running
|
// Automatic update of configuration while the server is running
|
||||||
let config_update = state.config.clone();
|
let config_update = state.config.clone();
|
||||||
|
let user_manager = Arc::clone(&state.user_manager);
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
|
|
||||||
|
|
||||||
let new_config = config::Config::parse(config_file.clone().into());
|
let new_config = config::Config::parse(config_file.clone().into());
|
||||||
let mut config = config_update.lock().await;
|
let mut config = config_update.lock().await;
|
||||||
|
|
||||||
if new_config != *config {
|
if new_config != *config {
|
||||||
info!("Server configuration modification detected!");
|
info!("Server configuration modification detected!");
|
||||||
*config = new_config;
|
*config = new_config;
|
||||||
|
// let collected = collect_advanced_users(&config.advanced_users);
|
||||||
|
// for (uuid, userinfo) in collected {
|
||||||
|
// user_manager.insert_user(uuid, userinfo);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
let collected = collect_advanced_users(&config.advanced_users);
|
||||||
|
for (uuid, userinfo) in collected {
|
||||||
|
user_manager.insert_user(uuid, userinfo);
|
||||||
|
}
|
||||||
|
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ pub async fn user_info(
|
||||||
|
|
||||||
let avatar_file = format!("avatars/{}.moon", formatted_uuid);
|
let avatar_file = format!("avatars/{}.moon", formatted_uuid);
|
||||||
|
|
||||||
let auth_system = match state.authenticated.get_by_uuid(&uuid) {
|
let auth_system = match state.user_manager.get_by_uuid(&uuid) {
|
||||||
Some(d) => d.auth_system.to_string(),
|
Some(d) => d.auth_system.to_string(),
|
||||||
None => return Json(json!("err")),
|
None => return Json(json!("err")),
|
||||||
};
|
};
|
||||||
|
|
@ -113,7 +113,7 @@ pub async fn upload_avatar(
|
||||||
None => http_error_ret!(UNAUTHORIZED, "Authentication error!"),
|
None => http_error_ret!(UNAUTHORIZED, "Authentication error!"),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(user_info) = state.authenticated.get(&token) {
|
if let Some(user_info) = state.user_manager.get(&token) {
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
"{} ({}) trying to upload an avatar",
|
"{} ({}) trying to upload an avatar",
|
||||||
user_info.uuid,
|
user_info.uuid,
|
||||||
|
|
@ -128,7 +128,7 @@ pub async fn upload_avatar(
|
||||||
|
|
||||||
pub async fn equip_avatar(Token(token): Token, State(state): State<AppState>) -> String {
|
pub async fn equip_avatar(Token(token): Token, State(state): State<AppState>) -> String {
|
||||||
debug!("[API] S2C : Equip");
|
debug!("[API] S2C : Equip");
|
||||||
let uuid = state.authenticated.get(&token.unwrap()).unwrap().uuid;
|
let uuid = state.user_manager.get(&token.unwrap()).unwrap().uuid;
|
||||||
if state
|
if state
|
||||||
.broadcasts
|
.broadcasts
|
||||||
.get(&uuid)
|
.get(&uuid)
|
||||||
|
|
@ -147,7 +147,7 @@ pub async fn delete_avatar(Token(token): Token, State(state): State<AppState>) -
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
None => http_error_ret!(UNAUTHORIZED, "Authentication error!"),
|
None => http_error_ret!(UNAUTHORIZED, "Authentication error!"),
|
||||||
};
|
};
|
||||||
if let Some(user_info) = state.authenticated.get(&token) {
|
if let Some(user_info) = state.user_manager.get(&token) {
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
"{} ({}) is trying to delete the avatar",
|
"{} ({}) is trying to delete the avatar",
|
||||||
user_info.uuid,
|
user_info.uuid,
|
||||||
|
|
|
||||||
20
src/utils.rs
20
src/utils.rs
|
|
@ -1,10 +1,12 @@
|
||||||
use std::{fs::File, io::Read};
|
use std::{fs::File, io::Read, str::FromStr};
|
||||||
|
|
||||||
use base64::prelude::*;
|
use base64::prelude::*;
|
||||||
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
||||||
use ring::digest::{self, digest};
|
use ring::digest::{self, digest};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use crate::auth::{AuthSystem, Userinfo};
|
||||||
|
|
||||||
// Core functions
|
// Core functions
|
||||||
pub fn rand() -> [u8; 50] {
|
pub fn rand() -> [u8; 50] {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
|
|
@ -34,6 +36,22 @@ pub fn get_correct_array(value: &toml::Value) -> Vec<u8> {
|
||||||
.map(move |x| x.as_integer().unwrap() as u8)
|
.map(move |x| x.as_integer().unwrap() as u8)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
pub fn collect_advanced_users(value: &toml::Table) -> Vec<(Uuid, Userinfo)> {
|
||||||
|
value
|
||||||
|
.iter()
|
||||||
|
.map( |(uuid, userdata)| {
|
||||||
|
let auth_system = AuthSystem::from_str(userdata.as_table().unwrap().get("authSystem").expect("Can't find authSystem in advancedUser!").as_str().unwrap()).unwrap();
|
||||||
|
let username = userdata.as_table().unwrap().get("username").expect("Can't find username in advancedUser!").as_str().unwrap().to_string();
|
||||||
|
(
|
||||||
|
Uuid::parse_str(uuid).unwrap(),
|
||||||
|
Userinfo { username,
|
||||||
|
uuid: Uuid::parse_str(uuid).unwrap(),
|
||||||
|
auth_system,
|
||||||
|
token: None
|
||||||
|
}
|
||||||
|
)})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn format_uuid(uuid: &Uuid) -> String {
|
pub fn format_uuid(uuid: &Uuid) -> String {
|
||||||
// let uuid = Uuid::parse_str(&uuid)?; TODO: Вероятно format_uuid стоит убрать
|
// let uuid = Uuid::parse_str(&uuid)?; TODO: Вероятно format_uuid стоит убрать
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
||||||
info!("[WebSocket{}] Connection successfully closed!", owner.name());
|
info!("[WebSocket{}] Connection successfully closed!", owner.name());
|
||||||
if let Some(u) = owner.0 {
|
if let Some(u) = owner.0 {
|
||||||
state.broadcasts.remove(&u.uuid);
|
state.broadcasts.remove(&u.uuid);
|
||||||
state.authenticated.remove(&u.uuid);
|
state.user_manager.remove(&u.uuid);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +68,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
||||||
debug!("[WebSocket{}] Receive error! Connection terminated!", owner.name());
|
debug!("[WebSocket{}] Receive error! Connection terminated!", owner.name());
|
||||||
if let Some(u) = owner.0 {
|
if let Some(u) = owner.0 {
|
||||||
state.broadcasts.remove(&u.uuid);
|
state.broadcasts.remove(&u.uuid);
|
||||||
state.authenticated.remove(&u.uuid);
|
state.user_manager.remove(&u.uuid);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -82,7 +82,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
||||||
error!("[WebSocket{}] This message is not from Figura! {e:?}", owner.name());
|
error!("[WebSocket{}] This message is not from Figura! {e:?}", owner.name());
|
||||||
if let Some(u) = owner.0 {
|
if let Some(u) = owner.0 {
|
||||||
state.broadcasts.remove(&u.uuid);
|
state.broadcasts.remove(&u.uuid);
|
||||||
state.authenticated.remove(&u.uuid);
|
state.user_manager.remove(&u.uuid);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
|
@ -94,7 +94,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
||||||
C2SMessage::Token(token) => {
|
C2SMessage::Token(token) => {
|
||||||
debug!("[WebSocket{}] C2S : Token", owner.name());
|
debug!("[WebSocket{}] C2S : Token", owner.name());
|
||||||
let token = String::from_utf8(token.to_vec()).unwrap();
|
let token = String::from_utf8(token.to_vec()).unwrap();
|
||||||
match state.authenticated.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.0 = Some(WSUser { username: t.username.clone(), token, uuid: t.uuid });
|
owner.0 = Some(WSUser { username: t.username.clone(), token, uuid: t.uuid });
|
||||||
|
|
@ -115,7 +115,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
||||||
debug!("[WebSocket] Tried to log in with {token}"); // Tried to log in with token: {token}
|
debug!("[WebSocket] Tried to log in with {token}"); // Tried to log in with token: {token}
|
||||||
if let Some(u) = owner.0 {
|
if let Some(u) = owner.0 {
|
||||||
state.broadcasts.remove(&u.uuid);
|
state.broadcasts.remove(&u.uuid);
|
||||||
state.authenticated.remove(&u.uuid);
|
state.user_manager.remove(&u.uuid);
|
||||||
}
|
}
|
||||||
return; // TODO: Define the trip code
|
return; // TODO: Define the trip code
|
||||||
},
|
},
|
||||||
|
|
@ -170,7 +170,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
||||||
warn!("[WebSocket{}] Send error! Connection terminated!", owner.name());
|
warn!("[WebSocket{}] Send error! Connection terminated!", owner.name());
|
||||||
if let Some(u) = owner.0 {
|
if let Some(u) = owner.0 {
|
||||||
state.broadcasts.remove(&u.uuid);
|
state.broadcasts.remove(&u.uuid);
|
||||||
state.authenticated.remove(&u.uuid);
|
state.user_manager.remove(&u.uuid);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -184,7 +184,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
||||||
warn!("[WebSocketSubscriber{}] Send error! Connection terminated!", owner.name());
|
warn!("[WebSocketSubscriber{}] Send error! Connection terminated!", owner.name());
|
||||||
if let Some(u) = owner.0 {
|
if let Some(u) = owner.0 {
|
||||||
state.broadcasts.remove(&u.uuid);
|
state.broadcasts.remove(&u.uuid);
|
||||||
state.authenticated.remove(&u.uuid);
|
state.user_manager.remove(&u.uuid);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue