Skip to content

Commit

Permalink
Merge branch 'eng-1413-full-access-perms-ui' of https://github.com/sp…
Browse files Browse the repository at this point in the history
…acedriveapp/spacedrive into eng-1413-full-access-perms-ui
  • Loading branch information
ameer2468 committed Nov 17, 2023
2 parents 25074b1 + f096735 commit 7914f4b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 34 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/desktop/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ async fn request_fda_macos() {
#[specta::specta]
// If this erorrs, we don't have FDA and we need to re-prompt for it otherwise we can't access personal directories.
async fn has_fda() -> bool {
FullDiskAccess::has_fda().await
FullDiskAccess::has_fda()
}

#[tauri::command(async)]
Expand Down
4 changes: 3 additions & 1 deletion crates/fda/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ edition = { workspace = true }

[dependencies]
dirs = "5.0.1"
tokio = { workspace = true, features = ["rt-multi-thread", "fs", "macros"] }
thiserror = "1.0.50"

[dev-dependencies]
tempfile = '3.8.1'
68 changes: 37 additions & 31 deletions crates/fda/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,42 +24,47 @@
#![forbid(unsafe_code, deprecated_in_future)]
#![allow(clippy::missing_errors_doc, clippy::module_name_repetitions)]

use std::{io::ErrorKind, path::PathBuf};

use dirs::{
audio_dir, cache_dir, config_dir, config_local_dir, data_dir, data_local_dir, desktop_dir,
document_dir, download_dir, executable_dir, home_dir, picture_dir, preference_dir, public_dir,
runtime_dir, state_dir, template_dir, video_dir,
};
use std::{fs, path::PathBuf};

pub mod error;

use error::Result;

pub struct FullDiskAccess(Vec<PathBuf>);

// TODO(brxken128): add `ErrorKind::ReadOnlyFilesystem` once stable
impl FullDiskAccess {
async fn can_access_path(path: PathBuf) -> bool {
match tokio::fs::read_dir(path).await {
Ok(_) => true,
Err(e) => matches!(e.kind(), ErrorKind::NotFound | ErrorKind::PermissionDenied,),
#[cfg(target_family = "unix")]
fn is_path_rw(path: PathBuf) -> bool {
use std::os::unix::fs::MetadataExt;

(fs::metadata(path)).map_or(false, |md| {
let mode = md.mode();
mode & 0x180 == 0x180 // rw access
})
}

#[cfg(target_family = "windows")]
pub(crate) fn is_path_rw(path: PathBuf) -> bool {
if let Ok(md) = fs::metadata(path) {
!md.permissions().readonly()
} else {
false
}
}

/// [`FullDiskAccess::has_fda`] needs to be checked each time we go to access a potentially protected directory, and we need to prompt for
/// FDA if we don't have it.
pub async fn has_fda() -> bool {
#[must_use]
pub fn has_fda() -> bool {
let dirs = Self::default();
for dir in dirs.0 {
if !Self::can_access_path(dir).await {
return false;
}
}
true
dirs.0.into_iter().all(Self::is_path_rw)
}

#[allow(clippy::missing_const_for_fn)]
pub fn request_fda() -> Result<()> {
#[cfg(target_os = "macos")]
{
Expand Down Expand Up @@ -98,19 +103,6 @@ impl Default for FullDiskAccess {
state_dir(),
template_dir(),
video_dir(),
Some(PathBuf::from(
"/System/Applications/Time Machine.app/Contents",
)),
Some(PathBuf::from("/System/Applications/Safari.app/Contents")),
Some(PathBuf::from(
"/System/Applications/System Weather/Contents",
)),
Some(PathBuf::from("/System/Applications/Safari.app/Contents")),
Some(PathBuf::from("/System/Applications/iMofie.app/Contents")),
Some(PathBuf::from(
"/System/Applications/System Settings.app/Contents",
)),
Some(PathBuf::from("/System/Applications/Siri.app/Contents")),
]
.into_iter()
.flatten()
Expand All @@ -121,6 +113,9 @@ impl Default for FullDiskAccess {

#[cfg(test)]
mod tests {
use std::fs;
use tempfile::tempdir;

use super::FullDiskAccess;

#[test]
Expand All @@ -130,8 +125,19 @@ mod tests {
FullDiskAccess::request_fda().unwrap();
}

#[tokio::test]
async fn has_fda() {
FullDiskAccess::has_fda().await;
#[test]
fn has_fda() {
assert!(FullDiskAccess::has_fda());
}

#[test]
#[should_panic(expected = "assertion failed")]
fn should_fail() {
let dir = tempdir().unwrap();
let path = dir.into_path();
let mut perms = fs::metadata(&path).unwrap().permissions();
perms.set_readonly(true);
fs::set_permissions(&path, perms).unwrap();
assert!(FullDiskAccess::is_path_rw(path));
}
}

0 comments on commit 7914f4b

Please sign in to comment.