diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2022-10-16 22:54:54 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-16 22:54:54 -0500 |
| commit | 4cef62e8e4aa04e44048eb67e5091c12a73d2a09 (patch) | |
| tree | 1c3b03bad262bdcab878cd42d445676290000bea /azalea-auth/src/sessionserver.rs | |
| parent | 993914d175609e5d291e7caafc1983379642e7fe (diff) | |
| download | azalea-drasl-4cef62e8e4aa04e44048eb67e5091c12a73d2a09.tar.xz | |
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
Diffstat (limited to 'azalea-auth/src/sessionserver.rs')
| -rw-r--r-- | azalea-auth/src/sessionserver.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/azalea-auth/src/sessionserver.rs b/azalea-auth/src/sessionserver.rs new file mode 100644 index 00000000..31857bc0 --- /dev/null +++ b/azalea-auth/src/sessionserver.rs @@ -0,0 +1,79 @@ +//! 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, + }) + } + } +} |
