1use std::{
150 collections::HashMap,
151 io::{Read, Write},
152 sync::{Arc, Mutex},
153 time::Duration,
154};
155
156use base64::{Engine, engine::general_purpose};
157use flate2::{Compression, read::GzDecoder, write::GzEncoder};
158use ring::{
159 aead::{self, AES_256_GCM, LessSafeKey, UnboundKey},
160 hmac,
161 rand::{SecureRandom, SystemRandom},
162};
163use serde::{Deserialize, Serialize};
164use tauri::{AppHandle, Emitter, Manager};
165use tokio::{
166 sync::{Mutex as AsyncMutex, RwLock, Semaphore},
167 time::timeout,
168};
169
170use crate::dev_log;
171
172#[derive(Debug, Clone, Serialize, Deserialize)]
174pub struct TauriIPCMessage {
175 pub channel:String,
176
177 pub data:serde_json::Value,
178
179 pub sender:Option<String>,
180
181 pub timestamp:u64,
182}
183
184#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct ConnectionStatus {
187 pub connected:bool,
188}
189
190type ListenerCallback = Box<dyn Fn(serde_json::Value) -> Result<(), String> + Send + Sync>;
192
193#[derive(Clone)]
195pub struct TauriIPCServer {
196 app_handle:AppHandle,
197
198 listeners:Arc<Mutex<HashMap<String, Vec<ListenerCallback>>>>,
199
200 is_connected:Arc<Mutex<bool>>,
201
202 message_queue:Arc<Mutex<Vec<TauriIPCMessage>>>,
203}
204
205pub struct MessageCompressor {
207 CompressionLevel:u32,
208
209 BatchSize:usize,
210}
211
212impl MessageCompressor {
213 pub fn new(CompressionLevel:u32, BatchSize:usize) -> Self { Self { CompressionLevel, BatchSize } }
215
216 pub fn compress_messages(&self, Messages:Vec<TauriIPCMessage>) -> Result<Vec<u8>, String> {
218 let SerializedMessages =
219 serde_json::to_vec(&Messages).map_err(|e| format!("Failed to serialize messages: {}", e))?;
220
221 let mut encoder = GzEncoder::new(Vec::new(), Compression::new(self.CompressionLevel));
222
223 encoder
224 .write_all(&SerializedMessages)
225 .map_err(|e| format!("Failed to compress messages: {}", e))?;
226
227 encoder.finish().map_err(|e| format!("Failed to finish compression: {}", e))
228 }
229
230 pub fn decompress_messages(&self, CompressedData:&[u8]) -> Result<Vec<TauriIPCMessage>, String> {
232 let mut decoder = GzDecoder::new(CompressedData);
233
234 let mut DecompressedData = Vec::new();
235
236 decoder
237 .read_to_end(&mut DecompressedData)
238 .map_err(|e| format!("Failed to decompress data: {}", e))?;
239
240 serde_json::from_slice(&DecompressedData).map_err(|e| format!("Failed to deserialize messages: {}", e))
241 }
242
243 pub fn should_batch(&self, MessagesCount:usize) -> bool { MessagesCount >= self.BatchSize }
245}
246
247impl TauriIPCServer {
248 pub fn new(app_handle:AppHandle) -> Self {
250 dev_log!("ipc", "[TauriIPCServer] Initializing Mountain IPC Server");
251
252 Self {
253 app_handle,
254
255 listeners:Arc::new(Mutex::new(HashMap::new())),
256
257 is_connected:Arc::new(Mutex::new(false)),
258
259 message_queue:Arc::new(Mutex::new(Vec::new())),
260 }
261 }
262
263 pub async fn initialize(&self) -> Result<(), String> {
265 dev_log!("ipc", "[TauriIPCServer] Setting up IPC listeners");
266
267 {
269 let mut is_connected = self
270 .is_connected
271 .lock()
272 .map_err(|e| format!("Failed to lock connection status: {}", e))?;
273
274 *is_connected = true;
275 }
276
277 self.send_connection_status(true)
279 .await
280 .map_err(|e| format!("Failed to send connection status: {}", e))?;
281
282 dev_log!("ipc", "[TauriIPCServer] IPC Server initialized successfully");
283
284 self.process_message_queue().await;
286
287 Ok(())
288 }
289
290 pub async fn send(&self, channel:&str, data:serde_json::Value) -> Result<(), String> {
292 let Message = TauriIPCMessage {
293 channel:channel.to_string(),
294
295 data,
296
297 sender:Some("mountain".to_string()),
298
299 timestamp:std::time::SystemTime::now()
300 .duration_since(std::time::UNIX_EPOCH)
301 .unwrap_or_default()
302 .as_millis() as u64,
303 };
304
305 let is_connected = {
306 let guard = self
307 .is_connected
308 .lock()
309 .map_err(|e| format!("Failed to check connection status: {}", e))?;
310
311 *guard
312 };
313
314 if !is_connected {
315 let mut queue = self
317 .message_queue
318 .lock()
319 .map_err(|e| format!("Failed to access Message queue: {}", e))?;
320
321 queue.push(Message);
322
323 dev_log!(
324 "ipc",
325 "[TauriIPCServer] Message queued (channel: {}, queue size: {})",
326 channel,
327 queue.len()
328 );
329
330 return Ok(());
331 }
332
333 self.emit_message(&Message).await
335 }
336
337 pub fn on(&self, channel:&str, callback:ListenerCallback) -> Result<(), String> {
339 let mut listeners = self
340 .listeners
341 .lock()
342 .map_err(|e| format!("Failed to access listeners: {}", e))?;
343
344 listeners.entry(channel.to_string()).or_insert_with(Vec::new).push(callback);
345
346 dev_log!("ipc", "[TauriIPCServer] Listener registered for channel: {}", channel);
347
348 Ok(())
349 }
350
351 pub fn off(&self, channel:&str, callback:&ListenerCallback) -> Result<(), String> {
353 let mut listeners = self
354 .listeners
355 .lock()
356 .map_err(|e| format!("Failed to access listeners: {}", e))?;
357
358 if let Some(channel_listeners) = listeners.get_mut(channel) {
359 channel_listeners.retain(|cb| !std::ptr::eq(cb as *const _, callback as *const _));
360
361 if channel_listeners.is_empty() {
362 listeners.remove(channel);
363 }
364 }
365
366 dev_log!("ipc", "[TauriIPCServer] Listener removed from channel: {}", channel);
367
368 Ok(())
369 }
370
371 pub async fn IncomingMessage(&self, Message:TauriIPCMessage) -> Result<(), String> {
373 dev_log!("ipc", "[TauriIPCServer] Received Message on channel: {}", Message.channel);
374
375 let listeners = self
376 .listeners
377 .lock()
378 .map_err(|e| format!("Failed to access listeners: {}", e))?;
379
380 if let Some(channel_listeners) = listeners.get(&Message.channel) {
381 for callback in channel_listeners {
382 if let Err(e) = callback(Message.data.clone()) {
383 dev_log!(
384 "ipc",
385 "error: [TauriIPCServer] Error in listener for channel {}: {}",
386 Message.channel,
387 e
388 );
389 }
390 }
391 } else {
392 dev_log!("ipc", "[TauriIPCServer] No listeners found for channel: {}", Message.channel);
393 }
394
395 Ok(())
396 }
397
398 async fn send_connection_status(&self, connected:bool) -> Result<(), String> {
400 let status = ConnectionStatus { connected };
401
402 self.app_handle
403 .emit("vscode-ipc-status", status)
404 .map_err(|e| format!("Failed to emit connection status: {}", e))?;
405
406 dev_log!("ipc", "[TauriIPCServer] Connection status sent: {}", connected);
407
408 Ok(())
409 }
410
411 async fn emit_message(&self, Message:&TauriIPCMessage) -> Result<(), String> {
413 self.app_handle
414 .emit("vscode-ipc-Message", Message)
415 .map_err(|e| format!("Failed to emit Message: {}", e))?;
416
417 dev_log!("ipc", "[TauriIPCServer] Message emitted on channel: {}", Message.channel);
418
419 Ok(())
420 }
421
422 async fn process_message_queue(&self) {
424 let mut queue = match self.message_queue.lock() {
425 Ok(queue) => queue,
426
427 Err(e) => {
428 dev_log!("ipc", "error: [TauriIPCServer] Failed to access Message queue: {}", e);
429
430 return;
431 },
432 };
433
434 while let Some(Message) = queue.pop() {
435 if let Err(e) = self.emit_message(&Message).await {
436 dev_log!("ipc", "error: [TauriIPCServer] Failed to send queued Message: {}", e);
437
438 queue.insert(0, Message);
440
441 break;
442 }
443 }
444
445 dev_log!(
446 "ipc",
447 "[TauriIPCServer] Message queue processed, {} messages remaining",
448 queue.len()
449 );
450 }
451
452 pub fn get_connection_status(&self) -> Result<bool, String> {
454 let guard = self
455 .is_connected
456 .lock()
457 .map_err(|e| format!("Failed to get connection status: {}", e))?;
458
459 Ok(*guard)
460 }
461
462 pub fn get_queue_size(&self) -> Result<usize, String> {
464 let guard = self
465 .message_queue
466 .lock()
467 .map_err(|e| format!("Failed to get queue size: {}", e))?;
468
469 Ok(guard.len())
470 }
471
472 pub fn dispose(&self) -> Result<(), String> {
474 {
475 let mut listeners = self
476 .listeners
477 .lock()
478 .map_err(|e| format!("Failed to access listeners: {}", e))?;
479
480 listeners.clear();
481 }
482
483 {
484 let mut queue = self
485 .message_queue
486 .lock()
487 .map_err(|e| format!("Failed to access Message queue: {}", e))?;
488
489 queue.clear();
490 }
491
492 {
493 let mut is_connected = self
494 .is_connected
495 .lock()
496 .map_err(|e| format!("Failed to access connection status: {}", e))?;
497
498 *is_connected = false;
499 }
500
501 dev_log!("ipc", "[TauriIPCServer] IPC Server disposed");
502
503 Ok(())
504 }
505
506 pub async fn validate_message_permissions(&self, Message:&TauriIPCMessage) -> Result<(), String> {
508 let permission_manager = PermissionManager::new();
509
510 permission_manager.initialize_defaults().await;
511
512 let context = self.create_security_context(Message);
513
514 let operation = Message.channel.replace("mountain_", "");
516
517 permission_manager.validate_permission(&operation, &context).await
519 }
520
521 fn create_security_context(&self, Message:&TauriIPCMessage) -> SecurityContext {
523 SecurityContext {
524 user_id:Message.sender.clone().unwrap_or("unknown".to_string()),
525
526 roles:vec!["user".to_string()],
528
529 permissions:vec![],
530
531 ip_address:"127.0.0.1".to_string(),
533
534 timestamp:std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_millis(Message.timestamp),
535 }
536 }
537
538 pub async fn log_security_event(&self, event:SecurityEvent) {
540 let permission_manager = PermissionManager::new();
541
542 permission_manager.log_security_event(event).await;
543 }
544
545 pub async fn record_performance_metrics(&self, channel:String, duration:std::time::Duration, success:bool) {
547 dev_log!(
549 "ipc",
550 "[TauriIPCServer] Performance recorded - Channel: {}, Duration: {:?}, Success: {}",
551 channel,
552 duration,
553 success
554 );
555 }
556
557 pub async fn get_security_audit_log(&self, limit:usize) -> Result<Vec<SecurityEvent>, String> {
559 let permission_manager = PermissionManager::new();
560
561 Ok(permission_manager.get_audit_log(limit).await)
562 }
563
564 pub async fn send_compressed_batch(&self, channel:&str, messages:Vec<TauriIPCMessage>) -> Result<(), String> {
566 let compressor = MessageCompressor::new(6, 10);
569
570 let compressed_data = compressor
571 .compress_messages(messages)
572 .map_err(|e| format!("Failed to compress batch: {}", e))?;
573
574 let batch_message = TauriIPCMessage {
575 channel:"compressed_batch".to_string(),
576
577 data:serde_json::Value::String(general_purpose::STANDARD.encode(&compressed_data)),
578
579 sender:Some("mountain".to_string()),
580
581 timestamp:std::time::SystemTime::now()
582 .duration_since(std::time::UNIX_EPOCH)
583 .unwrap_or_default()
584 .as_millis() as u64,
585 };
586
587 self.send(channel, serde_json::to_value(batch_message).unwrap()).await
588 }
589
590 pub async fn CompressedBatch(&self, Message:TauriIPCMessage) -> Result<(), String> {
592 let compressed_data_base64 = Message.data.as_str().ok_or("Compressed batch data must be a string")?;
593
594 let compressed_data = general_purpose::STANDARD
595 .decode(compressed_data_base64)
596 .map_err(|e| format!("Failed to decode base64: {}", e))?;
597
598 let compressor = MessageCompressor::new(6, 10);
599
600 let messages = compressor
601 .decompress_messages(&compressed_data)
602 .map_err(|e| format!("Failed to decompress batch: {}", e))?;
603
604 for Message in messages {
606 self.IncomingMessage(Message).await?;
607 }
608
609 Ok(())
610 }
611
612 pub async fn send_with_pool(&self, channel:&str, data:serde_json::Value) -> Result<(), String> {
614 let pool = Arc::new(ConnectionPool::new(10, Duration::from_secs(30)));
615
616 let Handle = pool
617 .GetConnection()
618 .await
619 .map_err(|e| format!("Failed to get connection: {}", e))?;
620
621 let result = self.send(channel, data).await;
622
623 pool.ReleaseConnection(Handle).await;
624
625 result
626 }
627
628 pub async fn get_connection_stats(&self) -> Result<ConnectionStats, String> {
630 let pool = Arc::new(ConnectionPool::new(10, Duration::from_secs(30)));
631
632 Ok(pool.GetStats().await)
633 }
634
635 pub async fn send_secure(&self, channel:&str, data:serde_json::Value) -> Result<(), String> {
637 let secure_channel =
638 SecureMessageChannel::new().map_err(|e| format!("Failed to create secure channel: {}", e))?;
639
640 let Message = TauriIPCMessage {
641 channel:channel.to_string(),
642
643 data,
644
645 sender:Some("mountain".to_string()),
646
647 timestamp:std::time::SystemTime::now()
648 .duration_since(std::time::UNIX_EPOCH)
649 .unwrap_or_default()
650 .as_millis() as u64,
651 };
652
653 let encrypted_message = secure_channel
654 .encrypt_message(&Message)
655 .map_err(|e| format!("Failed to encrypt Message: {}", e))?;
656
657 let encrypted_data = serde_json::to_value(encrypted_message)
658 .map_err(|e| format!("Failed to serialize encrypted Message: {}", e))?;
659
660 self.send("secure_message", encrypted_data).await
661 }
662
663 pub async fn SecureMessage(&self, encrypted_data:serde_json::Value) -> Result<(), String> {
665 let encrypted_message:EncryptedMessage = serde_json::from_value(encrypted_data)
666 .map_err(|e| format!("Failed to deserialize encrypted Message: {}", e))?;
667
668 let secure_channel =
669 SecureMessageChannel::new().map_err(|e| format!("Failed to create secure channel: {}", e))?;
670
671 let Message = secure_channel
672 .decrypt_message(&encrypted_message)
673 .map_err(|e| format!("Failed to decrypt Message: {}", e))?;
674
675 self.IncomingMessage(Message).await
676 }
677
678 pub async fn MessageWithPermissions(&self, Message:TauriIPCMessage) -> Result<(), String> {
680 let permission_manager = PermissionManager::new();
681
682 let context = self.create_security_context(&Message);
683
684 let operation = Message.channel.replace("mountain_", "");
686
687 permission_manager.validate_permission(&operation, &context).await?;
689
690 self.IncomingMessage(Message).await
692 }
693}
694
695pub struct ConnectionPool {
702 MaxConnections:usize,
703
704 ConnectionTimeout:Duration,
705
706 Semaphore:Arc<Semaphore>,
707
708 ActiveConnection:Arc<AsyncMutex<HashMap<String, ConnectionHandle>>>,
709
710 HealthChecker:Arc<AsyncMutex<ConnectionHealthChecker>>,
711}
712
713#[derive(Clone)]
715pub struct ConnectionHandle {
716 pub id:String,
717
718 pub created_at:std::time::Instant,
719
720 pub last_used:std::time::Instant,
721
722 pub health_score:f64,
723
724 pub error_count:usize,
725}
726
727impl ConnectionHandle {
728 pub fn new() -> Self {
730 Self {
731 id:uuid::Uuid::new_v4().to_string(),
732
733 created_at:std::time::Instant::now(),
734
735 last_used:std::time::Instant::now(),
736
737 health_score:100.0,
738
739 error_count:0,
740 }
741 }
742
743 pub fn update_health(&mut self, success:bool) {
745 if success {
746 self.health_score = (self.health_score + 10.0).min(100.0);
747
748 self.error_count = 0;
749 } else {
750 self.health_score = (self.health_score - 25.0).max(0.0);
751
752 self.error_count += 1;
753 }
754
755 self.last_used = std::time::Instant::now();
756 }
757
758 pub fn is_healthy(&self) -> bool { self.health_score > 50.0 && self.error_count < 5 }
760}
761
762impl ConnectionPool {
763 pub fn new(MaxConnections:usize, ConnectionTimeout:Duration) -> Self {
765 Self {
766 MaxConnections,
767
768 ConnectionTimeout,
769
770 Semaphore:Arc::new(Semaphore::new(MaxConnections)),
771
772 ActiveConnection:Arc::new(AsyncMutex::new(HashMap::new())),
773
774 HealthChecker:Arc::new(AsyncMutex::new(ConnectionHealthChecker::new())),
775 }
776 }
777
778 pub async fn GetConnection(&self) -> Result<ConnectionHandle, String> {
780 let _permit = timeout(self.ConnectionTimeout, self.Semaphore.acquire())
781 .await
782 .map_err(|_| "Connection timeout")?
783 .map_err(|e| format!("Failed to acquire connection: {}", e))?;
784
785 let Handle = ConnectionHandle::new();
786
787 {
788 let mut connections = self.ActiveConnection.lock().await;
789
790 connections.insert(Handle.id.clone(), Handle.clone());
791 }
792
793 self.StartHealthMonitoring(&Handle.id).await;
795
796 Ok(Handle)
797 }
798
799 pub async fn ReleaseConnection(&self, Handle:ConnectionHandle) {
801 {
802 let mut connections = self.ActiveConnection.lock().await;
803
804 connections.remove(&Handle.id);
805 }
806
807 }
809
810 pub async fn GetStats(&self) -> ConnectionStats {
812 let connections = self.ActiveConnection.lock().await;
813
814 let healthy_connections = connections.values().filter(|h| h.is_healthy()).count();
815
816 ConnectionStats {
817 total_connections:connections.len(),
818
819 healthy_connections,
820
821 max_connections:self.MaxConnections,
822
823 available_permits:self.Semaphore.available_permits(),
824
825 connection_timeout:self.ConnectionTimeout,
826 }
827 }
828
829 pub async fn CleanUpStaleConnections(&self) -> usize {
831 let mut connections = self.ActiveConnection.lock().await;
832
833 let now = std::time::Instant::now();
834
835 let stale_threshold = Duration::from_secs(300);
837
838 let stale_ids:Vec<String> = connections
839 .iter()
840 .filter(|(_, Handle)| now.duration_since(Handle.last_used) > stale_threshold || !Handle.is_healthy())
841 .map(|(id, _)| id.clone())
842 .collect();
843
844 let stale_count = stale_ids.len();
845
846 for id in stale_ids {
847 connections.remove(&id);
848 }
849
850 stale_count
851 }
852
853 async fn StartHealthMonitoring(&self, connection_id:&str) {
855 let health_checker = self.HealthChecker.clone();
856
857 let active_connection = self.ActiveConnection.clone();
858
859 let connection_id = connection_id.to_string();
860
861 tokio::spawn(async move {
862 let mut interval = tokio::time::interval(Duration::from_secs(30));
863
864 loop {
865 interval.tick().await;
866
867 let checker = health_checker.lock().await;
868 let mut connections = match active_connection.try_lock() {
869 Ok(conns) => conns,
870 Err(_) => continue,
871 };
872
873 if let Some(Handle) = connections.get_mut(&connection_id) {
874 let is_healthy = checker.check_connection_health(Handle).await;
875 Handle.update_health(is_healthy);
876
877 if !Handle.is_healthy() {
878 dev_log!(
879 "ipc",
880 "Connection {} marked as unhealthy (score: {:.1})",
881 Handle.id,
882 Handle.health_score
883 );
884 }
885 } else {
886 break;
888 }
889 }
890 });
891 }
892}
893
894struct ConnectionHealthChecker {
896 ping_timeout:Duration,
897}
898
899impl ConnectionHealthChecker {
900 fn new() -> Self { Self { ping_timeout:Duration::from_secs(5) } }
901
902 async fn check_connection_health(&self, _handle:&mut ConnectionHandle) -> bool {
904 let start_time = std::time::Instant::now();
907
908 tokio::time::sleep(Duration::from_millis(10)).await;
910
911 let response_time = start_time.elapsed();
912
913 response_time < self.ping_timeout
915 }
916}
917
918#[derive(Debug, Clone, Default)]
920pub struct ConnectionStats {
921 pub total_connections:usize,
922
923 pub healthy_connections:usize,
924
925 pub max_connections:usize,
926
927 pub available_permits:usize,
928
929 pub connection_timeout:Duration,
930}
931
932pub struct SecureMessageChannel {
934 encryption_key:LessSafeKey,
935
936 hmac_key:Vec<u8>,
937}
938
939impl SecureMessageChannel {
940 pub fn new() -> Result<Self, String> {
942 let rng = SystemRandom::new();
943
944 let mut encryption_key_bytes = vec![0u8; 32];
946
947 rng.fill(&mut encryption_key_bytes)
948 .map_err(|e| format!("Failed to generate encryption key: {}", e))?;
949
950 let unbound_key = UnboundKey::new(&AES_256_GCM, &encryption_key_bytes)
951 .map_err(|e| format!("Failed to create unbound key: {}", e))?;
952
953 let encryption_key = LessSafeKey::new(unbound_key);
954
955 let mut hmac_key = vec![0u8; 32];
957
958 rng.fill(&mut hmac_key)
959 .map_err(|e| format!("Failed to generate HMAC key: {}", e))?;
960
961 Ok(Self { encryption_key, hmac_key })
962 }
963
964 pub fn encrypt_message(&self, Message:&TauriIPCMessage) -> Result<EncryptedMessage, String> {
966 let serialized_message =
967 serde_json::to_vec(Message).map_err(|e| format!("Failed to serialize Message: {}", e))?;
968
969 let mut nonce = [0u8; 12];
971
972 SystemRandom::new()
973 .fill(&mut nonce)
974 .map_err(|e| format!("Failed to generate nonce: {}", e))?;
975
976 let mut in_out = serialized_message.clone();
978
979 self.encryption_key
980 .seal_in_place_append_tag(aead::Nonce::assume_unique_for_key(nonce), aead::Aad::empty(), &mut in_out)
981 .map_err(|e| format!("Encryption failed: {}", e))?;
982
983 let hmac_key = hmac::Key::new(hmac::HMAC_SHA256, &self.hmac_key);
985
986 let hmac_tag = hmac::sign(&hmac_key, &in_out);
987
988 Ok(EncryptedMessage { nonce:nonce.to_vec(), ciphertext:in_out, hmac_tag:hmac_tag.as_ref().to_vec() })
989 }
990
991 pub fn decrypt_message(&self, encrypted:&EncryptedMessage) -> Result<TauriIPCMessage, String> {
993 let hmac_key = hmac::Key::new(hmac::HMAC_SHA256, &self.hmac_key);
995
996 hmac::verify(&hmac_key, &encrypted.ciphertext, &encrypted.hmac_tag)
997 .map_err(|_| "HMAC verification failed".to_string())?;
998
999 let mut in_out = encrypted.ciphertext.clone();
1001
1002 let nonce_slice:&[u8] = &encrypted.nonce;
1003
1004 let nonce_array:[u8; 12] = nonce_slice.try_into().map_err(|_| "Invalid nonce length".to_string())?;
1005
1006 let nonce = aead::Nonce::assume_unique_for_key(nonce_array);
1007
1008 self.encryption_key
1009 .open_in_place(nonce, aead::Aad::empty(), &mut in_out)
1010 .map_err(|e| format!("Decryption failed: {}", e))?;
1011
1012 let plaintext_len = in_out.len() - AES_256_GCM.tag_len();
1014
1015 in_out.truncate(plaintext_len);
1016
1017 serde_json::from_slice(&in_out).map_err(|e| format!("Failed to deserialize Message: {}", e))
1019 }
1020
1021 pub fn rotate_keys(&mut self) -> Result<(), String> {
1023 *self = Self::new()?;
1024 Ok(())
1025 }
1026}
1027
1028#[derive(Debug, Clone, Serialize, Deserialize)]
1030pub struct EncryptedMessage {
1031 nonce:Vec<u8>,
1032
1033 ciphertext:Vec<u8>,
1034
1035 hmac_tag:Vec<u8>,
1036}
1037
1038#[tauri::command]
1040pub async fn mountain_ipc_receive_message(app_handle:tauri::AppHandle, Message:TauriIPCMessage) -> Result<(), String> {
1041 dev_log!(
1042 "ipc",
1043 "[TauriIPCServer] Received IPC Message from Wind on channel: {}",
1044 Message.channel
1045 );
1046
1047 if let Some(ipc_server) = app_handle.try_state::<TauriIPCServer>() {
1049 if let Err(e) = ipc_server.validate_message_permissions(&Message).await {
1051 dev_log!(
1052 "ipc",
1053 "error: [TauriIPCServer] Permission validation failed for channel {}: {}",
1054 Message.channel,
1055 e
1056 );
1057
1058 ipc_server
1060 .log_security_event(SecurityEvent {
1061 event_type:SecurityEventType::PermissionDenied,
1062 user_id:Message.sender.clone().unwrap_or("unknown".to_string()),
1063 operation:Message.channel.clone(),
1064 timestamp:std::time::SystemTime::now(),
1065 details:Some(format!("Permission denied: {}", e)),
1066 })
1067 .await;
1068
1069 return Err(format!("Permission denied: {}", e));
1070 }
1071
1072 let start_time = std::time::Instant::now();
1074
1075 let result = ipc_server.IncomingMessage(Message.clone()).await;
1076
1077 let duration = start_time.elapsed();
1078
1079 ipc_server
1081 .record_performance_metrics(Message.channel, duration, result.is_ok())
1082 .await;
1083
1084 result
1085 } else {
1086 Err("IPC Server not found in application state".to_string())
1087 }
1088}
1089
1090#[tauri::command]
1102pub async fn mountain_ipc_get_status(app_handle:tauri::AppHandle) -> Result<ConnectionStatus, String> {
1103 if let Some(ipc_server) = app_handle.try_state::<TauriIPCServer>() {
1104 let connected = ipc_server
1105 .get_connection_status()
1106 .map_err(|e| format!("Failed to get connection status: {}", e))?;
1107
1108 Ok(ConnectionStatus { connected })
1109 } else {
1110 Err("IPC Server not found in application state".to_string())
1111 }
1112}
1113
1114#[derive(Debug, Clone, Serialize, Deserialize)]
1116pub struct SecurityContext {
1117 pub user_id:String,
1118
1119 pub roles:Vec<String>,
1120
1121 pub permissions:Vec<String>,
1122
1123 pub ip_address:String,
1124
1125 pub timestamp:std::time::SystemTime,
1126}
1127
1128pub struct PermissionManager {
1130 roles:Arc<RwLock<HashMap<String, Role>>>,
1131
1132 permissions:Arc<RwLock<HashMap<String, Permission>>>,
1133
1134 audit_log:Arc<RwLock<Vec<SecurityEvent>>>,
1135}
1136
1137#[derive(Debug, Clone, Serialize, Deserialize)]
1139pub struct SecurityEvent {
1140 pub event_type:SecurityEventType,
1141
1142 pub user_id:String,
1143
1144 pub operation:String,
1145
1146 pub timestamp:std::time::SystemTime,
1147
1148 pub details:Option<String>,
1149}
1150
1151#[derive(Debug, Clone, Serialize, Deserialize)]
1152pub enum SecurityEventType {
1153 PermissionDenied,
1154
1155 AccessGranted,
1156
1157 ConfigurationChange,
1158
1159 SecurityViolation,
1160
1161 PerformanceAnomaly,
1162}
1163
1164#[derive(Debug, Clone, Serialize, Deserialize)]
1166pub struct Role {
1167 pub name:String,
1168
1169 pub permissions:Vec<String>,
1170
1171 pub description:String,
1172}
1173
1174#[derive(Debug, Clone, Serialize, Deserialize)]
1176pub struct Permission {
1177 pub name:String,
1178
1179 pub description:String,
1180
1181 pub category:String,
1182}
1183
1184impl PermissionManager {
1185 pub fn new() -> Self {
1186 Self {
1187 roles:Arc::new(RwLock::new(HashMap::new())),
1188
1189 permissions:Arc::new(RwLock::new(HashMap::new())),
1190
1191 audit_log:Arc::new(RwLock::new(Vec::new())),
1192 }
1193 }
1194
1195 pub async fn validate_permission(&self, operation:&str, context:&SecurityContext) -> Result<(), String> {
1197 let required_permissions = self.get_required_permissions(operation).await;
1199
1200 if required_permissions.is_empty() {
1201 return Ok(()); }
1203
1204 let mut user_permissions:Vec<String> = context.permissions.iter().cloned().collect();
1206
1207 for role in context.roles.iter() {
1208 let role_perms = self.get_role_permissions(role).await;
1209
1210 user_permissions.extend(role_perms);
1211 }
1212
1213 for required in required_permissions {
1214 if !user_permissions.contains(&required) {
1215 return Err(format!("Missing permission: {}", required));
1216 }
1217 }
1218
1219 self.log_security_event(SecurityEvent {
1221 event_type:SecurityEventType::AccessGranted,
1222 user_id:context.user_id.clone(),
1223 operation:operation.to_string(),
1224 timestamp:std::time::SystemTime::now(),
1225 details:Some(format!("Access granted for operation: {}", operation)),
1226 })
1227 .await;
1228
1229 Ok(())
1230 }
1231
1232 async fn get_required_permissions(&self, operation:&str) -> Vec<String> {
1234 match operation {
1236 "file:write" | "file:delete" => vec!["file.write".to_string()],
1237
1238 "configuration:update" => vec!["config.update".to_string()],
1239
1240 "storage:set" => vec!["storage.write".to_string()],
1241
1242 "native:openExternal" => vec!["system.external".to_string()],
1243
1244 _ => Vec::new(),
1246 }
1247 }
1248
1249 async fn get_role_permissions(&self, role_name:&str) -> Vec<String> {
1251 let roles = self.roles.read().await;
1252
1253 roles.get(role_name).map(|role| role.permissions.clone()).unwrap_or_default()
1254 }
1255
1256 pub async fn log_security_event(&self, event:SecurityEvent) {
1258 let mut audit_log = self.audit_log.write().await;
1259
1260 audit_log.push(event);
1261
1262 if audit_log.len() > 1000 {
1264 audit_log.remove(0);
1265 }
1266 }
1267
1268 pub async fn get_audit_log(&self, limit:usize) -> Vec<SecurityEvent> {
1270 let audit_log = self.audit_log.read().await;
1271
1272 audit_log.iter().rev().take(limit).cloned().collect()
1273 }
1274
1275 pub async fn initialize_defaults(&self) {
1277 let mut permissions = self.permissions.write().await;
1278
1279 let mut roles = self.roles.write().await;
1280
1281 let standard_permissions = vec![
1283 ("file.read", "Read file operations"),
1284 ("file.write", "Write file operations"),
1285 ("config.read", "Read configuration"),
1286 ("config.update", "Update configuration"),
1287 ("storage.read", "Read storage"),
1288 ("storage.write", "Write storage"),
1289 ("system.external", "Access external system resources"),
1290 ];
1291
1292 for (name, description) in standard_permissions {
1293 permissions.insert(
1294 name.to_string(),
1295 Permission {
1296 name:name.to_string(),
1297 description:description.to_string(),
1298 category:"standard".to_string(),
1299 },
1300 );
1301 }
1302
1303 let standard_roles = vec![
1305 ("user", vec!["file.read", "config.read", "storage.read"]),
1306 (
1307 "developer",
1308 vec!["file.read", "file.write", "config.read", "storage.read", "storage.write"],
1309 ),
1310 (
1311 "admin",
1312 vec![
1313 "file.read",
1314 "file.write",
1315 "config.read",
1316 "config.update",
1317 "storage.read",
1318 "storage.write",
1319 "system.external",
1320 ],
1321 ),
1322 ];
1323
1324 for (name, role_permissions) in standard_roles {
1325 roles.insert(
1326 name.to_string(),
1327 Role {
1328 name:name.to_string(),
1329 permissions:role_permissions.iter().map(|p| p.to_string()).collect(),
1330 description:format!("{} role with standard permissions", name),
1331 },
1332 );
1333 }
1334 }
1335}