#![forbid(unsafe_code)]
use std::{fs, path::PathBuf};
fn workspace_file(path: &str) -> String {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.and_then(std::path::Path::parent)
.expect("workspace root")
.to_path_buf();
fs::read_to_string(root.join(path)).unwrap_or_else(|error| panic!("read {path}: {error}"))
}
#[test]
fn apple_sources_preserve_the_mobile_security_boundary() {
let app = workspace_file("apple/Sources/App/IronStorageApp.swift");
let watch = workspace_file("apple/Sources/Watch/IronStorageWatchApp.swift");
let autofill = workspace_file("apple/Sources/AutoFill/CredentialProviderViewController.swift");
let bridges = format!(
"{}\n{}",
workspace_file("crates/apple/src/lib.rs"),
workspace_file("crates/watch-apple/src/lib.rs")
);
for (name, source) in [
("iPhone", app.as_str()),
("Watch", watch.as_str()),
("AutoFill", autofill.as_str()),
("Apple Rust bridges", bridges.as_str()),
] {
for forbidden in [
"Process(",
"NSTask",
concat!("Command", "::new("),
"posix_spawn(",
] {
assert!(!source.contains(forbidden), "{name} launches {forbidden}");
}
}
for (name, source) in [
("iPhone", app.as_str()),
("Watch", watch.as_str()),
("AutoFill", autofill.as_str()),
] {
for forbidden in ["print(", "NSLog(", "Logger(", "os_log("] {
assert!(
!source.contains(forbidden),
"{name} logs through {forbidden}"
);
}
}
assert!(!app.contains("FileManager.default"));
for forbidden in ["otpauth://", "HMAC", "SHA1", "SHA256", "SHA512", ".gpg-id"] {
assert!(
!watch.contains(forbidden),
"Watch implements storage or OTP domain behavior: {forbidden}"
);
}
assert!(watch.contains("core.presentationAt"));
assert!(watch.contains("SecItemCopyMatching"));
assert!(app.contains("session.sendMessage(payload"));
assert!(app.contains("session.transferUserInfo(payload)"));
assert!(app.contains("session.outstandingUserInfoTransfers"));
assert!(
app.split_once("@main")
.expect("iPhone app delegate")
.0
.contains("UIApplication.didBecomeActiveNotification")
);
assert!(watch.contains("didReceiveMessage message"));
assert!(watch.contains("didReceiveUserInfo userInfo"));
assert!(watch.contains("session.outstandingUserInfoTransfers"));
assert!(watch.contains("session.transferUserInfo(acknowledgement)"));
assert!(
watch
.split_once("func sceneBecameActive()")
.expect("Watch foreground handler")
.1
.split_once("func sceneBecameInactive()")
.expect("Watch inactive handler")
.0
.contains("receivedApplicationContext")
);
assert!(watch.contains("applyAuthoritativeSnapshot"));
}
#[test]
fn iphone_entry_editor_keeps_add_action_accessible_while_typing() {
let app = workspace_file("apple/Sources/App/IronStorageApp.swift");
assert!(app.contains("navigationItem.rightBarButtonItems = [save, add]"));
assert!(app.contains("tableView.keyboardDismissMode = .interactive"));
assert!(app.contains("field.returnKeyType = .done"));
assert!(app.contains("textField.resignFirstResponder()"));
assert!(!app.contains("inputAccessoryView = keyboardToolbar"));
}
#[test]
fn every_apple_bundle_has_an_audited_privacy_manifest() {
let project = workspace_file("apple/project.yml");
for path in [
"Resources/App/PrivacyInfo.xcprivacy",
"Resources/AutoFill/PrivacyInfo.xcprivacy",
"Resources/Watch/PrivacyInfo.xcprivacy",
] {
assert!(project.contains(path), "Xcode target omits {path}");
}
for path in [
"apple/Resources/App/PrivacyInfo.xcprivacy",
"apple/Resources/AutoFill/PrivacyInfo.xcprivacy",
"apple/Resources/Watch/PrivacyInfo.xcprivacy",
] {
let manifest = workspace_file(path);
assert!(manifest.contains("NSPrivacyTracking\n\t"));
assert!(manifest.contains("NSPrivacyCollectedDataTypes\n\t"));
}
let app = workspace_file("apple/Resources/App/PrivacyInfo.xcprivacy");
assert!(app.contains("NSPrivacyAccessedAPICategoryFileTimestamp"));
assert!(app.contains("C617.1"));
assert!(app.contains("NSPrivacyAccessedAPICategorySystemBootTime"));
assert!(app.contains("35F9.1"));
assert!(project.contains("NSFaceIDUsageDescription"));
assert!(project.contains("NSCameraUsageDescription"));
}