aboutsummaryrefslogtreecommitdiff
path: root/azalea-auth/src/sessionserver.rs
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2022-10-16 22:54:54 -0500
committerGitHub <noreply@github.com>2022-10-16 22:54:54 -0500
commit4cef62e8e4aa04e44048eb67e5091c12a73d2a09 (patch)
tree1c3b03bad262bdcab878cd42d445676290000bea /azalea-auth/src/sessionserver.rs
parent993914d175609e5d291e7caafc1983379642e7fe (diff)
downloadazalea-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.rs79
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,
+ })
+ }
+ }
+}