Skip to main content

Mountain/Environment/
FileSystemProvider.rs

1//! # FileSystemProvider (Environment)
2//!
3//! RESPONSIBILITIES:
4//! - Implements
5//!   [`FileSystemReader`](CommonLibrary::FileSystem::FileSystemReader) and
6//!   [`FileSystemWriter`](CommonLibrary::FileSystem::FileSystemWriter) for
7//! `MountainEnvironment`
8//! - Provides secure, validated filesystem access with workspace trust
9//!   enforcement
10//! - Handles file operations: read, write, stat, delete, rename, copy,
11//!   directory traversal
12//! - Detects and handles symbolic links properly
13//! - Enforces path validation to prevent directory traversal attacks
14//!
15//! SECURITY MODEL:
16//! - Sandboxed filesystem access limited to registered workspace folders
17//! - All operations call `Utility::IsPathAllowedForAccess` first
18//! - Requires workspace trust to be enabled for any file access
19//! - Path normalization prevents `../` attacks
20//! - Symbolic link detection avoids following untrusted links outside
21//!   workspaces
22//!
23//! ERROR HANDLING:
24//! - Uses [`CommonError`](CommonLibrary::Error::CommonError) for all operations
25//! - File operation errors are mapped via `CommonError::FromStandardIOError`
26//! - Validates paths are within workspace boundaries (IsPathAllowedForAccess)
27//! - Rejects directory reads when file expected (ReadFile)
28//!
29//! PERFORMANCE:
30//! - Uses async tokio::fs for non-blocking I/O operations
31//! - Symbolic link detection uses `symlink_metadata` in addition to `metadata`
32//! - TODO: Consider caching file metadata for frequently accessed files
33//!
34//! VS CODE REFERENCE:
35//! - `vs/workbench/services/files/electron-browser/diskFileSystemProvider.ts` -
36//!   secure FS access
37//! - `vs/platform/files/common/files.ts` - file system interfaces
38//! - `vs/base/common/network.ts` - URI and path handling
39//!
40//! TODO:
41//! - Implement filesystem change watching (notify, inotify, FSEvents)
42//! - Add path normalization to prevent directory traversal
43//! - Implement proper symbolic link resolution with security checks
44//! - Add support for file permissions and ownership metadata
45//! - Implement atomic file writes using temp file + rename pattern
46//! - Add filesystem usage statistics (disk space, file counts)
47//! - Implement file attribute querying (hidden, readonly, executable)
48//! - Add support for extended file attributes on Unix/macOS
49//! - Consider adding filesystem cache for metadata
50//! - Implement trash operation using platform trash API (not delete)
51//! - Add support for file system encoding detection
52//! - Implement case sensitivity handling based on filesystem type
53//!
54//! MODULE STRUCTURE:
55//! - [`ReadOperations.rs`](ReadOperations.rs) - `FileSystemReader`
56//!   implementation
57//! - [`WriteOperations.rs`](WriteOperations.rs) - `FileSystemWriter`
58//!   implementation
59
60use std::path::PathBuf;
61
62use CommonLibrary::{
63	Error::CommonError::CommonError,
64	FileSystem::{
65		DTO::{FileSystemStatDTO::FileSystemStatDTO, FileTypeDTO::FileTypeDTO},
66		FileSystemReader::FileSystemReader,
67		FileSystemWriter::FileSystemWriter,
68	},
69};
70use async_trait::async_trait;
71
72use super::MountainEnvironment::MountainEnvironment;
73
74// Private submodules containing the actual implementation
75#[path = "FileSystemProvider/ReadOperations.rs"]
76mod ReadOperations;
77#[path = "FileSystemProvider/WriteOperations.rs"]
78mod WriteOperations;
79
80#[async_trait]
81impl FileSystemReader for MountainEnvironment {
82	/// Delegates to ReadOperations module
83	async fn ReadFile(&self, path:&PathBuf) -> Result<Vec<u8>, CommonError> {
84		ReadOperations::read_file_impl(self, path).await
85	}
86
87	/// Delegates to ReadOperations module
88	async fn StatFile(&self, path:&PathBuf) -> Result<FileSystemStatDTO, CommonError> {
89		ReadOperations::stat_file_impl(self, path).await
90	}
91
92	/// Delegates to ReadOperations module
93	async fn ReadDirectory(&self, path:&PathBuf) -> Result<Vec<(String, FileTypeDTO)>, CommonError> {
94		ReadOperations::read_directory_impl(self, path).await
95	}
96}
97
98#[async_trait]
99impl FileSystemWriter for MountainEnvironment {
100	/// Delegates to WriteOperations module
101	async fn WriteFile(&self, path:&PathBuf, content:Vec<u8>, create:bool, overwrite:bool) -> Result<(), CommonError> {
102		WriteOperations::write_file_impl(self, path, content, create, overwrite).await
103	}
104
105	/// Delegates to WriteOperations module
106	async fn CreateDirectory(&self, path:&PathBuf, recursive:bool) -> Result<(), CommonError> {
107		WriteOperations::create_directory_impl(self, path, recursive).await
108	}
109
110	/// Delegates to WriteOperations module
111	async fn Delete(&self, path:&PathBuf, recursive:bool, use_trash:bool) -> Result<(), CommonError> {
112		WriteOperations::delete_impl(self, path, recursive, use_trash).await
113	}
114
115	/// Delegates to WriteOperations module
116	async fn Rename(&self, source:&PathBuf, target:&PathBuf, overwrite:bool) -> Result<(), CommonError> {
117		WriteOperations::rename_impl(self, source, target, overwrite).await
118	}
119
120	/// Delegates to WriteOperations module
121	async fn Copy(&self, source:&PathBuf, target:&PathBuf, overwrite:bool) -> Result<(), CommonError> {
122		WriteOperations::copy_impl(self, source, target, overwrite).await
123	}
124
125	/// Delegates to WriteOperations module
126	async fn CreateFile(&self, path:&PathBuf) -> Result<(), CommonError> {
127		WriteOperations::create_file_impl(self, path).await
128	}
129}