fix: add tracing, fix proto, small tweaks

Co-authored-by: zaaarf <zaaarf@proton.me>
This commit is contained in:
dev@ftbsc 2023-01-21 12:09:15 +01:00
parent 9a062cc7a8
commit 2cf80d2eaf
4 changed files with 53 additions and 35 deletions

View file

@ -15,3 +15,4 @@ serde_json = "1"
tracing-subscriber = "0.3" tracing-subscriber = "0.3"
uuid = "1" uuid = "1"
chrono = "0.4" chrono = "0.4"
tracing = "0.1"

View file

@ -1,10 +1,12 @@
# HOW TO USE # HOW TO USE
Add to java args (on client/server) Add to java args (on client/server)
``` ```
-Dminecraft.api.auth.host=http://localhost:8081/auth -Dminecraft.api.auth.host=https://ygddrasil.fantabos.co/auth
-Dminecraft.api.account.host=http://localhost:8081/account -Dminecraft.api.session.host=https://yggdrasil.fantabos.co
-Dminecraft.api.session.host=http://localhost:8081/session
-Dminecraft.api.services.host=http://localhost:8081/services -Dminecraft.api.account.host=http://yggdrasil.fantabos.co/account
-Dminecraft.api.services.host=http://yggdrasil.fantabos.co/services
``` ```
## TODO ## TODO

View file

@ -1,7 +1,7 @@
mod proto; mod proto;
mod entities; mod entities;
use std::{net::SocketAddr, collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
use chrono::{DateTime, Utc, Duration}; use chrono::{DateTime, Utc, Duration};
use clap::Parser; use clap::Parser;
@ -10,6 +10,9 @@ use proto::{Error, AuthenticateRequest, AuthenticateResponse, JoinRequest, JoinR
use sea_orm::{EntityTrait, QueryFilter, ColumnTrait, DatabaseConnection, Database, ActiveValue::NotSet, Set}; use sea_orm::{EntityTrait, QueryFilter, ColumnTrait, DatabaseConnection, Database, ActiveValue::NotSet, Set};
use tokio::sync::Mutex; use tokio::sync::Mutex;
use uuid::Uuid; use uuid::Uuid;
use tracing::{info, warn};
use crate::proto::Property;
/// Reimplementation of legacy auth server for minecraft /// Reimplementation of legacy auth server for minecraft
#[derive(Parser, Debug, Clone)] #[derive(Parser, Debug, Clone)]
@ -18,18 +21,13 @@ struct ConfigArgs {
/// Connection string for database /// Connection string for database
database: String, database: String,
// /// Listen address /// Address to bind web application onto
// #[arg(short, long, default_value_t = )] #[arg(short, long, default_value = "127.0.0.1:26656")]
// listen_addr: String, bind_addr: String,
/// Listen port
#[arg(short, long, default_value_t = 25556)]
listen_port: u16,
/// Valid time for join requests, in seconds /// Valid time for join requests, in seconds
#[arg(short, long, default_value_t = 10)] #[arg(short, long, default_value_t = 10)]
time_window: u32, time_window: u32,
} }
#[derive(Clone)] #[derive(Clone)]
@ -60,19 +58,21 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = Database::connect(cfg.database.clone()).await?; let db = Database::connect(cfg.database.clone()).await?;
let store = Arc::new(Mutex::new(HashMap::new())); let store = Arc::new(Mutex::new(HashMap::new()));
let addr = cfg.bind_addr.parse()?;
let app = Router::new() let app = Router::new()
.route("/", get(root)) .route("/auth/authenticate", post(authenticate)) //in: username, pass; out: token
.route("/authenticate", post(authenticate)) .route("/auth/validate", post(validate)) //in: token; out: boolean valid
.route("/validate", post(validate)) .route("/auth/refresh", post(refresh)) //in: token out: refreshed token
.route("/refresh", post(refresh))
// .route("/signout", post(signout)) // .route("/signout", post(signout))
// .route("/invalidate", post(invalidate)) // .route("/invalidate", post(invalidate))
.route("/join", post(join)) .route("/session/minecraft/join", post(join))
.route("/hasJoined", get(has_joined)) .route("/session/minecraft/hasJoined", get(has_joined))
.route("/register", post(register_tmp)) .route("/register", post(register_tmp))
.fallback(fallback_route)
.with_state(AppState { store, db, cfg }); .with_state(AppState { store, db, cfg });
let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); // TODO parse strings from CLI info!(target: "MAIN", "serving app...");
axum::Server::bind(&addr) axum::Server::bind(&addr)
.serve(app.into_make_service()) .serve(app.into_make_service())
@ -81,11 +81,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(()) Ok(())
} }
async fn root() -> impl IntoResponse { async fn fallback_route() -> impl IntoResponse {
let error = Error { let error = Error {
error: "No route specified".into(), error: "No valid route specified".into(),
errorMessage: "No route specified".into(), errorMessage: "No route requested or invalid route specified".into(),
cause: "No route specified".into(), cause: "Routing".into(),
}; };
(StatusCode::OK, Json(error)) (StatusCode::OK, Json(error))
@ -124,8 +124,8 @@ async fn refresh(State(state): State<AppState>, Json(payload): Json<RefreshReque
entities::token::ActiveModel{ entities::token::ActiveModel{
id: NotSet, id: NotSet,
access_token: Set(payload.accessToken.clone()), access_token: Set(payload.accessToken.clone()),
created_at: NotSet, created_at: Set(Utc::now()),
user_id: NotSet, user_id: Set(user.id),
} }
).exec(&state.db).await.unwrap(); ).exec(&state.db).await.unwrap();
Ok(Json( Ok(Json(
@ -179,7 +179,7 @@ async fn authenticate(State(state): State<AppState>, Json(payload): Json<Authent
async fn join(State(state): State<AppState>, Json(payload): Json<JoinRequest>) -> StatusCode { async fn join(State(state): State<AppState>, Json(payload): Json<JoinRequest>) -> StatusCode {
let user = entities::user::Entity::find().filter( let user = entities::user::Entity::find().filter(
entities::user::Column::Uuid.eq(payload.selectedProfile) entities::user::Column::Uuid.eq(payload.selectedProfile.id)
).one(&state.db).await.unwrap().unwrap(); ).one(&state.db).await.unwrap().unwrap();
let tokens = entities::token::Entity::find().filter( let tokens = entities::token::Entity::find().filter(
@ -187,9 +187,11 @@ async fn join(State(state): State<AppState>, Json(payload): Json<JoinRequest>) -
).all(&state.db).await.unwrap(); ).all(&state.db).await.unwrap();
if tokens.iter().any(|x| x.access_token == payload.accessToken) { if tokens.iter().any(|x| x.access_token == payload.accessToken) {
state.store.lock().await.insert(payload.selectedProfile, JoinAttempt::new(payload.serverId)); state.store.lock().await.insert(payload.selectedProfile.id, JoinAttempt::new(payload.serverId.clone()));
info!(target: "JOIN", "user {} has joined server {}", payload.selectedProfile.name, payload.serverId);
StatusCode::OK StatusCode::OK
} else { } else {
warn!(target: "JOIN", "user {} attempted to join server {} without a valid token", payload.selectedProfile.name, payload.serverId);
StatusCode::UNAUTHORIZED StatusCode::UNAUTHORIZED
} }
} }
@ -211,18 +213,31 @@ async fn has_joined(State(state): State<AppState>, Query(query): Query<HashMap<S
let response = JoinResponse { let response = JoinResponse {
id: user.uuid, id: user.uuid,
name: username.clone(), name: username.clone(),
properties: vec![], properties: vec![
Property {
name: "textures".into(),
value: "".into(),
signature: Some("".into()),
}
],
}; };
info!(target: "hasJOINED", "server found user -> {:?}", response);
Ok(Json(response)) Ok(Json(response))
} else { } else {
warn!(target: "hasJOINED", "server found user but join was late or for another server");
Err(StatusCode::NOT_FOUND) Err(StatusCode::NOT_FOUND)
} }
}, },
None => Err(StatusCode::NOT_FOUND), None => {
warn!(target: "hasJOINED", "server didn't find user");
Err(StatusCode::NOT_FOUND)
},
} }
}, },
None => Err(StatusCode::NOT_FOUND), None => {
warn!(target: "hasJOINED", "invalid UUID");
Err(StatusCode::NOT_FOUND)
},
} }
} }

View file

@ -16,7 +16,7 @@ pub struct Agent {
pub version: u32, pub version: u32,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Debug)]
pub struct Property { pub struct Property {
pub name: String, pub name: String,
pub value: String, pub value: String,
@ -88,11 +88,11 @@ pub struct SignoutRequest {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct JoinRequest { pub struct JoinRequest {
pub accessToken: String, pub accessToken: String,
pub selectedProfile: Uuid, pub selectedProfile: Profile,
pub serverId: String, pub serverId: String,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Debug)]
pub struct JoinResponse { pub struct JoinResponse {
pub id: Uuid, pub id: Uuid,
pub name: String, pub name: String,