Added device_id, access_token and account_id fetcher.

This commit is contained in:
Marta Borgia Leiva 2024-12-18 00:14:49 +01:00
parent 2d6c8a186b
commit b9bc170013
3 changed files with 260 additions and 3 deletions

193
src/auth.rs Normal file
View file

@ -0,0 +1,193 @@
use reqwest::blocking::*;
use log::*;
use serde::Deserialize;
const OAUTH_TOKEN : (&str, &str)= (
"3f69e56c7649492c8cc29f1af08a8a12", // Client
"b51ee9cb12234f50a69efa67ef53812e", // Secret
);
#[derive(Debug)]
pub struct DeviceCredentials {
access_token : String,
account_id : String,
device_id : String,
}
impl DeviceCredentials {
pub fn new() -> DeviceCredentials {
DeviceCredentials{
device_id: String::new(),
account_id: String::new(),
access_token: String::new(),
}
}
pub fn get_access_token_and_account_id(&mut self, http_client: &Client, authcode: &str) {
if authcode.is_empty() {
error!("Authentication Code cannot be empty");
return;
}
#[derive(Debug, Deserialize)]
struct ResponseStruct {
access_token: String,
expires_in: u16,
expires_at: String,
token_type: String,
refresh_token: String,
refresh_expires: u16,
refresh_expires_at: String,
account_id: String,
client_id: String,
internal_client: bool,
client_service: String,
scope: Vec<String>,
displayName: String,
app: String,
in_app_id: String,
product_id: String,
application_id: String,
acr: String,
auth_time: String
}
let url = "https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token";
let mut req_body: String = String::from("grant_type=authorization_code&code=").trim().to_string();
req_body.push_str(authcode.trim());
let response = Client::post(&http_client, url)
.body(req_body)
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Authorization",
"Basic M2Y2OWU1NmM3NjQ5NDkyYzhjYzI5ZjFhZjA4YThhMTI6YjUxZWU5Y2IxMjIzNGY1MGE2OWVmYTY3ZWY1MzgxMmU=")
.send();
match response {
Ok(response_data) => {
match response_data.json::<ResponseStruct>().ok() {
Some(response) => {
self.access_token = response.access_token;
self.account_id = response.account_id;
},
None => {
error!("Failed to get access_token!");
}
}
},
_ => { error!("Failed to get access token!"); },
}
}
pub fn get_device_auth(&mut self, http_client: &Client) {
if self.access_token.is_empty() || self.account_id.is_empty() {
error!("Device access token cannot be empty!");
return;
}
let mut url : String = String::from("https://account-public-service-prod.ol.epicgames.com/account/api/public/account/");
url.push_str(self.account_id.as_str());
url.push_str("/deviceAuth");
/*
let it : String = String::new;
it.starts_with("one thing");
// Just discovered String.starts_with() KEKW
*/
#[derive(Debug, Deserialize)]
struct CreatedObject {
location: String,
ipAddress: String,
dateTime: String,
}
#[derive(Debug, Deserialize)]
struct ResponseStruct {
deviceId: String,
accountId: String,
secret: String,
userAgent: String,
created: CreatedObject,
}
let mut bearer_header = String::from("Bearer ");
bearer_header.push_str(self.access_token.as_str());
let response = Client::post(&http_client, url)
.header("Authorization", bearer_header.as_str())
.send();
match response {
Ok(response_data) => {
match response_data.json::<ResponseStruct>().ok() {
Some(response_json) => {
self.device_id = response_json.deviceId;
}
None => {
error!("Failed to parse device_id!");
},
}
},
_ => { error!("Failed to get device_id!"); },
}
}
pub fn get_device_auth_from(&mut self, access_token: &str, account_id: &str) {
if access_token.is_empty() || account_id.is_empty() {
error!("Device access token cannot be empty!");
return;
}
let mut url : String = String::from("https://account-public-service-prod.ol.epicgames.com/account/api/public/account/");
url.push_str(account_id.as_str());
url.push_str("/deviceAuth");
/*
let it : String = String::new;
it.starts_with("one thing");
// Just discovered String.starts_with() KEKW
*/
#[derive(Debug, Deserialize)]
struct CreatedObject {
location: String,
ipAddress: String,
dateTime: String,
}
#[derive(Debug, Deserialize)]
struct ResponseStruct {
deviceId: String,
accountId: String,
secret: String,
userAgent: String,
created: CreatedObject,
}
let mut bearer_header = String::from("Bearer ");
bearer_header.push_str(access_token.as_str());
let response = Client::post(&http_client, url)
.header("Authorization", bearer_header.as_str())
.send();
match response {
Ok(response_data) => {
match response_data.json::<ResponseStruct>().ok() {
Some(response_json) => {
self.device_id = response_json.deviceId;
}
None => {
error!("Failed to parse device_id!");
},
}
},
_ => { error!("Failed to get device_id!"); },
}
}
pub fn get_exchange_code() {
todo!();
}
}

View file

@ -1,3 +1,68 @@
mod auth;
use log::*;
use colog;
use std::env::args;
use std::io::Write;
use crate::auth::DeviceCredentials;
fn main() {
println!("Hello, world!");
/* Initial initializations */
{
colog::init();
// TODO: Set log level to display nothing
}
/* Command line arg fetching and handling */
let command_line_arguments: Vec<String> = args().collect();
{
/* Help page */
if command_line_arguments.iter().any(|a| a == "--help") {
// TODO: Complete help message
let help_page : &str =
"
=== godo-launcher help page===\n
`--verbose`, `-v`, `-vv`\t| Enables debug logging.
`--debug`, `-d`\t\t\t| Enables verbose logging.
`--help`, `-h`\t\t\t| Prints this page.
";
println!("{help_page}");
std::process::exit(0);
}
/* LogLevel modifiers */
if command_line_arguments.iter().any(|a| a == "--verbose" || a == "-v" || a == "-vv") {
// TODO: Change Log Level to info and warn
}
if command_line_arguments.iter().any(|a| a == "--debug") {
warn!("Debug info enabled!");
// TODO: Change Log Level to debug
}
}
/* Authentication Process */
let http_client_builder = reqwest::blocking::ClientBuilder::new()
.https_only(true)
.user_agent(concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),));
let http_client = http_client_builder.build().unwrap_or(reqwest::blocking::Client::new());
// Authentication code from user input
print!("Insert AuthCode > ");
std::io::stdout().flush().unwrap();
let mut auth_code: String = "".to_string();
let _ = std::io::stdin().read_line(&mut auth_code).unwrap();
let mut credentials : DeviceCredentials = DeviceCredentials::new();
credentials.get_access_token_and_account_id(&http_client, &auth_code);
credentials.get_device_auth(&http_client);
dbg!(&credentials);
/* Game Launching*/
}