feat: super cheap hack to fallback to microsoft

This commit is contained in:
əlemi 2023-01-22 19:41:07 +01:00
parent 87e87811b3
commit be1ac67d16
No known key found for this signature in database
GPG key ID: BBCBFE5D7244634E
3 changed files with 38 additions and 7 deletions

View file

@ -10,6 +10,7 @@ clap = { version = "4", features = ["derive"] }
tokio = { version = "1.24.2", features = ["full"] }
sea-orm = { version = "0.10", features = [ "sqlx-postgres", "sqlx-sqlite", "runtime-tokio-rustls", "macros" ] }
axum = "0.6.2"
reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tracing-subscriber = "0.3"

View file

@ -16,7 +16,7 @@ use tracing::{info, metadata::LevelFilter};
use crate::routes::{
auth::{authenticate, validate, refresh},
session::{join, has_joined, profile},
session::{join, has_joined_wrapper, profile},
};
/// Reimplementation of legacy auth server for minecraft
@ -33,6 +33,10 @@ struct ConfigArgs {
/// Valid time for join requests, in seconds
#[arg(short, long, default_value_t = 10)]
time_window: u32,
/// Enable join request fallback to Microsoft
#[arg(long)]
fallback: bool,
}
#[derive(Clone)]
@ -76,14 +80,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.route("/auth/refresh", post(refresh)) //in: token out: refreshed token
// SESSION
.route("/session/minecraft/join", post(join))
.route("/session/minecraft/hasJoined", get(has_joined))
.route("/session/minecraft/hasJoined", get(has_joined_wrapper))
.route("/session/minecraft/profile/:user_id", get(profile))
// CUSTOM
.route("/register", post(register_tmp))
.fallback(fallback_route)
.with_state(AppState { store, db, cfg });
info!(target: "MAIN", "serving app...");
info!(target: "MAIN", "serving Yggdrasil on {}", &addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())

View file

@ -29,10 +29,36 @@ pub async fn join(State(state): State<AppState>, Json(payload): Json<proto::Join
}
}
pub async fn has_joined(State(state): State<AppState>, Query(query): Query<HashMap<String, String>>) -> Result<Json<proto::JoinResponse>, StatusCode> {
let username = query.get("username").unwrap().clone();
let server_id = query.get("serverId").unwrap();
info!(target: "SESSION", "[HAS_JOINED] called with user:{} server:{}", username, server_id);
pub async fn has_joined_wrapper(State(state): State<AppState>, Query(query): Query<HashMap<String, String>>) -> Result<Json<proto::JoinResponse>, StatusCode> {
let username = query.get("username").ok_or(StatusCode::UNPROCESSABLE_ENTITY)?;
let server_id = query.get("serverId").ok_or(StatusCode::UNPROCESSABLE_ENTITY)?;
let user_ip = query.get("ip");
match has_joined_local(&state, username, server_id, user_ip).await {
Ok(r) => Ok(r),
Err(e) => {
if state.cfg.fallback {
Ok(has_joined_microsoft(&state, username, server_id, user_ip).await?)
} else {
Err(e)
}
}
}
}
pub async fn has_joined_microsoft(_state: &AppState, username: &String, server_id: &String, _user_ip: Option<&String>) -> Result<Json<proto::JoinResponse>, StatusCode> {
Ok(
Json( // TODO don't do it with a format!!!
reqwest::get(format!("https://sessionserver.mojang.com/session/minecraft/hasJoined?username={}&serverId={}", username, server_id))
.await.map_err(|_| StatusCode::SERVICE_UNAVAILABLE)?
.json::<proto::JoinResponse>()
.await.map_err(|_| StatusCode::UNAUTHORIZED)?
)
)
}
pub async fn has_joined_local(state: &AppState, username: &String, server_id: &String, user_ip: Option<&String>) -> Result<Json<proto::JoinResponse>, StatusCode> {
info!(target: "SESSION", "[HAS_JOINED] called with user:{} server:{} ip:{:?}", username, server_id, user_ip);
let user = entities::user::Entity::find().filter(
entities::user::Column::Name.eq(username.clone())