Skip to content

Commit

Permalink
Merge pull request #3 from OpenXbox/feat/halo_waypoint_auth
Browse files Browse the repository at this point in the history
examples: Add Halo waypoint auth examples, add descriptions
  • Loading branch information
tuxuser committed Dec 21, 2023
2 parents 69232a3 + 66b3147 commit e56c3bc
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 9 deletions.
6 changes: 6 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ name = "auth_cli"
[[bin]]
name = "auth_azure"

[[bin]]
name = "auth_minecraft"

[[bin]]
name = "auth_halo"

[[bin]]
name = "xbl_signed_request"

Expand Down
6 changes: 4 additions & 2 deletions examples/src/bin/auth_azure.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Authenticating via custom Azure Client Id to Xbox Live
//!
use std::str::from_utf8;

use async_trait::async_trait;
Expand Down Expand Up @@ -56,6 +58,7 @@ impl AuthPromptCallback for HttpCallbackHandler {

#[tokio::main]
async fn main() -> Result<(), Error> {
eprintln!("NOTE: --flow authorization-code required!");
auth_main(
XalAppParameters {
app_id: "388ea51c-0b25-4029-aae2-17df49d23905".into(),
Expand All @@ -76,8 +79,7 @@ async fn main() -> Result<(), Error> {
redirect_url_base: "http://localhost:8080".into(),
},
)
.await
.ok();
.await?;

Ok(())
}
5 changes: 2 additions & 3 deletions examples/src/bin/auth_cli.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//! Authenticating by following instructions on the CLI
use xal::{AccessTokenPrefix, CliCallbackHandler, Error};
use xal_examples::auth_main_default;

#[tokio::main]
async fn main() -> Result<(), Error> {
auth_main_default(AccessTokenPrefix::None, CliCallbackHandler)
.await
.ok();
auth_main_default(AccessTokenPrefix::None, CliCallbackHandler).await?;

Ok(())
}
115 changes: 115 additions & 0 deletions examples/src/bin/auth_halo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//! Halo Waypoint authentication
//! - Acquiring Spartan token
//! - Acquiring flighting Id
//!
//! Reference:
//! Den Delimarsky, Halo Infinite Web API Authentication
//! Blog post: https://den.dev/blog/halo-api-authentication/
//!
use chrono::{DateTime, Utc};
use env_logger::Env;
use serde::Deserialize;
use serde_json::json;
use xal::{extensions::JsonExDeserializeMiddleware, Error, TokenStore, XalAuthenticator};

#[derive(Debug, Deserialize)]
pub struct SpartanTokenExpiry {
#[serde(rename = "ISO8601Date")]
pub iso8601_date: DateTime<Utc>,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct SpartanTokenResponse {
pub expires_utc: SpartanTokenExpiry,
pub spartan_token: String,
pub token_duration: String,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct FlightConfiguration {
pub flight_configuration_id: String,
}

#[tokio::main]
async fn main() -> Result<(), Error> {
env_logger::Builder::from_env(Env::default().default_filter_or("trace")).init();

// Load tokens from JSON
let token_store = TokenStore::load_from_file("tokens.json")?;

token_store
.user_token
.clone()
.ok_or(Error::GeneralError("No User token available".into()))?;
let xuid = token_store
.authorization_token
.clone()
.ok_or(Error::GeneralError("No XSTS token available".into()))?
.display_claims
.ok_or(Error::GeneralError("No DisplayClaims".into()))?
.xui
.first()
.ok_or(Error::GeneralError("No xui node".into()))?
.get("xid")
.ok_or(Error::GeneralError("No X(U)ID".into()))?
.to_owned();

let mut authenticator = XalAuthenticator::from(token_store.clone());
let xsts_halo_waypoint = authenticator
.get_xsts_token(
None,
None,
token_store.user_token.as_ref(),
"https://prod.xsts.halowaypoint.com/",
)
.await?;

let xsts_token = xsts_halo_waypoint.token;

let spartan_token_request = json!({
"Audience": "urn:343:s3:services",
"MinVersion": "4",
"Proof": [{
"Token": xsts_token,
"TokenType": "Xbox_XSTSv3"
}]
});

/* Halo stuff */
let client = reqwest::ClientBuilder::new().build()?;

// Fetch spartan token
let spartan_token = client
.post("https://settings.svc.halowaypoint.com/spartan-token")
.header(
"User-Agent",
"HaloWaypoint/2021112313511900 CFNetwork/1327.0.4 Darwin/21.2.0",
)
.header("Accept", "application/json")
.json(&spartan_token_request)
.send()
.await?
.json_ex::<SpartanTokenResponse>()
.await?;
println!("Spartan Token: {spartan_token:?}");

let clearance_url = format!("https://settings.svc.halowaypoint.com/oban/flight-configurations/titles/hi/audiences/RETAIL/players/xuid({xuid})/active?sandbox=UNUSED&build=210921.22.01.10.1706-0");
// Get halo clearance token
let flighting_config = client
.get(clearance_url)
.header(
"User-Agent",
"HaloWaypoint/2021112313511900 CFNetwork/1327.0.4 Darwin/21.2.0",
)
.header("Accept", "application/json")
.header("x-343-authorization-spartan", spartan_token.spartan_token)
.send()
.await?
.json_ex::<FlightConfiguration>()
.await?;
println!("Flighting: {flighting_config:?}");

Ok(())
}
2 changes: 2 additions & 0 deletions examples/src/bin/auth_minecraft.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Authenticating to Minecraft Bedrock as Nintendo-Switch-client
//!
use serde_json::json;
use xal::{
extensions::JsonExDeserializeMiddleware, oauth2::TokenResponse, AccessTokenPrefix,
Expand Down
4 changes: 1 addition & 3 deletions examples/src/bin/auth_webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,7 @@ async fn main() -> Result<(), Error> {
.to_owned(),
};

auth_main_default(AccessTokenPrefix::None, callback_handler)
.await
.ok();
auth_main_default(AccessTokenPrefix::None, callback_handler).await?;

Ok(())
}
6 changes: 5 additions & 1 deletion examples/src/bin/xbl_signed_request.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Sending a signed http request to XBL userpresence API
//!
use env_logger::Env;
use xal::{
cvlib::CorrelationVector,
Expand Down Expand Up @@ -39,8 +41,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.send()
.await?
.log()
.await?
.text()
.await?;

println!("{:?}", userpresence);
println!("{userpresence}");
Ok(())
}

0 comments on commit e56c3bc

Please sign in to comment.