The system design has changed, but the refactor is not over.

In future commits, I will strive to maintain a consistent style.
This commit is contained in:
Shiroyasha 2024-07-01 03:43:06 +03:00
parent 7594e3d615
commit a1f9eba502
Signed by: shiroyashik
GPG key ID: E4953D3940D7860A
25 changed files with 410 additions and 367 deletions

161
src/api/figura/profile.rs Normal file
View file

@ -0,0 +1,161 @@
use anyhow_http::{http_error_ret, response::Result};
use axum::{
body::Bytes,
extract::{Path, State},
Json,
};
use tracing::debug;
use serde_json::{json, Value};
use tokio::{
fs,
io::{self, AsyncReadExt, BufWriter},
};
use uuid::Uuid;
use crate::{
auth::Token,
utils::{calculate_file_sha256, format_uuid, get_correct_array},
AppState,
};
use super::types::S2CMessage;
pub async fn user_info(
Path(uuid): Path<Uuid>,
State(state): State<AppState>,
) -> Json<Value> {
tracing::info!("Receiving profile information for {}", uuid);
let formatted_uuid = format_uuid(&uuid);
let avatar_file = format!("avatars/{}.moon", formatted_uuid);
let auth_system = match state.user_manager.get_by_uuid(&uuid) {
Some(d) => d.auth_system.to_string(),
None => return Json(json!("err")),
};
let mut user_info_response = json!({
"uuid": &formatted_uuid,
"rank": "default",
"equipped": [],
"lastUsed": "2024-05-11T22:20:48.884Z",
"equippedBadges": {
"special": [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]
},
"version": "0.1.4+1.20.1",
"banned": false,
"authSystem": auth_system
});
if let Some(settings) = state.config.lock().await.advanced_users.get(&formatted_uuid) {
let pride = get_correct_array(settings.get("pride").unwrap());
let special = get_correct_array(settings.get("special").unwrap());
let badges = user_info_response
.get_mut("equippedBadges")
.and_then(Value::as_object_mut)
.unwrap();
badges.append(
json!({
"special": special,
"pride": pride
})
.as_object_mut()
.unwrap(),
)
}
if fs::metadata(&avatar_file).await.is_ok() {
if let Some(equipped) = user_info_response
.get_mut("equipped")
.and_then(Value::as_array_mut)
{
match calculate_file_sha256(&avatar_file) {
Ok(hash) => equipped.push(json!({
"id": "avatar",
"owner": &formatted_uuid,
"hash": hash
})),
Err(_e) => {}
}
}
}
Json(user_info_response)
}
pub async fn download_avatar(Path(uuid): Path<Uuid>) -> Result<Vec<u8>> {
let uuid = format_uuid(&uuid);
tracing::info!("Requesting an avatar: {}", uuid);
let mut file = if let Ok(file) = fs::File::open(format!("avatars/{}.moon", uuid)).await {
file
} else {
http_error_ret!(NOT_FOUND, "Error! This avatar does not exist!");
};
let mut buffer = Vec::new();
file.read_to_end(&mut buffer).await?;
//match Body::from_file("avatars/74cf2ba3-f346-4dfe-b3b5-f453b9f5cc5e.moon").await {
// match Body::from_file(format!("avatars/{}.moon",uuid)).await {
// Ok(body) => Ok(Response::builder(StatusCode::Ok).body(body).build()),
// Err(e) => Err(e.into()),
// }
Ok(buffer)
}
pub async fn upload_avatar(
Token(token): Token,
State(state): State<AppState>,
body: Bytes,
) -> Result<String> {
let request_data = body;
let token = match token {
Some(t) => t,
None => http_error_ret!(UNAUTHORIZED, "Authentication error!"),
};
if let Some(user_info) = state.user_manager.get(&token) {
tracing::info!(
"{} ({}) trying to upload an avatar",
user_info.uuid,
user_info.username
);
let avatar_file = format!("avatars/{}.moon", user_info.uuid);
let mut file = BufWriter::new(fs::File::create(&avatar_file).await?);
io::copy(&mut request_data.as_ref(), &mut file).await?;
}
Ok("ok".to_string())
}
pub async fn equip_avatar(Token(token): Token, State(state): State<AppState>) -> String {
debug!("[API] S2C : Equip");
let uuid = state.user_manager.get(&token.unwrap()).unwrap().uuid;
if state
.broadcasts
.get(&uuid)
.unwrap()
.send(S2CMessage::Event(uuid).to_vec())
.is_err()
{
debug!("[WebSocket] Failed to send Event! Maybe there is no one to send")
// TODO: Put into Handler
};
"ok".to_string()
}
pub async fn delete_avatar(Token(token): Token, State(state): State<AppState>) -> Result<String> {
let token = match token {
Some(t) => t,
None => http_error_ret!(UNAUTHORIZED, "Authentication error!"),
};
if let Some(user_info) = state.user_manager.get(&token) {
tracing::info!(
"{} ({}) is trying to delete the avatar",
user_info.uuid,
user_info.username
);
let avatar_file = format!("avatars/{}.moon", user_info.uuid);
fs::remove_file(avatar_file).await?;
}
// let avatar_file = format!("avatars/{}.moon",user_info.uuid);
Ok("ok".to_string())
}