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

XalAppParameters: Implement defining (optional) client_secret, rename app_id -> client_id #4

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
12 changes: 8 additions & 4 deletions examples/src/bin/auth_azure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ use xal::{
};
use xal_examples::auth_main;

// Replace with your own Azure Client parameters
const CLIENT_ID: &'static str = "388ea51c-0b25-4029-aae2-17df49d23905";
const REDIRECT_URL: &'static str = "http://localhost:8080/auth/callback";
const CLIENT_SECRET: Option<&'static str> = None;

pub struct HttpCallbackHandler {
bind_host: String,
redirect_url_base: String,
Expand Down Expand Up @@ -61,15 +66,14 @@ async fn main() -> Result<(), Error> {
eprintln!("NOTE: --flow authorization-code required!");
auth_main(
XalAppParameters {
app_id: "388ea51c-0b25-4029-aae2-17df49d23905".into(),
client_id: CLIENT_ID.into(),
title_id: None,
auth_scopes: vec![
Scope::new("Xboxlive.signin".into()),
Scope::new("Xboxlive.offline_access".into()),
],
redirect_uri: Some(
RedirectUrl::new("http://localhost:8080/auth/callback".into()).unwrap(),
),
redirect_uri: Some(RedirectUrl::new(REDIRECT_URL.into()).unwrap()),
client_secret: CLIENT_SECRET.map(|x| x.to_string()),
},
CLIENT_ANDROID(),
"RETAIL".into(),
Expand Down
25 changes: 13 additions & 12 deletions src/authenticator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,10 +407,10 @@ impl XalAuthenticator {
/// Create an internal [`oauth2::Client`]
///
/// Refer to [`oauth2`] crate for it's usage
pub fn oauth_client(&self, client_secret: Option<ClientSecret>) -> Result<BasicClient, Error> {
pub fn oauth_client(&self) -> Result<BasicClient, Error> {
let client = OAuthClient::new(
ClientId::new(self.app_params.app_id.to_string()),
client_secret,
ClientId::new(self.app_params.client_id.to_string()),
self.app_params.client_secret.clone().map(ClientSecret::new),
AuthUrl::new(Constants::OAUTH20_AUTHORIZE_URL.to_string())?,
Some(TokenUrl::new(Constants::OAUTH20_TOKEN_URL.to_string())?),
)
Expand Down Expand Up @@ -438,13 +438,14 @@ impl XalAuthenticator {
/// # async fn demo_code() {
/// let mut authenticator = XalAuthenticator::new(
/// XalAppParameters {
/// app_id: "388ea51c-0b25-4029-aae2-17df49d23905".into(),
/// client_id: "388ea51c-0b25-4029-aae2-17df49d23905".into(),
/// title_id: None,
/// auth_scopes: vec![
/// Scope::new("Xboxlive.signin".into()),
/// Scope::new("Xboxlive.offline_access".into())
/// ],
/// redirect_uri: Some(RedirectUrl::new("https://login.live.com/oauth20_desktop.srf".into()).unwrap())
/// redirect_uri: Some(RedirectUrl::new("https://login.live.com/oauth20_desktop.srf".into()).unwrap()),
/// client_secret: None,
/// },
/// client_params::CLIENT_ANDROID(),
/// "RETAIL".into()
Expand All @@ -461,7 +462,7 @@ impl XalAuthenticator {
implicit_flow: bool,
) -> Result<(EndUserVerificationUrl, CsrfToken), Error> {
let client =
self.oauth_client(None)?
self.oauth_client()?
.set_redirect_uri(self.app_params.redirect_uri.clone().ok_or(
Error::InvalidRedirectUrl("Redirect URL was not provided".into()),
)?);
Expand Down Expand Up @@ -508,7 +509,7 @@ impl XalAuthenticator {
pub async fn initiate_device_code_auth(
&mut self,
) -> Result<StandardDeviceAuthorizationResponse, Error> {
self.oauth_client(None)?
self.oauth_client()?
.exchange_device_code()
.unwrap()
.add_scopes(self.app_params.auth_scopes.clone())
Expand Down Expand Up @@ -555,7 +556,7 @@ impl XalAuthenticator {
S: Fn(std::time::Duration) -> SF,
SF: std::future::Future<Output = ()>,
{
self.oauth_client(None)?
self.oauth_client()?
.exchange_device_access_token(device_auth_resp)
.request_async(&async_http_client, sleep_fn, None)
.await
Expand Down Expand Up @@ -592,7 +593,7 @@ impl XalAuthenticator {
authorization_code: AuthorizationCode,
code_verifier: Option<PkceCodeVerifier>,
) -> Result<response::WindowsLiveTokens, Error> {
let client = self.oauth_client(None)?;
let client = self.oauth_client()?;

let mut req = client.exchange_code(authorization_code);

Expand Down Expand Up @@ -656,7 +657,7 @@ impl XalAuthenticator {
T: serde::de::DeserializeOwned,
{
let resp = self
.oauth_client(None)?
.oauth_client()?
.exchange_refresh_token(refresh_token)
.add_scopes(scopes)
.request_async(&async_http_client)
Expand Down Expand Up @@ -791,7 +792,7 @@ impl XalAuthenticator {
))?;

let json_body = request::SisuAuthenticationRequest {
app_id: &self.app_params.app_id,
app_id: &self.app_params.client_id,
title_id: &title_id,
redirect_uri: self.app_params.redirect_uri.as_deref().ok_or(
Error::InvalidRedirectUrl("sisu_authenticate requires Redirect URL".to_string()),
Expand Down Expand Up @@ -892,7 +893,7 @@ impl XalAuthenticator {
) -> Result<response::SisuAuthorizationResponse, Error> {
let json_body = request::SisuAuthorizationRequest {
access_token: &format!("t={}", access_token.access_token().secret()),
app_id: &self.app_params.app_id,
app_id: &self.app_params.client_id,
device_token: &device_token.token,
sandbox: &self.sandbox_id.clone(),
site_name: "user.auth.xboxlive.com",
Expand Down
42 changes: 27 additions & 15 deletions src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,14 +506,16 @@ impl ToString for DeviceType {
/// Mandatory for XAL authentication flow
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct XalAppParameters {
/// App Id (For authorization/permission scope)
pub app_id: String,
/// App Title-Id (For TitleToken)
/// OAuth2 Client Id
pub client_id: String,
/// App Title-Id (Required for SISU auth flow, for TitleToken)
pub title_id: Option<String>,
/// Scopes
pub auth_scopes: Vec<Scope>,
/// Redirect Uri (For OAuth2 code response)
pub redirect_uri: Option<RedirectUrl>,
/// OAuth2 Client Secret
pub client_secret: Option<String>,
}

/// Application parameter constants
Expand Down Expand Up @@ -544,52 +546,56 @@ pub mod app_params {
/// Xbox Beta App
pub fn APP_XBOX_BETA() -> XalAppParameters {
XalAppParameters {
app_id: "000000004415494b".into(),
client_id: "000000004415494b".into(),
title_id: Some("177887386".into()),
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
// Originally "ms-xal-000000004415494b://auth"
redirect_uri: Some(
RedirectUrl::new(crate::Constants::OAUTH20_DESKTOP_REDIRECT_URL.into()).unwrap(),
),
client_secret: None,
}
}

/// Xbox App
pub fn APP_XBOX() -> XalAppParameters {
XalAppParameters {
app_id: "000000004c12ae6f".into(),
client_id: "000000004c12ae6f".into(),
title_id: Some("328178078".into()),
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
// Originally "ms-xal-000000004c12ae6f://auth"
redirect_uri: Some(
RedirectUrl::new(crate::Constants::OAUTH20_DESKTOP_REDIRECT_URL.into()).unwrap(),
),
client_secret: None,
}
}

/// Gamepass App
pub fn APP_GAMEPASS() -> XalAppParameters {
XalAppParameters {
app_id: "000000004c20a908".into(),
client_id: "000000004c20a908".into(),
title_id: Some("1016898439".into()),
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
// Originally "ms-xal-000000004c20a908://auth"
redirect_uri: Some(
RedirectUrl::new(crate::Constants::OAUTH20_DESKTOP_REDIRECT_URL.into()).unwrap(),
),
client_secret: None,
}
}

/// Gamepass Beta App
pub fn APP_GAMEPASS_BETA() -> XalAppParameters {
XalAppParameters {
app_id: "000000004c20a908".into(),
client_id: "000000004c20a908".into(),
title_id: Some("1016898439".into()),
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
// Originally "ms-xal-public-beta-000000004c20a908://auth"
redirect_uri: Some(
RedirectUrl::new(crate::Constants::OAUTH20_DESKTOP_REDIRECT_URL.into()).unwrap(),
),
client_secret: None,
}
}

Expand All @@ -598,86 +604,92 @@ pub mod app_params {
/// Uses default `oauth20_desktop.srf` redirect uri
pub fn APP_FAMILY_SETTINGS() -> XalAppParameters {
XalAppParameters {
app_id: "00000000482C8F49".into(),
client_id: "00000000482C8F49".into(),
title_id: Some("1618633878".into()),
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
redirect_uri: Some(
RedirectUrl::new(crate::Constants::OAUTH20_DESKTOP_REDIRECT_URL.into()).unwrap(),
),
client_secret: None,
}
}

/// Old Xbox App (non-sisu-flow)
pub fn APP_OLD_XBOX_APP() -> XalAppParameters {
XalAppParameters {
app_id: "0000000048093EE3".into(),
client_id: "0000000048093EE3".into(),
title_id: None,
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
redirect_uri: Some(
RedirectUrl::new(crate::Constants::OAUTH20_DESKTOP_REDIRECT_URL.into()).unwrap(),
),
client_secret: None,
}
}

/// Minecraft for Windows (JAVA)
pub fn MC_JAVA_WIN32() -> XalAppParameters {
XalAppParameters {
app_id: "00000000402b5328".into(),
client_id: "00000000402b5328".into(),
title_id: None,
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
redirect_uri: Some(
RedirectUrl::new(crate::Constants::OAUTH20_DESKTOP_REDIRECT_URL.into()).unwrap(),
),
client_secret: None,
}
}

/// Minecraft Bedrock (Nintendo Switch)
pub fn MC_BEDROCK_SWITCH() -> XalAppParameters {
XalAppParameters {
app_id: "00000000441cc96b".into(),
client_id: "00000000441cc96b".into(),
title_id: Some("2047319603".into()),
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
redirect_uri: Some(
RedirectUrl::new(crate::Constants::OAUTH20_DESKTOP_REDIRECT_URL.into()).unwrap(),
),
client_secret: None,
}
}

/// Minecraft Bedrock (Android)
pub fn MC_BEDROCK_ANDROID() -> XalAppParameters {
XalAppParameters {
app_id: "0000000048183522".into(),
client_id: "0000000048183522".into(),
title_id: Some("1739947436".into()),
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
redirect_uri: Some(
RedirectUrl::new(crate::Constants::OAUTH20_DESKTOP_REDIRECT_URL.into()).unwrap(),
),
client_secret: None,
}
}

/// Minecraft Bedrock (iOS)
pub fn MC_BEDROCK_IOS() -> XalAppParameters {
XalAppParameters {
app_id: "000000004c17c01a".into(),
client_id: "000000004c17c01a".into(),
title_id: Some("1810924247".into()),
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
redirect_uri: Some(
RedirectUrl::new(crate::Constants::OAUTH20_DESKTOP_REDIRECT_URL.into()).unwrap(),
),
client_secret: None,
}
}

/*
/// Minecraft Bedrock (Win32))
pub const MC_BEDROCK_WIN32: XalAppParameters = XalAppParameters {
app_id: "".into(),
client_id: "".into(),
title_id: "896928775".into(),
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
redirect_uri: None,
};

pub const MC_BEDROCK_PLAYSTATION: XalAppParameters = XalAppParameters {
app_id: "".into(),
client_id: "".into(),
title_id: "2044456598".into(),
auth_scopes: vec![Scope::new(Constants::SCOPE_SERVICE_USER_AUTH.to_string())],
redirect_uri: None,
Expand Down
4 changes: 2 additions & 2 deletions src/tokenstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,10 @@ mod tests {

#[test]
fn read_from_string() {
let tokens_str = r#"{"app_params":{"app_id":"00000000441cc96b","title_id":"42","auth_scopes":["service::user.auth.xboxlive.com::MBI_SSL"],"redirect_uri":"https://login.live.com/oauth20_desktop.srf"},"client_params":{"user_agent":"XAL","device_type":"NINTENDO","client_version":"0.0.0","query_display":"touch"},"sandbox_id":"RETAIL","live_token":{"access_token":"accessTokenABC","token_type":"bearer","expires_in":86400,"refresh_token":"refreshTokenABC","scope":"service::user.auth.xboxlive.com::MBI_SSL"}}"#;
let tokens_str = r#"{"app_params":{"client_id":"00000000441cc96b","title_id":"42","auth_scopes":["service::user.auth.xboxlive.com::MBI_SSL"],"redirect_uri":"https://login.live.com/oauth20_desktop.srf"},"client_params":{"user_agent":"XAL","device_type":"NINTENDO","client_version":"0.0.0","query_display":"touch"},"sandbox_id":"RETAIL","live_token":{"access_token":"accessTokenABC","token_type":"bearer","expires_in":86400,"refresh_token":"refreshTokenABC","scope":"service::user.auth.xboxlive.com::MBI_SSL"}}"#;
let ts = TokenStore::deserialize_from_string(tokens_str).unwrap();

assert_eq!(ts.app_params.app_id, "00000000441cc96b");
assert_eq!(ts.app_params.client_id, "00000000441cc96b");
assert_eq!(ts.app_params.title_id, Some("42".into()));
assert_eq!(
ts.app_params.auth_scopes.first().unwrap().as_str(),
Expand Down