mirror of
https://github.com/nab138/isideload.git
synced 2026-03-02 06:26:16 +01:00
Add list devices and refactor
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -1071,8 +1071,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "plist-macro"
|
name = "plist-macro"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/nab138/plist_macro?branch=master#7004b1625aa50044bd381ee5393a9c85cec039d5"
|
||||||
checksum = "8888e02e251eba3258cc58fb79f0d8675c34b3428749e738562d58a0271bf035"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"plist",
|
"plist",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,3 +5,4 @@ default-members = ["isideload"]
|
|||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
rustls-platform-verifier = { git = "https://github.com/cstkingkey/rustls-platform-verifier", branch = "extra" }
|
rustls-platform-verifier = { git = "https://github.com/cstkingkey/rustls-platform-verifier", branch = "extra" }
|
||||||
|
plist-macro = { git = "https://github.com/nab138/plist_macro", branch = "master" }
|
||||||
@@ -50,10 +50,19 @@ async fn main() {
|
|||||||
.await
|
.await
|
||||||
.expect("Failed to create developer session");
|
.expect("Failed to create developer session");
|
||||||
|
|
||||||
let res = dev_session
|
let teams = dev_session
|
||||||
.list_teams()
|
.list_teams()
|
||||||
.await
|
.await
|
||||||
.expect("Failed to list teams");
|
.expect("Failed to list teams");
|
||||||
|
|
||||||
|
let team = teams
|
||||||
|
.get(0)
|
||||||
|
.expect("No developer teams available for this account");
|
||||||
|
|
||||||
|
let res = dev_session
|
||||||
|
.list_devices(team, None)
|
||||||
|
.await
|
||||||
|
.expect("Failed to list developer devices");
|
||||||
|
|
||||||
println!("{:#?}", res);
|
println!("{:#?}", res);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use plist::Dictionary;
|
use plist::Dictionary;
|
||||||
|
use plist_macro::plist_to_xml_string;
|
||||||
use plist_macro::pretty_print_dictionary;
|
use plist_macro::pretty_print_dictionary;
|
||||||
use reqwest::{
|
use reqwest::{
|
||||||
Certificate, ClientBuilder,
|
Certificate, ClientBuilder,
|
||||||
@@ -7,11 +8,7 @@ use reqwest::{
|
|||||||
use rootcause::prelude::*;
|
use rootcause::prelude::*;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::{
|
use crate::{SideloadError, anisette::AnisetteClientInfo, util::plist::PlistDataExtract};
|
||||||
SideloadError,
|
|
||||||
anisette::AnisetteClientInfo,
|
|
||||||
util::plist::{PlistDataExtract, plist_to_xml_string},
|
|
||||||
};
|
|
||||||
|
|
||||||
const APPLE_ROOT: &[u8] = include_bytes!("./apple_root.der");
|
const APPLE_ROOT: &[u8] = include_bytes!("./apple_root.der");
|
||||||
const URL_BAG: &str = "https://gsa.apple.com/grandslam/GsService2/lookup";
|
const URL_BAG: &str = "https://gsa.apple.com/grandslam/GsService2/lookup";
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use plist::Dictionary;
|
use plist::Dictionary;
|
||||||
use plist_macro::plist;
|
use plist_macro::{plist, plist_to_xml_string};
|
||||||
use rootcause::prelude::*;
|
use rootcause::prelude::*;
|
||||||
use tracing::debug;
|
use serde::de::DeserializeOwned;
|
||||||
|
use tracing::warn;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -10,11 +11,12 @@ use crate::{
|
|||||||
apple_account::{AppToken, AppleAccount},
|
apple_account::{AppToken, AppleAccount},
|
||||||
grandslam::GrandSlam,
|
grandslam::GrandSlam,
|
||||||
},
|
},
|
||||||
dev::{
|
dev::structures::{
|
||||||
device_type::DeveloperDeviceType,
|
DeveloperDevice,
|
||||||
structures::{DeveloperTeam, ListTeamResponse},
|
DeveloperDeviceType::{self, *},
|
||||||
|
DeveloperTeam, ListDevicesResponse, ListTeamsResponse,
|
||||||
},
|
},
|
||||||
util::plist::{PlistDataExtract, plist_to_xml_string},
|
util::plist::PlistDataExtract,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct DeveloperSession<'a> {
|
pub struct DeveloperSession<'a> {
|
||||||
@@ -58,12 +60,12 @@ impl<'a> DeveloperSession<'a> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_developer_request(
|
pub async fn send_developer_request<T: DeserializeOwned>(
|
||||||
&self,
|
&self,
|
||||||
url: &str,
|
url: &str,
|
||||||
body: Option<Dictionary>,
|
body: impl Into<Option<Dictionary>>,
|
||||||
) -> Result<String, Report> {
|
) -> Result<T, Report> {
|
||||||
let body = body.unwrap_or_else(|| Dictionary::new());
|
let body = body.into().unwrap_or_else(|| Dictionary::new());
|
||||||
|
|
||||||
let base = plist!(dict {
|
let base = plist!(dict {
|
||||||
"clientId": "XABBG36SBA",
|
"clientId": "XABBG36SBA",
|
||||||
@@ -89,22 +91,60 @@ impl<'a> DeveloperSession<'a> {
|
|||||||
.await
|
.await
|
||||||
.context("Failed to read developer request response text")?;
|
.context("Failed to read developer request response text")?;
|
||||||
|
|
||||||
// let dict: Dictionary = plist::from_bytes(text.as_bytes())
|
let dict: T = plist::from_bytes(text.as_bytes())
|
||||||
// .context("Failed to parse developer request plist")?;
|
.context("Failed to parse developer request plist")?;
|
||||||
|
|
||||||
Ok(text)
|
Ok(dict)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list_teams(&self) -> Result<Vec<DeveloperTeam>, Report> {
|
pub async fn list_teams(&self) -> Result<Vec<DeveloperTeam>, Report> {
|
||||||
let res = self
|
let response: ListTeamsResponse = self
|
||||||
.send_developer_request(&DeveloperDeviceType::Any.dev_url("listTeams"), None)
|
.send_developer_request(&dev_url("listTeams", Any), None)
|
||||||
.await?;
|
.await
|
||||||
|
.context("Failed to list developer teams")?;
|
||||||
|
|
||||||
let response: ListTeamResponse = plist::from_bytes(res.as_bytes())
|
if response.result_code != 0 {
|
||||||
.context("Failed to parse list teams response plist")?;
|
warn!(
|
||||||
|
"Non-zero list teams response code: {}",
|
||||||
debug!("List Teams Response Code: {:?}", response.result_code);
|
response.result_code
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
Ok(response.teams)
|
Ok(response.teams)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn list_devices(
|
||||||
|
&self,
|
||||||
|
team: &DeveloperTeam,
|
||||||
|
device_type: impl Into<Option<DeveloperDeviceType>>,
|
||||||
|
) -> Result<Vec<DeveloperDevice>, Report> {
|
||||||
|
let body = plist!(dict {
|
||||||
|
"teamId": &team.team_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
let response: ListDevicesResponse = self
|
||||||
|
.send_developer_request(&dev_url("listDevices", device_type), body)
|
||||||
|
.await
|
||||||
|
.context("Failed to list developer devices")?;
|
||||||
|
|
||||||
|
if response.result_code != 0 {
|
||||||
|
warn!(
|
||||||
|
"Non-zero list devices response code: {}",
|
||||||
|
response.result_code
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(response.devices)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dev_url(endpoint: &str, device_type: impl Into<Option<DeveloperDeviceType>>) -> String {
|
||||||
|
format!(
|
||||||
|
"https://developerservices2.apple.com/services/QH65B2/{}{}.action?clientId=XABBG36SBA",
|
||||||
|
device_type
|
||||||
|
.into()
|
||||||
|
.unwrap_or(DeveloperDeviceType::Ios)
|
||||||
|
.url_segment(),
|
||||||
|
endpoint,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum DeveloperDeviceType {
|
|
||||||
Any,
|
|
||||||
Ios,
|
|
||||||
Tvos,
|
|
||||||
Watchos,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeveloperDeviceType {
|
|
||||||
pub fn url_segment(&self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
DeveloperDeviceType::Any => "",
|
|
||||||
DeveloperDeviceType::Ios => "ios/",
|
|
||||||
DeveloperDeviceType::Tvos => "tvos/",
|
|
||||||
DeveloperDeviceType::Watchos => "watchos/",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dev_url(&self, endpoint: &str) -> String {
|
|
||||||
format!(
|
|
||||||
"https://developerservices2.apple.com/services/QH65B2/{}{}.action?clientId=XABBG36SBA",
|
|
||||||
self.url_segment(),
|
|
||||||
endpoint,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,2 @@
|
|||||||
pub mod developer_session;
|
pub mod developer_session;
|
||||||
pub mod device_type;
|
|
||||||
pub mod structures;
|
pub mod structures;
|
||||||
@@ -1,17 +1,52 @@
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum DeveloperDeviceType {
|
||||||
|
Any,
|
||||||
|
Ios,
|
||||||
|
Tvos,
|
||||||
|
Watchos,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeveloperDeviceType {
|
||||||
|
pub fn url_segment(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
DeveloperDeviceType::Any => "",
|
||||||
|
DeveloperDeviceType::Ios => "ios/",
|
||||||
|
DeveloperDeviceType::Tvos => "tvos/",
|
||||||
|
DeveloperDeviceType::Watchos => "watchos/",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct DeveloperTeam {
|
pub struct DeveloperTeam {
|
||||||
name: String,
|
pub name: Option<String>,
|
||||||
team_id: String,
|
pub team_id: String,
|
||||||
r#type: String,
|
pub r#type: Option<String>,
|
||||||
status: String,
|
pub status: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ListTeamResponse {
|
pub struct ListTeamsResponse {
|
||||||
pub teams: Vec<DeveloperTeam>,
|
pub teams: Vec<DeveloperTeam>,
|
||||||
pub result_code: i64,
|
pub result_code: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DeveloperDevice {
|
||||||
|
pub name: String,
|
||||||
|
pub device_id: String,
|
||||||
|
pub device_number: String,
|
||||||
|
pub status: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ListDevicesResponse {
|
||||||
|
pub devices: Vec<DeveloperDevice>,
|
||||||
|
pub result_code: i64,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,15 +1,7 @@
|
|||||||
use plist::Dictionary;
|
use plist::Dictionary;
|
||||||
use plist_macro::{plist_to_xml_bytes, plist_value_to_xml_bytes, pretty_print_dictionary};
|
use plist_macro::pretty_print_dictionary;
|
||||||
use rootcause::prelude::*;
|
use rootcause::prelude::*;
|
||||||
|
|
||||||
pub fn plist_to_xml_string(p: &Dictionary) -> String {
|
|
||||||
String::from_utf8(plist_to_xml_bytes(p)).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn plist_value_to_xml_string(p: &plist::Value) -> String {
|
|
||||||
String::from_utf8(plist_value_to_xml_bytes(p)).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SensitivePlistAttachment {
|
pub struct SensitivePlistAttachment {
|
||||||
pub plist: Dictionary,
|
pub plist: Dictionary,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user