Skip to main content

verifyos_cli/
profiles.rs

1use crate::core::engine::Engine;
2use crate::rules::ats::{AtsAuditRule, AtsExceptionsGranularityRule};
3use crate::rules::bundle_leakage::BundleResourceLeakageRule;
4use crate::rules::bundle_metadata::BundleMetadataConsistencyRule;
5use crate::rules::core::AppStoreRule;
6use crate::rules::entitlements::{EntitlementsMismatchRule, EntitlementsProvisioningMismatchRule};
7use crate::rules::export_compliance::ExportComplianceRule;
8use crate::rules::extensions::ExtensionEntitlementsCompatibilityRule;
9use crate::rules::info_plist::{
10    InfoPlistCapabilitiesRule, InfoPlistRequiredKeysRule, InfoPlistVersionConsistencyRule,
11    LSApplicationQueriesSchemesAuditRule, UIRequiredDeviceCapabilitiesAuditRule,
12    UsageDescriptionsRule, UsageDescriptionsValueRule,
13};
14use crate::rules::permissions::CameraUsageDescriptionRule;
15use crate::rules::privacy::MissingPrivacyManifestRule;
16use crate::rules::privacy_manifest::PrivacyManifestCompletenessRule;
17use crate::rules::privacy_sdk::PrivacyManifestSdkCrossCheckRule;
18use crate::rules::private_api::PrivateApiRule;
19use crate::rules::signing::EmbeddedCodeSignatureTeamRule;
20use std::collections::HashSet;
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum ScanProfile {
24    Basic,
25    Full,
26}
27
28#[derive(Debug, Clone, Default)]
29pub struct RuleSelection {
30    pub include: HashSet<String>,
31    pub exclude: HashSet<String>,
32}
33
34impl RuleSelection {
35    pub fn allows(&self, rule_id: &str) -> bool {
36        let normalized = normalize_rule_id(rule_id);
37        let included = self.include.is_empty() || self.include.contains(&normalized);
38        let excluded = self.exclude.contains(&normalized);
39        included && !excluded
40    }
41}
42
43pub fn register_rules(engine: &mut Engine, profile: ScanProfile, selection: &RuleSelection) {
44    for rule in profile_rules(profile) {
45        if selection.allows(rule.id()) {
46            engine.register_rule(rule);
47        }
48    }
49}
50
51pub fn available_rule_ids(profile: ScanProfile) -> Vec<String> {
52    let mut ids: Vec<String> = profile_rules(profile)
53        .into_iter()
54        .map(|rule| normalize_rule_id(rule.id()))
55        .collect();
56    ids.sort();
57    ids.dedup();
58    ids
59}
60
61pub fn normalize_rule_id(rule_id: &str) -> String {
62    rule_id.trim().to_ascii_uppercase()
63}
64
65fn profile_rules(profile: ScanProfile) -> Vec<Box<dyn AppStoreRule>> {
66    match profile {
67        ScanProfile::Basic => basic_rules(),
68        ScanProfile::Full => full_rules(),
69    }
70}
71
72fn basic_rules() -> Vec<Box<dyn AppStoreRule>> {
73    vec![
74        Box::new(MissingPrivacyManifestRule),
75        Box::new(UsageDescriptionsRule),
76        Box::new(UsageDescriptionsValueRule),
77        Box::new(CameraUsageDescriptionRule),
78        Box::new(AtsAuditRule),
79        Box::new(AtsExceptionsGranularityRule),
80        Box::new(EntitlementsMismatchRule),
81        Box::new(EntitlementsProvisioningMismatchRule),
82        Box::new(EmbeddedCodeSignatureTeamRule),
83    ]
84}
85
86fn full_rules() -> Vec<Box<dyn AppStoreRule>> {
87    vec![
88        Box::new(MissingPrivacyManifestRule),
89        Box::new(PrivacyManifestCompletenessRule),
90        Box::new(PrivacyManifestSdkCrossCheckRule),
91        Box::new(CameraUsageDescriptionRule),
92        Box::new(UsageDescriptionsRule),
93        Box::new(UsageDescriptionsValueRule),
94        Box::new(InfoPlistRequiredKeysRule),
95        Box::new(InfoPlistCapabilitiesRule),
96        Box::new(LSApplicationQueriesSchemesAuditRule),
97        Box::new(UIRequiredDeviceCapabilitiesAuditRule),
98        Box::new(InfoPlistVersionConsistencyRule),
99        Box::new(ExportComplianceRule),
100        Box::new(AtsAuditRule),
101        Box::new(AtsExceptionsGranularityRule),
102        Box::new(EntitlementsMismatchRule),
103        Box::new(EntitlementsProvisioningMismatchRule),
104        Box::new(BundleMetadataConsistencyRule),
105        Box::new(BundleResourceLeakageRule),
106        Box::new(ExtensionEntitlementsCompatibilityRule),
107        Box::new(PrivateApiRule),
108        Box::new(EmbeddedCodeSignatureTeamRule),
109    ]
110}