1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00
azalea/azalea-auth/src/sessionserver.rs
mat 4cef62e8e4
Microsoft Authentication (#29)
* a

* try to do more work on auth signing (untested)

* well auth works when i remove the d= so

* auth stuff

* sessionserver stuff

* add auth in azalea-protocol/client

* caching*

refreshing microsoft auth tokens isn't implemented yet, also i haven't tested it

* how did i not notice that i had the code duplicated

* fix cache

* add refreshing msa token

* replace some printlns with log::trace

* auth works!

* Update main.rs

* fix clippy warnings
2022-10-16 22:54:54 -05:00

79 lines
2.4 KiB
Rust

//! Tell Mojang you're joining a multiplayer server.
//!
use serde::Deserialize;
use serde_json::json;
use thiserror::Error;
use uuid::Uuid;
#[derive(Debug, Error)]
pub enum SessionServerError {
#[error("Error sending HTTP request to sessionserver: {0}")]
HttpError(#[from] reqwest::Error),
#[error("Multiplayer is not enabled for this account")]
MultiplayerDisabled,
#[error("This account has been banned from multiplayer")]
Banned,
#[error("Unknown sessionserver error: {0}")]
Unknown(String),
#[error("Unexpected response from sessionserver (status code {status_code}): {body}")]
UnexpectedResponse { status_code: u16, body: String },
}
#[derive(Deserialize)]
pub struct ForbiddenError {
pub error: String,
pub path: String,
}
/// Tell Mojang's servers that you are going to join a multiplayer server,
/// which is required to join online-mode servers. The server ID is an empty
/// string.
pub async fn join(
access_token: &str,
public_key: &[u8],
private_key: &[u8],
uuid: &Uuid,
server_id: &str,
) -> Result<(), SessionServerError> {
let client = reqwest::Client::new();
let server_hash = azalea_crypto::hex_digest(&azalea_crypto::digest_data(
server_id.as_bytes(),
public_key,
private_key,
));
let mut encode_buffer = Uuid::encode_buffer();
let undashed_uuid = uuid.simple().encode_lower(&mut encode_buffer);
let data = json!({
"accessToken": access_token,
"selectedProfile": undashed_uuid,
"serverId": server_hash
});
println!("data: {:?}", data);
let res = client
.post("https://sessionserver.mojang.com/session/minecraft/join")
.json(&data)
.send()
.await?;
match res.status() {
reqwest::StatusCode::NO_CONTENT => Ok(()),
reqwest::StatusCode::FORBIDDEN => {
let forbidden = res.json::<ForbiddenError>().await?;
match forbidden.error.as_str() {
"InsufficientPrivilegesException" => Err(SessionServerError::MultiplayerDisabled),
"UserBannedException" => Err(SessionServerError::Banned),
_ => Err(SessionServerError::Unknown(forbidden.error)),
}
}
status_code => {
let body = res.text().await?;
Err(SessionServerError::UnexpectedResponse {
status_code: status_code.as_u16(),
body,
})
}
}
}