use std::sync::Arc;
use chrono::Timelike;
use crate::core::geo_resolver::{GeoResolver, GeoLocation};
use crate::core::behavior_bio::{BehaviorEngine, BehaviorInput, AnalysisResult as BehaviorResult};
use crate::core::device_fp::{AdaptiveFingerprintEngine, AdaptiveFingerprint};
use crate::core::network_analyzer::{NetworkAnalyzer, NetworkAnalysisResult};
pub struct CompositeVerifier {
pub geo: Arc<GeoResolver>,
pub behavior: Arc<BehaviorEngine>,
pub device_fp: Arc<AdaptiveFingerprintEngine>,
pub network: Arc<NetworkAnalyzer>,
}
impl CompositeVerifier {
pub async fn verify_smart_access(
&self,
geo_input: Option<(std::net::IpAddr, (f64, f64, u8, f64))>,
behavior_input: BehaviorInput,
device_info: (&str, &str, &str),
allowed_zones: &[String],
allowed_hours: Option<(u8, u8)>,
) -> Result<bool, String> {
let geo_location = match &geo_input {
Some((ip, gps)) => {
self.geo
.resolve(crate::core::geo_resolver::GeoResolver::ResolveParams {
ip: Some(*ip),
gps: Some(*gps),
sim_location: None,
satellite_location: None,
indoor_data: None,
ar_data: None,
mfa_token: None,
})
.await
.map_err(|e| format!("Geo error: {e}"))?
},
None => return Err("Geo input missing".to_string()),
};
if let Some(city) = &geo_location.city {
if !allowed_zones.contains(city) {
return Err("Access denied: zone not allowed".to_string());
}
} else {
return Err("Geo location city missing".to_string());
}
if let Some((start, end)) = allowed_hours {
let hour = chrono::Utc::now().hour() as u8;
if hour < start || hour > end {
return Err("Access denied: outside allowed hours".to_string());
}
}
let behavior_result = self.behavior.process(behavior_input).await.map_err(|e| format!("Behavior error: {e}"))?;
if behavior_result.risk_level as u8 >= 3 { return Err("Access denied: behavioral risk".to_string());
}
let device_fp = self.device_fp.generate_fingerprint(device_info.0, device_info.1, device_info.2).await.map_err(|e| format!("Device FP error: {e}"))?;
if device_fp.security_level < 5 {
return Err("Access denied: device not trusted".to_string());
}
Ok(true)
}
}