feat: super cheap hack to fallback to microsoft
This commit is contained in:
parent
87e87811b3
commit
be1ac67d16
3 changed files with 38 additions and 7 deletions
|
@ -10,6 +10,7 @@ clap = { version = "4", features = ["derive"] }
|
||||||
tokio = { version = "1.24.2", features = ["full"] }
|
tokio = { version = "1.24.2", features = ["full"] }
|
||||||
sea-orm = { version = "0.10", features = [ "sqlx-postgres", "sqlx-sqlite", "runtime-tokio-rustls", "macros" ] }
|
sea-orm = { version = "0.10", features = [ "sqlx-postgres", "sqlx-sqlite", "runtime-tokio-rustls", "macros" ] }
|
||||||
axum = "0.6.2"
|
axum = "0.6.2"
|
||||||
|
reqwest = { version = "0.11", features = ["json"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
tracing-subscriber = "0.3"
|
tracing-subscriber = "0.3"
|
||||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -16,7 +16,7 @@ use tracing::{info, metadata::LevelFilter};
|
||||||
|
|
||||||
use crate::routes::{
|
use crate::routes::{
|
||||||
auth::{authenticate, validate, refresh},
|
auth::{authenticate, validate, refresh},
|
||||||
session::{join, has_joined, profile},
|
session::{join, has_joined_wrapper, profile},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Reimplementation of legacy auth server for minecraft
|
/// Reimplementation of legacy auth server for minecraft
|
||||||
|
@ -33,6 +33,10 @@ struct ConfigArgs {
|
||||||
/// 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,
|
||||||
|
|
||||||
|
/// Enable join request fallback to Microsoft
|
||||||
|
#[arg(long)]
|
||||||
|
fallback: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[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
|
.route("/auth/refresh", post(refresh)) //in: token out: refreshed token
|
||||||
// SESSION
|
// SESSION
|
||||||
.route("/session/minecraft/join", post(join))
|
.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))
|
.route("/session/minecraft/profile/:user_id", get(profile))
|
||||||
// CUSTOM
|
// CUSTOM
|
||||||
.route("/register", post(register_tmp))
|
.route("/register", post(register_tmp))
|
||||||
.fallback(fallback_route)
|
.fallback(fallback_route)
|
||||||
.with_state(AppState { store, db, cfg });
|
.with_state(AppState { store, db, cfg });
|
||||||
|
|
||||||
info!(target: "MAIN", "serving app...");
|
info!(target: "MAIN", "serving Yggdrasil on {}", &addr);
|
||||||
|
|
||||||
axum::Server::bind(&addr)
|
axum::Server::bind(&addr)
|
||||||
.serve(app.into_make_service())
|
.serve(app.into_make_service())
|
||||||
|
|
|
@ -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> {
|
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").unwrap().clone();
|
let username = query.get("username").ok_or(StatusCode::UNPROCESSABLE_ENTITY)?;
|
||||||
let server_id = query.get("serverId").unwrap();
|
let server_id = query.get("serverId").ok_or(StatusCode::UNPROCESSABLE_ENTITY)?;
|
||||||
info!(target: "SESSION", "[HAS_JOINED] called with user:{} server:{}", username, server_id);
|
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(
|
let user = entities::user::Entity::find().filter(
|
||||||
entities::user::Column::Name.eq(username.clone())
|
entities::user::Column::Name.eq(username.clone())
|
||||||
|
|
Loading…
Reference in a new issue