Skip to content

Commit

Permalink
Extend documentation, fix code examples
Browse files Browse the repository at this point in the history
  • Loading branch information
tuxuser committed Dec 19, 2023
1 parent 9b3c8c3 commit deda4d3
Show file tree
Hide file tree
Showing 10 changed files with 533 additions and 205 deletions.
10 changes: 4 additions & 6 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,21 @@ env_logger = "0.10.1"
log = "0.4.20"
clap = { version = "4.4.8", features = ["derive"] }
chrono = "0.4.31"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
reqwest = { version = "0.11", features = ["json"] }

# Optional dependencies
tokio = { version = "1", features = ["full"], optional = true }
wry = { version = "0.34.2", optional = true }

[features]
webview = ["dep:wry"]
tokio = ["dep:tokio"]
webview = ["wry"]

[[bin]]
name = "auth_cli"
required-features = ["tokio"]

[[bin]]
name = "auth_azure"
required-features = ["tokio"]

[[bin]]
name = "auth_webview"
required-features = ["webview","tokio"]
required-features = ["webview"]
28 changes: 20 additions & 8 deletions examples/src/bin/auth_azure.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use std::str::from_utf8;

use async_trait::async_trait;
use tokio::{net::TcpListener, io::{AsyncReadExt, AsyncWriteExt}};
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::TcpListener,
};
use xal::{
client_params::CLIENT_ANDROID,
flows::{AuthPromptCallback, AuthPromptData},
oauth2::{RedirectUrl, Scope},
url::Url,
Error, client_params::CLIENT_ANDROID, Constants, XalAppParameters, oauth2::{Scope, RedirectUrl, ResourceOwnerUsername, ResourceOwnerPassword}, XalAuthenticator,
Error, XalAppParameters,
};
use xal_examples::auth_main;

Expand Down Expand Up @@ -40,10 +45,13 @@ impl AuthPromptCallback for HttpCallbackHandler {
let http_req = from_utf8(&buf)?;
println!("HTTP REQ: {http_req}");

let path = http_req.split(" ").nth(1).unwrap();
let path = http_req.split(' ').nth(1).unwrap();
println!("Path: {path}");

Ok(Some(Url::parse(&format!("{}{}", self.redirect_url_base, path))?))
Ok(Some(Url::parse(&format!(
"{}{}",
self.redirect_url_base, path
))?))
}
}

Expand All @@ -54,19 +62,23 @@ async fn main() -> Result<(), Error> {
app_id: "388ea51c-0b25-4029-aae2-17df49d23905".into(),
title_id: None,
auth_scopes: vec![
Scope::new("Xboxlive.signin".into()), Scope::new("Xboxlive.offline_access".into())
Scope::new("Xboxlive.signin".into()),
Scope::new("Xboxlive.offline_access".into()),
],
redirect_uri: Some(
RedirectUrl::new("http://localhost:8080/auth/callback".into()).unwrap(),
),
},
CLIENT_ANDROID(),
"RETAIL".into(),
Constants::RELYING_PARTY_XBOXLIVE.into(),
xal::AccessTokenPrefix::D,
HttpCallbackHandler {
bind_host: "127.0.0.1:8080".into(),
redirect_url_base: "http://localhost:8080".into(),
}
).await
},
)
.await
.ok();

Ok(())
}
9 changes: 5 additions & 4 deletions examples/src/bin/auth_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use xal_examples::auth_main_default;

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

Ok(())
}
67 changes: 67 additions & 0 deletions examples/src/bin/auth_minecraft.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use serde_json::json;
use xal::{
extensions::JsonExDeserializeMiddleware, flows, oauth2::TokenResponse, AccessTokenPrefix,
Error, XalAuthenticator,
};
use xal_examples::auth_main;

#[tokio::main]
async fn main() -> Result<(), Error> {
let app_params = xal::app_params::MC_BEDROCK_SWITCH();
let client_params = xal::client_params::CLIENT_NINTENDO();

let ts = auth_main(
app_params,
client_params,
"RETAIL".into(),
AccessTokenPrefix::None,
flows::CliCallbackHandler,
)
.await?;

let mut authenticator = XalAuthenticator::from(ts.clone());
let xsts_mc_services = authenticator
.get_xsts_token(
ts.device_token.as_ref(),
ts.title_token.as_ref(),
ts.user_token.as_ref(),
"rp://api.minecraftservices.com/",
)
.await?;

let identity_token = xsts_mc_services.authorization_header_value();
println!("identityToken: {identity_token}");

/* Minecraft stuff */
// Fetch minecraft token
let mc_token = reqwest::Client::new()
.post("https://api.minecraftservices.com/authentication/login_with_xbox")
.json(&json!({"identityToken": identity_token}))
.send()
.await?
.json_ex::<xal::oauth2::basic::BasicTokenResponse>()
.await?;
println!("MC: {mc_token:?}");

// Get minecraft entitlements
let entitlements = reqwest::Client::new()
.get("https://api.minecraftservices.com/entitlements/mcstore")
.bearer_auth(mc_token.access_token().secret())
.send()
.await?
.text()
.await?;
println!("Entitlements: {entitlements}");

// Get minecraft profile
let profile = reqwest::Client::new()
.get("https://api.minecraftservices.com/minecraft/profile")
.bearer_auth(mc_token.access_token().secret())
.send()
.await?
.text()
.await?;
println!("Profile: {profile}");

Ok(())
}
8 changes: 6 additions & 2 deletions examples/src/bin/auth_webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use wry::{
use xal::{
flows::{AuthPromptCallback, AuthPromptData},
url::Url,
Error, XalAuthenticator, AccessTokenPrefix,
AccessTokenPrefix, Error, XalAuthenticator,
};
use xal_examples::auth_main_default;

Expand Down Expand Up @@ -111,5 +111,9 @@ async fn main() -> Result<(), Error> {
.to_owned(),
};

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

Ok(())
}
40 changes: 21 additions & 19 deletions examples/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use clap::{Parser, ValueEnum};
use env_logger::Env;
use log::info;
use xal::{flows, Error, XalAppParameters, XalAuthenticator, XalClientParameters, AccessTokenPrefix, Constants};
use xal::{
flows, tokenstore::TokenStore, AccessTokenPrefix, Constants, Error, XalAppParameters,
XalAuthenticator, XalClientParameters,
};

/// Common cli arguments
#[derive(Parser, Debug)]
Expand Down Expand Up @@ -54,13 +57,12 @@ pub enum AuthFlow {

pub async fn auth_main_default(
access_token_prefix: AccessTokenPrefix,
auth_cb: impl flows::AuthPromptCallback
) -> Result<(), Error> {
auth_cb: impl flows::AuthPromptCallback,
) -> Result<TokenStore, Error> {
auth_main(
XalAppParameters::default(),
XalClientParameters::default(),
"RETAIL".to_owned(),
Constants::RELYING_PARTY_XBOXLIVE.into(),
access_token_prefix,
auth_cb,
)
Expand All @@ -72,31 +74,28 @@ pub async fn auth_main(
app_params: XalAppParameters,
client_params: XalClientParameters,
sandbox_id: String,
xsts_relying_party: String,
access_token_prefix: AccessTokenPrefix,
auth_cb: impl flows::AuthPromptCallback,
) -> Result<(), Error> {
) -> Result<TokenStore, Error> {
let args = handle_args();

let mut ts = match flows::try_refresh_tokens_from_file(&args.token_filepath).await {
let mut ts = match flows::try_refresh_live_tokens_from_file(&args.token_filepath).await {
Ok((mut authenticator, ts)) => {
info!("Tokens refreshed succesfully, proceeding with Xbox Live Authorization");
match args.flow {
AuthFlow::Sisu => {
info!("Authorize and gather rest of xbox live tokens via sisu");
flows::xbox_live_sisu_authorization_flow(
&mut authenticator, ts.live_token
)
.await?
},
flows::xbox_live_sisu_authorization_flow(&mut authenticator, ts.live_token)
.await?
}
_ => {
info!("Authorize Xbox Live the traditional way, via individual requests");
flows::xbox_live_authorization_traditional_flow(
&mut authenticator,
ts.live_token,
xsts_relying_party,
Constants::RELYING_PARTY_XBOXLIVE.into(),
access_token_prefix,
false
false,
)
.await?
}
Expand All @@ -108,9 +107,12 @@ pub async fn auth_main(

info!("Authentication via flow={:?}", args.flow);
let ts = match args.flow {
AuthFlow::Sisu => flows::xbox_live_sisu_full_flow(&mut authenticator, auth_cb).await?,
AuthFlow::Sisu => {
flows::xbox_live_sisu_full_flow(&mut authenticator, auth_cb).await?
}
AuthFlow::DeviceCode => {
flows::ms_device_code_flow(&mut authenticator, auth_cb, tokio::time::sleep).await?
flows::ms_device_code_flow(&mut authenticator, auth_cb, tokio::time::sleep)
.await?
}
AuthFlow::Implicit => {
flows::ms_authorization_flow(&mut authenticator, auth_cb, true).await?
Expand All @@ -129,18 +131,18 @@ pub async fn auth_main(
flows::xbox_live_authorization_traditional_flow(
&mut authenticator,
ts.live_token,
xsts_relying_party,
Constants::RELYING_PARTY_XBOXLIVE.into(),
access_token_prefix,
false,
)
.await?
},
}
}
}
};

ts.update_timestamp();
ts.save_to_file(&args.token_filepath)?;

Ok(())
Ok(ts)
}
Loading

0 comments on commit deda4d3

Please sign in to comment.