1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use tokio::time::{Duration, Instant};
9
10pub mod compliance;
11pub mod dashboard;
12pub mod metrics;
13pub mod reports;
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct AnalyticsConfig {
18 pub real_time_enabled: bool,
20
21 pub data_retention_days: u32,
23
24 pub collection_interval: Duration,
26
27 pub compliance_monitoring: bool,
29
30 pub performance_monitoring: bool,
32
33 pub max_event_buffer: usize,
35}
36
37impl Default for AnalyticsConfig {
38 fn default() -> Self {
39 Self {
40 real_time_enabled: true,
41 data_retention_days: 90,
42 collection_interval: Duration::from_secs(60),
43 compliance_monitoring: true,
44 performance_monitoring: true,
45 max_event_buffer: 10000,
46 }
47 }
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
52pub enum RbacEventType {
53 RoleAssignment,
55 PermissionCheck,
57 RoleManagement,
59 Authentication,
61 Authorization,
63 PolicyViolation,
65 PrivilegeEscalation,
67 AccessAnomaly,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct AnalyticsEvent {
74 pub id: String,
76
77 pub event_type: RbacEventType,
79
80 pub timestamp: chrono::DateTime<chrono::Utc>,
82
83 pub user_id: Option<String>,
85
86 pub role_id: Option<String>,
88
89 pub resource: Option<String>,
91
92 pub action: Option<String>,
94
95 pub result: EventResult,
97
98 pub metadata: HashMap<String, String>,
100
101 pub duration_ms: Option<u64>,
103
104 pub source_ip: Option<String>,
106
107 pub user_agent: Option<String>,
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
113pub enum EventResult {
114 Success,
115 Failure,
116 Denied,
117 Error,
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct RoleUsageStats {
123 pub role_id: String,
125
126 pub role_name: String,
128
129 pub user_count: u32,
131
132 pub permission_checks: u64,
134
135 pub successful_access: u64,
137
138 pub denied_access: u64,
140
141 pub last_used: Option<chrono::DateTime<chrono::Utc>>,
143
144 pub avg_response_time_ms: f64,
146
147 pub top_resources: Vec<ResourceAccess>,
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize)]
153pub struct ResourceAccess {
154 pub resource: String,
156
157 pub access_count: u64,
159
160 pub success_rate: f64,
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct PermissionUsageStats {
167 pub permission_id: String,
169
170 pub check_count: u64,
172
173 pub success_rate: f64,
175
176 pub used_by_roles: Vec<String>,
178
179 pub top_users: Vec<UserActivity>,
181
182 pub peak_hours: Vec<u8>, }
185
186#[derive(Debug, Clone, Serialize, Deserialize)]
188pub struct UserActivity {
189 pub user_id: String,
191
192 pub activity_count: u64,
194
195 pub last_activity: chrono::DateTime<chrono::Utc>,
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize)]
201pub struct ComplianceMetrics {
202 pub role_assignment_compliance: f64,
204
205 pub permission_scoping_compliance: f64,
207
208 pub orphaned_permissions: u32,
210
211 pub over_privileged_users: u32,
213
214 pub unused_roles: u32,
216
217 pub avg_access_revocation_time_hours: f64,
219
220 pub policy_violations: u32,
222
223 pub security_incidents: u32,
225}
226
227#[derive(Debug, Clone, Serialize, Deserialize)]
229pub struct PerformanceMetrics {
230 pub avg_permission_check_latency_ms: f64,
232
233 pub p95_permission_check_latency_ms: f64,
235
236 pub p99_permission_check_latency_ms: f64,
238
239 pub permission_checks_per_second: f64,
241
242 pub permission_cache_hit_rate: f64,
244
245 pub error_rate: f64,
247
248 pub cpu_usage_percent: f64,
250
251 pub memory_usage_mb: u64,
253}
254
255#[derive(Debug, Clone, Serialize, Deserialize)]
257pub struct TimeSeriesData {
258 pub timestamp: chrono::DateTime<chrono::Utc>,
260
261 pub value: f64,
263
264 pub tags: HashMap<String, String>,
266}
267
268#[derive(Debug, Clone, Serialize, Deserialize)]
270pub struct TrendAnalysis {
271 pub metric_name: String,
273
274 pub current_value: f64,
276
277 pub previous_value: f64,
279
280 pub change_percent: f64,
282
283 pub trend: TrendDirection,
285
286 pub data_points: Vec<TimeSeriesData>,
288}
289
290#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
292pub enum TrendDirection {
293 Increasing,
294 Decreasing,
295 Stable,
296 Volatile,
297}
298
299pub struct AnalyticsManager {
301 config: AnalyticsConfig,
302 event_buffer: Vec<AnalyticsEvent>,
303 last_collection: Instant,
304}
305
306impl AnalyticsManager {
307 pub fn new(config: AnalyticsConfig) -> Self {
309 Self {
310 config,
311 event_buffer: Vec::new(),
312 last_collection: Instant::now(),
313 }
314 }
315
316 pub async fn record_event(&mut self, event: AnalyticsEvent) -> Result<(), AnalyticsError> {
318 if self.event_buffer.len() >= self.config.max_event_buffer {
319 self.flush_events().await?;
320 }
321
322 self.event_buffer.push(event);
323
324 if self.config.real_time_enabled {
325 self.process_real_time_event(self.event_buffer.last().unwrap())
327 .await?;
328 }
329
330 Ok(())
331 }
332
333 pub async fn get_role_usage_stats(
335 &self,
336 _role_id: Option<&str>,
337 _time_range: Option<TimeRange>,
338 ) -> Result<Vec<RoleUsageStats>, AnalyticsError> {
339 Ok(vec![])
341 }
342
343 pub async fn get_permission_usage_stats(
345 &self,
346 _permission_id: Option<&str>,
347 _time_range: Option<TimeRange>,
348 ) -> Result<Vec<PermissionUsageStats>, AnalyticsError> {
349 Ok(vec![])
351 }
352
353 pub async fn get_compliance_metrics(
355 &self,
356 _time_range: Option<TimeRange>,
357 ) -> Result<ComplianceMetrics, AnalyticsError> {
358 Ok(ComplianceMetrics {
360 role_assignment_compliance: 95.5,
361 permission_scoping_compliance: 88.2,
362 orphaned_permissions: 5,
363 over_privileged_users: 12,
364 unused_roles: 3,
365 avg_access_revocation_time_hours: 2.5,
366 policy_violations: 8,
367 security_incidents: 1,
368 })
369 }
370
371 pub async fn get_performance_metrics(
373 &self,
374 _time_range: Option<TimeRange>,
375 ) -> Result<PerformanceMetrics, AnalyticsError> {
376 Ok(PerformanceMetrics {
378 avg_permission_check_latency_ms: 15.5,
379 p95_permission_check_latency_ms: 45.2,
380 p99_permission_check_latency_ms: 125.8,
381 permission_checks_per_second: 1250.0,
382 permission_cache_hit_rate: 0.92,
383 error_rate: 0.001,
384 cpu_usage_percent: 15.5,
385 memory_usage_mb: 512,
386 })
387 }
388
389 pub async fn get_trend_analysis(
391 &self,
392 metric_name: &str,
393 _time_range: TimeRange,
394 ) -> Result<TrendAnalysis, AnalyticsError> {
395 Ok(TrendAnalysis {
397 metric_name: metric_name.to_string(),
398 current_value: 100.0,
399 previous_value: 95.0,
400 change_percent: 5.26,
401 trend: TrendDirection::Increasing,
402 data_points: vec![],
403 })
404 }
405
406 pub async fn generate_report(
408 &self,
409 report_type: ReportType,
410 time_range: TimeRange,
411 ) -> Result<AnalyticsReport, AnalyticsError> {
412 let role_stats = self
413 .get_role_usage_stats(None, Some(time_range.clone()))
414 .await?;
415 let permission_stats = self
416 .get_permission_usage_stats(None, Some(time_range.clone()))
417 .await?;
418 let compliance_metrics = self
419 .get_compliance_metrics(Some(time_range.clone()))
420 .await?;
421 let performance_metrics = self
422 .get_performance_metrics(Some(time_range.clone()))
423 .await?;
424
425 Ok(AnalyticsReport {
426 report_type,
427 time_range,
428 generated_at: chrono::Utc::now(),
429 role_stats,
430 permission_stats,
431 compliance_metrics: compliance_metrics.clone(),
432 performance_metrics: performance_metrics.clone(),
433 summary: self.generate_report_summary(&compliance_metrics, &performance_metrics),
434 })
435 }
436
437 async fn flush_events(&mut self) -> Result<(), AnalyticsError> {
439 if self.event_buffer.is_empty() {
440 return Ok(());
441 }
442
443 self.event_buffer.clear();
446 self.last_collection = Instant::now();
447
448 Ok(())
449 }
450
451 async fn process_real_time_event(&self, _event: &AnalyticsEvent) -> Result<(), AnalyticsError> {
453 Ok(())
455 }
456
457 fn generate_report_summary(
459 &self,
460 compliance: &ComplianceMetrics,
461 performance: &PerformanceMetrics,
462 ) -> String {
463 format!(
464 "RBAC Analytics Summary: {}% compliance, {:.1}ms avg latency, {:.1}% error rate",
465 compliance.role_assignment_compliance,
466 performance.avg_permission_check_latency_ms,
467 performance.error_rate * 100.0
468 )
469 }
470}
471
472#[derive(Debug, Clone, Serialize, Deserialize)]
474pub struct TimeRange {
475 pub start: chrono::DateTime<chrono::Utc>,
476 pub end: chrono::DateTime<chrono::Utc>,
477}
478
479impl TimeRange {
480 pub fn last_hours(hours: u32) -> Self {
482 let end = chrono::Utc::now();
483 let start = end - chrono::Duration::hours(hours as i64);
484 Self { start, end }
485 }
486
487 pub fn last_days(days: u32) -> Self {
489 let end = chrono::Utc::now();
490 let start = end - chrono::Duration::days(days as i64);
491 Self { start, end }
492 }
493
494 pub fn today() -> Self {
496 let now = chrono::Utc::now();
497 let start = now.date_naive().and_hms_opt(0, 0, 0).unwrap().and_utc();
498 let end = now;
499 Self { start, end }
500 }
501}
502
503#[derive(Debug, Clone, Serialize, Deserialize)]
505pub enum ReportType {
506 Daily,
508 Weekly,
510 Monthly,
512 Compliance,
514 Performance,
516 Custom(String),
518}
519
520#[derive(Debug, Clone, Serialize, Deserialize)]
522pub struct AnalyticsReport {
523 pub report_type: ReportType,
524 pub time_range: TimeRange,
525 pub generated_at: chrono::DateTime<chrono::Utc>,
526 pub role_stats: Vec<RoleUsageStats>,
527 pub permission_stats: Vec<PermissionUsageStats>,
528 pub compliance_metrics: ComplianceMetrics,
529 pub performance_metrics: PerformanceMetrics,
530 pub summary: String,
531}
532
533#[derive(Debug, thiserror::Error)]
535pub enum AnalyticsError {
536 #[error("Data processing error: {0}")]
537 ProcessingError(String),
538
539 #[error("Storage error: {0}")]
540 StorageError(String),
541
542 #[error("Query error: {0}")]
543 QueryError(String),
544
545 #[error("Configuration error: {0}")]
546 ConfigError(String),
547
548 #[error("IO error: {0}")]
549 IoError(#[from] std::io::Error),
550
551 #[error("Serialization error: {0}")]
552 SerializationError(#[from] serde_json::Error),
553}
554
555#[cfg(test)]
556mod tests {
557 use super::*;
558
559 #[test]
560 fn test_analytics_config_default() {
561 let config = AnalyticsConfig::default();
562 assert!(config.real_time_enabled);
563 assert_eq!(config.data_retention_days, 90);
564 assert!(config.compliance_monitoring);
565 }
566
567 #[test]
568 fn test_time_range_creation() {
569 let range = TimeRange::last_hours(24);
570 assert!(range.end > range.start);
571
572 let today = TimeRange::today();
573 assert!(today.end > today.start);
574 }
575
576 #[tokio::test]
577 async fn test_analytics_manager_creation() {
578 let config = AnalyticsConfig::default();
579 let manager = AnalyticsManager::new(config);
580 assert_eq!(manager.event_buffer.len(), 0);
581 }
582
583 #[tokio::test]
584 async fn test_record_event() {
585 let config = AnalyticsConfig::default();
586 let mut manager = AnalyticsManager::new(config);
587
588 let event = AnalyticsEvent {
589 id: "test_event_1".to_string(),
590 event_type: RbacEventType::PermissionCheck,
591 timestamp: chrono::Utc::now(),
592 user_id: Some("user123".to_string()),
593 role_id: Some("admin".to_string()),
594 resource: Some("user_data".to_string()),
595 action: Some("read".to_string()),
596 result: EventResult::Success,
597 metadata: HashMap::new(),
598 duration_ms: Some(15),
599 source_ip: Some("192.168.1.1".to_string()),
600 user_agent: Some("TestAgent/1.0".to_string()),
601 };
602
603 let result = manager.record_event(event).await;
604 assert!(result.is_ok());
605 assert_eq!(manager.event_buffer.len(), 1);
606 }
607}
608
609