mirror of
https://github.com/nab138/isideload.git
synced 2026-03-02 14:36:16 +01:00
Fix clippy errors
This commit is contained in:
@@ -27,11 +27,11 @@ impl Application {
|
|||||||
let temp_path = temp_dir
|
let temp_path = temp_dir
|
||||||
.join(path.file_name().unwrap().to_string_lossy().to_string() + "_extracted");
|
.join(path.file_name().unwrap().to_string_lossy().to_string() + "_extracted");
|
||||||
if temp_path.exists() {
|
if temp_path.exists() {
|
||||||
std::fs::remove_dir_all(&temp_path).map_err(|e| Error::Filesystem(e))?;
|
std::fs::remove_dir_all(&temp_path).map_err(Error::Filesystem)?;
|
||||||
}
|
}
|
||||||
std::fs::create_dir_all(&temp_path).map_err(|e| Error::Filesystem(e))?;
|
std::fs::create_dir_all(&temp_path).map_err(Error::Filesystem)?;
|
||||||
|
|
||||||
let file = File::open(&path).map_err(|e| Error::Filesystem(e))?;
|
let file = File::open(&path).map_err(Error::Filesystem)?;
|
||||||
let mut archive = ZipArchive::new(file).map_err(|e| {
|
let mut archive = ZipArchive::new(file).map_err(|e| {
|
||||||
Error::Generic(format!("Failed to open application archive: {}", e))
|
Error::Generic(format!("Failed to open application archive: {}", e))
|
||||||
})?;
|
})?;
|
||||||
@@ -47,7 +47,7 @@ impl Application {
|
|||||||
})?
|
})?
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
.filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false))
|
.filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false))
|
||||||
.filter(|entry| entry.path().extension().map_or(false, |ext| ext == "app"))
|
.filter(|entry| entry.path().extension().is_some_and(|ext| ext == "app"))
|
||||||
.collect();
|
.collect();
|
||||||
if app_dirs.len() == 1 {
|
if app_dirs.len() == 1 {
|
||||||
bundle_path = app_dirs[0].path();
|
bundle_path = app_dirs[0].path();
|
||||||
|
|||||||
@@ -20,11 +20,10 @@ impl Bundle {
|
|||||||
pub fn new(bundle_dir: PathBuf) -> Result<Self, Error> {
|
pub fn new(bundle_dir: PathBuf) -> Result<Self, Error> {
|
||||||
let mut bundle_path = bundle_dir;
|
let mut bundle_path = bundle_dir;
|
||||||
// Remove trailing slash/backslash
|
// Remove trailing slash/backslash
|
||||||
if let Some(path_str) = bundle_path.to_str() {
|
if let Some(path_str) = bundle_path.to_str()
|
||||||
if path_str.ends_with('/') || path_str.ends_with('\\') {
|
&& (path_str.ends_with('/') || path_str.ends_with('\\')) {
|
||||||
bundle_path = PathBuf::from(&path_str[..path_str.len() - 1]);
|
bundle_path = PathBuf::from(&path_str[..path_str.len() - 1]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let info_plist_path = bundle_path.join("Info.plist");
|
let info_plist_path = bundle_path.join("Info.plist");
|
||||||
assert_bundle(
|
assert_bundle(
|
||||||
@@ -158,16 +157,14 @@ fn find_dylibs(dir: &Path, bundle_root: &Path) -> Result<Vec<String>, Error> {
|
|||||||
.map_err(|e| Error::InvalidBundle(format!("Failed to get file type: {}", e)))?;
|
.map_err(|e| Error::InvalidBundle(format!("Failed to get file type: {}", e)))?;
|
||||||
|
|
||||||
if file_type.is_file() {
|
if file_type.is_file() {
|
||||||
if let Some(name) = path.file_name().and_then(|n| n.to_str()) {
|
if let Some(name) = path.file_name().and_then(|n| n.to_str())
|
||||||
if name.ends_with(".dylib") {
|
&& name.ends_with(".dylib") {
|
||||||
// Get relative path from bundle root
|
// Get relative path from bundle root
|
||||||
if let Ok(relative_path) = path.strip_prefix(bundle_root) {
|
if let Ok(relative_path) = path.strip_prefix(bundle_root)
|
||||||
if let Some(relative_str) = relative_path.to_str() {
|
&& let Some(relative_str) = relative_path.to_str() {
|
||||||
libraries.push(relative_str.to_string());
|
libraries.push(relative_str.to_string());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if file_type.is_dir() {
|
} else if file_type.is_dir() {
|
||||||
collect_dylibs(&path, bundle_root, libraries)?;
|
collect_dylibs(&path, bundle_root, libraries)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ impl CertificateIdentity {
|
|||||||
hasher.update(apple_id.as_bytes());
|
hasher.update(apple_id.as_bytes());
|
||||||
let hash_string = hex::encode(hasher.finalize()).to_lowercase();
|
let hash_string = hex::encode(hasher.finalize()).to_lowercase();
|
||||||
let key_path = configuration_path.join("keys").join(hash_string);
|
let key_path = configuration_path.join("keys").join(hash_string);
|
||||||
fs::create_dir_all(&key_path).map_err(|e| Error::Filesystem(e))?;
|
fs::create_dir_all(&key_path).map_err(Error::Filesystem)?;
|
||||||
|
|
||||||
let key_file = key_path.join("key.pem");
|
let key_file = key_path.join("key.pem");
|
||||||
let cert_file = key_path.join("cert.pem");
|
let cert_file = key_path.join("cert.pem");
|
||||||
@@ -57,7 +57,7 @@ impl CertificateIdentity {
|
|||||||
let pem_data = key
|
let pem_data = key
|
||||||
.private_key_to_pem_pkcs8()
|
.private_key_to_pem_pkcs8()
|
||||||
.map_err(|e| Error::Certificate(format!("Failed to encode private key: {}", e)))?;
|
.map_err(|e| Error::Certificate(format!("Failed to encode private key: {}", e)))?;
|
||||||
fs::write(&key_file, pem_data).map_err(|e| Error::Filesystem(e))?;
|
fs::write(&key_file, pem_data).map_err(Error::Filesystem)?;
|
||||||
key
|
key
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ impl CertificateIdentity {
|
|||||||
let cert_pem = cert.to_pem().map_err(|e| {
|
let cert_pem = cert.to_pem().map_err(|e| {
|
||||||
Error::Certificate(format!("Failed to encode certificate to PEM: {}", e))
|
Error::Certificate(format!("Failed to encode certificate to PEM: {}", e))
|
||||||
})?;
|
})?;
|
||||||
fs::write(&cert_identity.cert_file, cert_pem).map_err(|e| Error::Filesystem(e))?;
|
fs::write(&cert_identity.cert_file, cert_pem).map_err(Error::Filesystem)?;
|
||||||
|
|
||||||
return Ok(cert_identity);
|
return Ok(cert_identity);
|
||||||
}
|
}
|
||||||
@@ -108,15 +108,12 @@ impl CertificateIdentity {
|
|||||||
.iter()
|
.iter()
|
||||||
.filter(|c| c.machine_name == self.machine_name)
|
.filter(|c| c.machine_name == self.machine_name)
|
||||||
{
|
{
|
||||||
if let Ok(x509_cert) = X509::from_der(&cert.cert_content) {
|
if let Ok(x509_cert) = X509::from_der(&cert.cert_content)
|
||||||
if let Ok(cert_public_key) = x509_cert.public_key() {
|
&& let Ok(cert_public_key) = x509_cert.public_key()
|
||||||
if let Ok(cert_public_key_der) = cert_public_key.public_key_to_der() {
|
&& let Ok(cert_public_key_der) = cert_public_key.public_key_to_der()
|
||||||
if cert_public_key_der == our_public_key {
|
&& cert_public_key_der == our_public_key {
|
||||||
return Ok(x509_cert);
|
return Ok(x509_cert);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(Error::Certificate(
|
Err(Error::Certificate(
|
||||||
"No matching certificate found".to_string(),
|
"No matching certificate found".to_string(),
|
||||||
@@ -202,7 +199,7 @@ impl CertificateIdentity {
|
|||||||
let cert_pem = certificate.to_pem().map_err(|e| {
|
let cert_pem = certificate.to_pem().map_err(|e| {
|
||||||
Error::Certificate(format!("Failed to encode certificate to PEM: {}", e))
|
Error::Certificate(format!("Failed to encode certificate to PEM: {}", e))
|
||||||
})?;
|
})?;
|
||||||
fs::write(&self.cert_file, cert_pem).map_err(|e| Error::Filesystem(e))?;
|
fs::write(&self.cert_file, cert_pem).map_err(Error::Filesystem)?;
|
||||||
|
|
||||||
self.certificate = Some(certificate);
|
self.certificate = Some(certificate);
|
||||||
|
|
||||||
|
|||||||
@@ -264,10 +264,10 @@ impl DeveloperSession {
|
|||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
result.push(DevelopmentCertificate {
|
result.push(DevelopmentCertificate {
|
||||||
name: name,
|
name,
|
||||||
certificate_id,
|
certificate_id,
|
||||||
serial_number: serial_number,
|
serial_number,
|
||||||
machine_name: machine_name,
|
machine_name,
|
||||||
cert_content,
|
cert_content,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ use crate::Error;
|
|||||||
pub async fn install_app(
|
pub async fn install_app(
|
||||||
provider: &impl IdeviceProvider,
|
provider: &impl IdeviceProvider,
|
||||||
app_path: &Path,
|
app_path: &Path,
|
||||||
progress_callback: impl Fn(u64) -> (),
|
progress_callback: impl Fn(u64),
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut afc_client = AfcClient::connect(provider)
|
let mut afc_client = AfcClient::connect(provider)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::IdeviceError(e))?;
|
.map_err(Error::IdeviceError)?;
|
||||||
|
|
||||||
let dir = format!(
|
let dir = format!(
|
||||||
"PublicStaging/{}",
|
"PublicStaging/{}",
|
||||||
@@ -26,7 +26,7 @@ pub async fn install_app(
|
|||||||
|
|
||||||
let mut instproxy_client = InstallationProxyClient::connect(provider)
|
let mut instproxy_client = InstallationProxyClient::connect(provider)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::IdeviceError(e))?;
|
.map_err(Error::IdeviceError)?;
|
||||||
|
|
||||||
let mut options = plist::Dictionary::new();
|
let mut options = plist::Dictionary::new();
|
||||||
options.insert("PackageType".to_string(), "Developer".into());
|
options.insert("PackageType".to_string(), "Developer".into());
|
||||||
@@ -40,7 +40,7 @@ pub async fn install_app(
|
|||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::IdeviceError(e))?;
|
.map_err(Error::IdeviceError)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -51,13 +51,13 @@ fn afc_upload_dir<'a>(
|
|||||||
afc_path: &'a str,
|
afc_path: &'a str,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>> {
|
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let entries = std::fs::read_dir(path).map_err(|e| Error::Filesystem(e))?;
|
let entries = std::fs::read_dir(path).map_err(Error::Filesystem)?;
|
||||||
afc_client
|
afc_client
|
||||||
.mk_dir(afc_path)
|
.mk_dir(afc_path)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::IdeviceError(e))?;
|
.map_err(Error::IdeviceError)?;
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
let entry = entry.map_err(|e| Error::Filesystem(e))?;
|
let entry = entry.map_err(Error::Filesystem)?;
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
let new_afc_path = format!(
|
let new_afc_path = format!(
|
||||||
@@ -77,16 +77,16 @@ fn afc_upload_dir<'a>(
|
|||||||
idevice::afc::opcode::AfcFopenMode::WrOnly,
|
idevice::afc::opcode::AfcFopenMode::WrOnly,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::IdeviceError(e))?;
|
.map_err(Error::IdeviceError)?;
|
||||||
let bytes = std::fs::read(&path).map_err(|e| Error::Filesystem(e))?;
|
let bytes = std::fs::read(&path).map_err(Error::Filesystem)?;
|
||||||
file_handle
|
file_handle
|
||||||
.write_entire(&bytes)
|
.write_entire(&bytes)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::IdeviceError(e))?;
|
.map_err(Error::IdeviceError)?;
|
||||||
file_handle
|
file_handle
|
||||||
.close()
|
.close()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::IdeviceError(e))?;
|
.map_err(Error::IdeviceError)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -54,28 +54,28 @@ impl SideloadLogger for DefaultLogger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sideload configuration options.
|
/// Sideload configuration options.
|
||||||
pub struct SideloadConfiguration {
|
pub struct SideloadConfiguration<'a> {
|
||||||
/// An arbitrary machine name to appear on the certificate (e.x. "YCode")
|
/// An arbitrary machine name to appear on the certificate (e.x. "YCode")
|
||||||
pub machine_name: String,
|
pub machine_name: String,
|
||||||
/// Logger for reporting progress and errors
|
/// Logger for reporting progress and errors
|
||||||
pub logger: Box<dyn SideloadLogger>,
|
pub logger: &'a dyn SideloadLogger,
|
||||||
/// Directory used to store intermediate artifacts (profiles, certs, etc.). This directory will not be cleared at the end.
|
/// Directory used to store intermediate artifacts (profiles, certs, etc.). This directory will not be cleared at the end.
|
||||||
pub store_dir: std::path::PathBuf,
|
pub store_dir: std::path::PathBuf,
|
||||||
/// Whether or not to revoke the certificate immediately after installation
|
/// Whether or not to revoke the certificate immediately after installation
|
||||||
pub revoke_cert: bool,
|
pub revoke_cert: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SideloadConfiguration {
|
impl Default for SideloadConfiguration<'_> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
SideloadConfiguration::new()
|
SideloadConfiguration::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SideloadConfiguration {
|
impl<'a> SideloadConfiguration<'a> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
SideloadConfiguration {
|
SideloadConfiguration {
|
||||||
machine_name: "isideload".to_string(),
|
machine_name: "isideload".to_string(),
|
||||||
logger: Box::new(DefaultLogger),
|
logger: &DefaultLogger,
|
||||||
store_dir: std::env::current_dir().unwrap(),
|
store_dir: std::env::current_dir().unwrap(),
|
||||||
revoke_cert: false,
|
revoke_cert: false,
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ impl SideloadConfiguration {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_logger(mut self, logger: Box<dyn SideloadLogger>) -> Self {
|
pub fn set_logger(mut self, logger: &'a dyn SideloadLogger) -> Self {
|
||||||
self.logger = logger;
|
self.logger = logger;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use std::{io::Write, path::PathBuf};
|
use std::{io::Write, path::PathBuf};
|
||||||
|
|
||||||
fn error_and_return(logger: &Box<dyn SideloadLogger>, error: Error) -> Result<(), Error> {
|
fn error_and_return(logger: &dyn SideloadLogger, error: Error) -> Result<(), Error> {
|
||||||
logger.error(&error);
|
logger.error(&error);
|
||||||
Err(error)
|
Err(error)
|
||||||
}
|
}
|
||||||
@@ -30,13 +30,13 @@ pub async fn sideload_app(
|
|||||||
device_provider: &impl IdeviceProvider,
|
device_provider: &impl IdeviceProvider,
|
||||||
dev_session: &DeveloperSession,
|
dev_session: &DeveloperSession,
|
||||||
app_path: PathBuf,
|
app_path: PathBuf,
|
||||||
config: SideloadConfiguration,
|
config: SideloadConfiguration<'_>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let logger = config.logger;
|
let logger = config.logger;
|
||||||
let mut lockdown_client = match LockdownClient::connect(device_provider).await {
|
let mut lockdown_client = match LockdownClient::connect(device_provider).await {
|
||||||
Ok(l) => l,
|
Ok(l) => l,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return error_and_return(&logger, Error::IdeviceError(e));
|
return error_and_return(logger, Error::IdeviceError(e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -44,13 +44,13 @@ pub async fn sideload_app(
|
|||||||
lockdown_client
|
lockdown_client
|
||||||
.start_session(&pairing_file)
|
.start_session(&pairing_file)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::IdeviceError(e))?;
|
.map_err(Error::IdeviceError)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let device_name = lockdown_client
|
let device_name = lockdown_client
|
||||||
.get_value(Some("DeviceName"), None)
|
.get_value(Some("DeviceName"), None)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::IdeviceError(e))?
|
.map_err(Error::IdeviceError)?
|
||||||
.as_string()
|
.as_string()
|
||||||
.ok_or(Error::Generic(
|
.ok_or(Error::Generic(
|
||||||
"Failed to convert DeviceName to string".to_string(),
|
"Failed to convert DeviceName to string".to_string(),
|
||||||
@@ -60,7 +60,7 @@ pub async fn sideload_app(
|
|||||||
let device_uuid = lockdown_client
|
let device_uuid = lockdown_client
|
||||||
.get_value(Some("UniqueDeviceID"), None)
|
.get_value(Some("UniqueDeviceID"), None)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Error::IdeviceError(e))?
|
.map_err(Error::IdeviceError)?
|
||||||
.as_string()
|
.as_string()
|
||||||
.ok_or(Error::Generic(
|
.ok_or(Error::Generic(
|
||||||
"Failed to convert UniqueDeviceID to string".to_string(),
|
"Failed to convert UniqueDeviceID to string".to_string(),
|
||||||
@@ -70,17 +70,17 @@ pub async fn sideload_app(
|
|||||||
let team = match dev_session.get_team().await {
|
let team = match dev_session.get_team().await {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return error_and_return(&logger, e);
|
return error_and_return(logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
logger.log("Successfully retrieved team");
|
logger.log("Successfully retrieved team");
|
||||||
|
|
||||||
ensure_device_registered(&logger, dev_session, &team, &device_uuid, &device_name).await?;
|
ensure_device_registered(logger, dev_session, &team, &device_uuid, &device_name).await?;
|
||||||
|
|
||||||
let cert = match CertificateIdentity::new(
|
let cert = match CertificateIdentity::new(
|
||||||
&config.store_dir,
|
&config.store_dir,
|
||||||
&dev_session,
|
dev_session,
|
||||||
dev_session.account.apple_id.clone(),
|
dev_session.account.apple_id.clone(),
|
||||||
config.machine_name,
|
config.machine_name,
|
||||||
)
|
)
|
||||||
@@ -88,7 +88,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return error_and_return(&logger, e);
|
return error_and_return(logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(ids) => ids,
|
Ok(ids) => ids,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return error_and_return(&logger, e);
|
return error_and_return(logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ pub async fn sideload_app(
|
|||||||
Some(id) => id.to_string(),
|
Some(id) => id.to_string(),
|
||||||
None => {
|
None => {
|
||||||
return error_and_return(
|
return error_and_return(
|
||||||
&logger,
|
logger,
|
||||||
Error::InvalidBundle("No bundle identifier found in IPA".to_string()),
|
Error::InvalidBundle("No bundle identifier found in IPA".to_string()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ pub async fn sideload_app(
|
|||||||
Some(name) => name.to_string(),
|
Some(name) => name.to_string(),
|
||||||
None => {
|
None => {
|
||||||
return error_and_return(
|
return error_and_return(
|
||||||
&logger,
|
logger,
|
||||||
Error::InvalidBundle("No bundle name found in IPA".to_string()),
|
Error::InvalidBundle("No bundle name found in IPA".to_string()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -132,7 +132,7 @@ pub async fn sideload_app(
|
|||||||
if let Some(id) = ext.bundle_identifier() {
|
if let Some(id) = ext.bundle_identifier() {
|
||||||
if !(id.starts_with(&main_app_bundle_id) && id.len() > main_app_bundle_id.len()) {
|
if !(id.starts_with(&main_app_bundle_id) && id.len() > main_app_bundle_id.len()) {
|
||||||
return error_and_return(
|
return error_and_return(
|
||||||
&logger,
|
logger,
|
||||||
Error::InvalidBundle(format!(
|
Error::InvalidBundle(format!(
|
||||||
"Extension {} is not part of the main app bundle identifier: {}",
|
"Extension {} is not part of the main app bundle identifier: {}",
|
||||||
ext.bundle_name().unwrap_or("Unknown"),
|
ext.bundle_name().unwrap_or("Unknown"),
|
||||||
@@ -150,7 +150,7 @@ pub async fn sideload_app(
|
|||||||
}
|
}
|
||||||
app.bundle.set_bundle_identifier(&main_app_id_str);
|
app.bundle.set_bundle_identifier(&main_app_id_str);
|
||||||
|
|
||||||
let extension_refs: Vec<_> = app.bundle.app_extensions().into_iter().collect();
|
let extension_refs: Vec<_> = app.bundle.app_extensions().iter().collect();
|
||||||
let mut bundles_with_app_id = vec![&app.bundle];
|
let mut bundles_with_app_id = vec![&app.bundle];
|
||||||
bundles_with_app_id.extend(extension_refs);
|
bundles_with_app_id.extend(extension_refs);
|
||||||
|
|
||||||
@@ -165,27 +165,27 @@ pub async fn sideload_app(
|
|||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if let Some(available) = list_app_id_response.available_quantity {
|
if let Some(available) = list_app_id_response.available_quantity
|
||||||
if app_ids_to_register.len() > available.try_into().unwrap() {
|
&& app_ids_to_register.len() > available.try_into().unwrap()
|
||||||
return error_and_return(
|
{
|
||||||
&logger,
|
return error_and_return(
|
||||||
Error::InvalidBundle(format!(
|
logger,
|
||||||
"This app requires {} app ids, but you only have {} available",
|
Error::InvalidBundle(format!(
|
||||||
app_ids_to_register.len(),
|
"This app requires {} app ids, but you only have {} available",
|
||||||
available
|
app_ids_to_register.len(),
|
||||||
)),
|
available
|
||||||
);
|
)),
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for bundle in app_ids_to_register {
|
for bundle in app_ids_to_register {
|
||||||
let id = bundle.bundle_identifier().unwrap_or("");
|
let id = bundle.bundle_identifier().unwrap_or("");
|
||||||
let name = bundle.bundle_name().unwrap_or("");
|
let name = bundle.bundle_name().unwrap_or("");
|
||||||
if let Err(e) = dev_session
|
if let Err(e) = dev_session
|
||||||
.add_app_id(DeveloperDeviceType::Ios, &team, &name, &id)
|
.add_app_id(DeveloperDeviceType::Ios, &team, name, id)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
return error_and_return(&logger, e);
|
return error_and_return(logger, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_app_id_response = match dev_session
|
list_app_id_response = match dev_session
|
||||||
@@ -194,7 +194,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(ids) => ids,
|
Ok(ids) => ids,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return error_and_return(&logger, e);
|
return error_and_return(logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ pub async fn sideload_app(
|
|||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
None => {
|
None => {
|
||||||
return error_and_return(
|
return error_and_return(
|
||||||
&logger,
|
logger,
|
||||||
Error::Generic(format!(
|
Error::Generic(format!(
|
||||||
"Main app ID {} not found in registered app IDs",
|
"Main app ID {} not found in registered app IDs",
|
||||||
main_app_id_str
|
main_app_id_str
|
||||||
@@ -240,12 +240,12 @@ pub async fn sideload_app(
|
|||||||
let mut body = plist::Dictionary::new();
|
let mut body = plist::Dictionary::new();
|
||||||
body.insert("APG3427HIY".to_string(), plist::Value::Boolean(true));
|
body.insert("APG3427HIY".to_string(), plist::Value::Boolean(true));
|
||||||
let new_features = match dev_session
|
let new_features = match dev_session
|
||||||
.update_app_id(DeveloperDeviceType::Ios, &team, &app_id, &body)
|
.update_app_id(DeveloperDeviceType::Ios, &team, app_id, &body)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(new_feats) => new_feats,
|
Ok(new_feats) => new_feats,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return error_and_return(&logger, e);
|
return error_and_return(logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
app_id.features = new_features;
|
app_id.features = new_features;
|
||||||
@@ -267,7 +267,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(groups) => groups,
|
Ok(groups) => groups,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return error_and_return(&logger, e);
|
return error_and_return(logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(group) => group,
|
Ok(group) => group,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return error_and_return(&logger, e);
|
return error_and_return(logger, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -306,7 +306,7 @@ pub async fn sideload_app(
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
if assign_res.is_err() {
|
if assign_res.is_err() {
|
||||||
return error_and_return(&logger, assign_res.err().unwrap());
|
return error_and_return(logger, assign_res.err().unwrap());
|
||||||
}
|
}
|
||||||
// let provisioning_profile = match account
|
// let provisioning_profile = match account
|
||||||
// // This doesn't seem right to me, but it's what Sideloader does... Shouldn't it be downloading the provisioning profile for this app ID, not the main?
|
// // This doesn't seem right to me, but it's what Sideloader does... Shouldn't it be downloading the provisioning profile for this app ID, not the main?
|
||||||
@@ -332,7 +332,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(pp /* tee hee */) => pp,
|
Ok(pp /* tee hee */) => pp,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return error_and_return(&logger, e);
|
return error_and_return(logger, e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -341,12 +341,12 @@ pub async fn sideload_app(
|
|||||||
.join(format!("{}.mobileprovision", main_app_id_str));
|
.join(format!("{}.mobileprovision", main_app_id_str));
|
||||||
|
|
||||||
if profile_path.exists() {
|
if profile_path.exists() {
|
||||||
std::fs::remove_file(&profile_path).map_err(|e| Error::Filesystem(e))?;
|
std::fs::remove_file(&profile_path).map_err(Error::Filesystem)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut file = std::fs::File::create(&profile_path).map_err(|e| Error::Filesystem(e))?;
|
let mut file = std::fs::File::create(&profile_path).map_err(Error::Filesystem)?;
|
||||||
file.write_all(&provisioning_profile.encoded_profile)
|
file.write_all(&provisioning_profile.encoded_profile)
|
||||||
.map_err(|e| Error::Filesystem(e))?;
|
.map_err(Error::Filesystem)?;
|
||||||
|
|
||||||
// Without this, zsign complains it can't find the provision file
|
// Without this, zsign complains it can't find the provision file
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
@@ -368,7 +368,7 @@ pub async fn sideload_app(
|
|||||||
{
|
{
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return error_and_return(&logger, Error::ZSignError(e));
|
return error_and_return(logger, Error::ZSignError(e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -381,7 +381,7 @@ pub async fn sideload_app(
|
|||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
return error_and_return(&logger, e);
|
return error_and_return(logger, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.revoke_cert {
|
if config.revoke_cert {
|
||||||
@@ -412,7 +412,7 @@ pub async fn sideload_app(
|
|||||||
logger.log("Certificate revoked");
|
logger.log("Certificate revoked");
|
||||||
} else {
|
} else {
|
||||||
return error_and_return(
|
return error_and_return(
|
||||||
&logger,
|
logger,
|
||||||
Error::Certificate("No certificate to revoke".to_string()),
|
Error::Certificate("No certificate to revoke".to_string()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -422,7 +422,7 @@ pub async fn sideload_app(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn ensure_device_registered(
|
pub async fn ensure_device_registered(
|
||||||
logger: &Box<dyn SideloadLogger>,
|
logger: &dyn SideloadLogger,
|
||||||
dev_session: &DeveloperSession,
|
dev_session: &DeveloperSession,
|
||||||
team: &DeveloperTeam,
|
team: &DeveloperTeam,
|
||||||
uuid: &str,
|
uuid: &str,
|
||||||
|
|||||||
Reference in New Issue
Block a user