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"
uuid = "1"
chrono = "0.4"
tracing = "0.1"

View file

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

View file

@ -1,7 +1,7 @@
mod proto;
mod entities;
use std::{net::SocketAddr, collections::HashMap, sync::Arc};
use std::{collections::HashMap, sync::Arc};
use chrono::{DateTime, Utc, Duration};
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 tokio::sync::Mutex;
use uuid::Uuid;
use tracing::{info, warn};
use crate::proto::Property;
/// Reimplementation of legacy auth server for minecraft
#[derive(Parser, Debug, Clone)]
@ -18,18 +21,13 @@ struct ConfigArgs {
/// Connection string for database
database: String,
// /// Listen address
// #[arg(short, long, default_value_t = )]
// listen_addr: String,
/// Listen port
#[arg(short, long, default_value_t = 25556)]
listen_port: u16,
/// Address to bind web application onto
#[arg(short, long, default_value = "127.0.0.1:26656")]
bind_addr: String,
/// Valid time for join requests, in seconds
#[arg(short, long, default_value_t = 10)]
time_window: u32,
}
#[derive(Clone)]
@ -60,19 +58,21 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = Database::connect(cfg.database.clone()).await?;
let store = Arc::new(Mutex::new(HashMap::new()));
let addr = cfg.bind_addr.parse()?;
let app = Router::new()
.route("/", get(root))
.route("/authenticate", post(authenticate))
.route("/validate", post(validate))
.route("/refresh", post(refresh))
.route("/auth/authenticate", post(authenticate)) //in: username, pass; out: token
.route("/auth/validate", post(validate)) //in: token; out: boolean valid
.route("/auth/refresh", post(refresh)) //in: token out: refreshed token
// .route("/signout", post(signout))
// .route("/invalidate", post(invalidate))
.route("/join", post(join))
.route("/hasJoined", get(has_joined))
.route("/session/minecraft/join", post(join))
.route("/session/minecraft/hasJoined", get(has_joined))
.route("/register", post(register_tmp))
.fallback(fallback_route)
.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)
.serve(app.into_make_service())
@ -81,11 +81,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
async fn root() -> impl IntoResponse {
async fn fallback_route() -> impl IntoResponse {
let error = Error {
error: "No route specified".into(),
errorMessage: "No route specified".into(),
cause: "No route specified".into(),
error: "No valid route specified".into(),
errorMessage: "No route requested or invalid route specified".into(),
cause: "Routing".into(),
};
(StatusCode::OK, Json(error))
@ -124,8 +124,8 @@ async fn refresh(State(state): State<AppState>, Json(payload): Json<RefreshReque
entities::token::ActiveModel{
id: NotSet,
access_token: Set(payload.accessToken.clone()),
created_at: NotSet,
user_id: NotSet,
created_at: Set(Utc::now()),
user_id: Set(user.id),
}
).exec(&state.db).await.unwrap();
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 {
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();
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();
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
} else {
warn!(target: "JOIN", "user {} attempted to join server {} without a valid token", payload.selectedProfile.name, payload.serverId);
StatusCode::UNAUTHORIZED
}
}
@ -211,18 +213,31 @@ async fn has_joined(State(state): State<AppState>, Query(query): Query<HashMap<S
let response = JoinResponse {
id: user.uuid,
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))
} else {
warn!(target: "hasJOINED", "server found user but join was late or for another server");
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,
}
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Debug)]
pub struct Property {
pub name: String,
pub value: String,
@ -88,11 +88,11 @@ pub struct SignoutRequest {
#[derive(Serialize, Deserialize)]
pub struct JoinRequest {
pub accessToken: String,
pub selectedProfile: Uuid,
pub selectedProfile: Profile,
pub serverId: String,
}
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Debug)]
pub struct JoinResponse {
pub id: Uuid,
pub name: String,