mod anisette;
mod dev_services;
mod grandslam;
use anyhow::Result;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Session {
pub apple_id: String,
pub dsid: String,
pub gs_token: String,
}
#[derive(Debug, Clone)]
pub struct Team {
pub id: String,
pub name: String,
pub status: String,
}
#[derive(Debug, Clone)]
pub struct Device {
pub id: String,
pub name: String,
pub udid: String,
pub model: String,
pub platform: String,
}
pub struct DevProfile {
pub mobileprovision: Vec<u8>,
pub cert_der: Vec<u8>,
pub key_pem: Vec<u8>,
}
pub struct AppleId {
anisette: anisette::AnisetteProvider,
agent: ureq::Agent,
}
impl AppleId {
pub fn new() -> Result<Self> {
let anisette = anisette::AnisetteProvider::new()?;
let agent = ureq::Agent::config_builder()
.http_status_as_error(false)
.tls_config(
ureq::tls::TlsConfig::builder()
.provider(ureq::tls::TlsProvider::NativeTls)
.disable_verification(true)
.build(),
)
.build()
.new_agent();
Ok(AppleId { anisette, agent })
}
pub fn device_id(&self) -> &str {
&self.anisette.device_id
}
pub fn login(
&self,
apple_id: &str,
password: &str,
two_factor: impl FnMut() -> Result<String>,
) -> Result<Session> {
grandslam::login(&self.agent, &self.anisette, apple_id, password, two_factor)
}
pub fn list_teams(&self, session: &Session) -> Result<Vec<Team>> {
dev_services::DevServicesClient::new(&self.agent, &self.anisette, session).list_teams()
}
pub fn list_devices(&self, session: &Session, team_id: &str) -> Result<Vec<Device>> {
dev_services::DevServicesClient::new(&self.agent, &self.anisette, session)
.list_devices(team_id)
}
pub fn add_device(
&self,
session: &Session,
team_id: &str,
name: &str,
udid: &str,
) -> Result<()> {
dev_services::DevServicesClient::new(&self.agent, &self.anisette, session)
.add_device(team_id, name, udid)
}
pub fn ensure_app_id(
&self,
session: &Session,
team_id: &str,
bundle_id: &str,
name: &str,
) -> Result<()> {
dev_services::DevServicesClient::new(&self.agent, &self.anisette, session)
.ensure_app_id(team_id, bundle_id, name)?;
Ok(())
}
pub fn fetch_development_profile(
&self,
session: &Session,
team_id: &str,
bundle_id: &str,
udids: &[&str],
cached_identity: Option<(&[u8], &[u8])>,
confirm_revoke: impl FnMut(&[String]) -> Result<bool>,
) -> Result<DevProfile> {
dev_services::DevServicesClient::new(&self.agent, &self.anisette, session)
.fetch_development_profile(team_id, bundle_id, udids, cached_identity, confirm_revoke)
}
}