55use std:: {
66 fmt,
77 path:: { Path , PathBuf } ,
8+ sync:: { Arc , Mutex } ,
89} ;
910
1011use glob:: Pattern ;
@@ -18,7 +19,7 @@ use crate::api::path::parse as parse_path;
1819/// Scope for filesystem access.
1920#[ derive( Clone ) ]
2021pub struct Scope {
21- allow_patterns : Vec < Pattern > ,
22+ allow_patterns : Arc < Mutex < Vec < Pattern > > > ,
2223}
2324
2425impl fmt:: Debug for Scope {
@@ -28,6 +29,8 @@ impl fmt::Debug for Scope {
2829 "allow_patterns" ,
2930 & self
3031 . allow_patterns
32+ . lock ( )
33+ . unwrap ( )
3134 . iter ( )
3235 . map ( |p| p. as_str ( ) )
3336 . collect :: < Vec < & str > > ( ) ,
@@ -36,6 +39,16 @@ impl fmt::Debug for Scope {
3639 }
3740}
3841
42+ fn push_pattern < P : AsRef < Path > > ( list : & mut Vec < Pattern > , pattern : P ) {
43+ let pattern: PathBuf = pattern. as_ref ( ) . components ( ) . collect ( ) ;
44+ list. push ( Pattern :: new ( & pattern. to_string_lossy ( ) ) . expect ( "invalid glob pattern" ) ) ;
45+ #[ cfg( windows) ]
46+ {
47+ list
48+ . push ( Pattern :: new ( & format ! ( "\\ \\ ?\\ {}" , pattern. display( ) ) ) . expect ( "invalid glob pattern" ) ) ;
49+ }
50+ }
51+
3952impl Scope {
4053 /// Creates a new scope from a `FsAllowlistScope` configuration.
4154 pub fn for_fs_api (
@@ -47,17 +60,33 @@ impl Scope {
4760 let mut allow_patterns = Vec :: new ( ) ;
4861 for path in & scope. 0 {
4962 if let Ok ( path) = parse_path ( config, package_info, env, path) {
50- let path: PathBuf = path. components ( ) . collect ( ) ;
51- allow_patterns. push ( Pattern :: new ( & path. to_string_lossy ( ) ) . expect ( "invalid glob pattern" ) ) ;
52- #[ cfg( windows) ]
53- {
54- allow_patterns. push (
55- Pattern :: new ( & format ! ( "\\ \\ ?\\ {}" , path. display( ) ) ) . expect ( "invalid glob pattern" ) ,
56- ) ;
57- }
63+ push_pattern ( & mut allow_patterns, path) ;
5864 }
5965 }
60- Self { allow_patterns }
66+ Self {
67+ allow_patterns : Arc :: new ( Mutex :: new ( allow_patterns) ) ,
68+ }
69+ }
70+
71+ /// Extend the allowed patterns with the given directory.
72+ ///
73+ /// After this function has been called, the frontend will be able to use the Tauri API to read
74+ /// the directory and all of its files and subdirectories.
75+ pub fn allow_directory < P : AsRef < Path > > ( & self , path : P , recursive : bool ) {
76+ let path = path. as_ref ( ) . to_path_buf ( ) ;
77+ let mut list = self . allow_patterns . lock ( ) . unwrap ( ) ;
78+
79+ // allow the directory to be read
80+ push_pattern ( & mut list, & path) ;
81+ // allow its files and subdirectories to be read
82+ push_pattern ( & mut list, path. join ( if recursive { "**" } else { "*" } ) ) ;
83+ }
84+
85+ /// Extend the allowed patterns with the given file path.
86+ ///
87+ /// After this function has been called, the frontend will be able to use the Tauri API to read the contents of this file.
88+ pub fn allow_file < P : AsRef < Path > > ( & self , path : P ) {
89+ push_pattern ( & mut self . allow_patterns . lock ( ) . unwrap ( ) , path) ;
6190 }
6291
6392 /// Determines if the given path is allowed on this scope.
@@ -71,7 +100,12 @@ impl Scope {
71100
72101 if let Ok ( path) = path {
73102 let path: PathBuf = path. components ( ) . collect ( ) ;
74- let allowed = self . allow_patterns . iter ( ) . any ( |p| p. matches_path ( & path) ) ;
103+ let allowed = self
104+ . allow_patterns
105+ . lock ( )
106+ . unwrap ( )
107+ . iter ( )
108+ . any ( |p| p. matches_path ( & path) ) ;
75109 allowed
76110 } else {
77111 false
0 commit comments