Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

examples: Add Halo waypoint auth examples, add descriptions #3

Merged
merged 3 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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(())
}