Skip to content

Commit

Permalink
Merge pull request #4 from OpenXbox/feat/client_secret
Browse files Browse the repository at this point in the history
XalAppParameters: Implement defining (optional) client_secret, rename app_id -> client_id
  • Loading branch information
tuxuser authored Dec 21, 2023
2 parents e56c3bc + b80861d commit f213221
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 33 deletions.
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

0 comments on commit f213221

Please sign in to comment.