@@ -154,15 +154,97 @@ void FSPermission::Apply(Environment* env,
154154 }
155155}
156156
157+ void FSPermission::Drop (Environment* env,
158+ PermissionScope scope,
159+ const std::string_view& param) {
160+ if (param.empty ()) {
161+ // Drop all access for this scope
162+ if (scope == PermissionScope::kFileSystemRead ||
163+ scope == PermissionScope::kFileSystem ) {
164+ deny_all_in_ = true ;
165+ allow_all_in_ = false ;
166+ granted_in_fs_.Clear ();
167+ granted_paths_in_.clear ();
168+ }
169+ if (scope == PermissionScope::kFileSystemWrite ||
170+ scope == PermissionScope::kFileSystem ) {
171+ deny_all_out_ = true ;
172+ allow_all_out_ = false ;
173+ granted_out_fs_.Clear ();
174+ granted_paths_out_.clear ();
175+ }
176+ return ;
177+ }
178+
179+ // When allowed with *, you can only drop * (no specific paths)
180+ std::string resolved = PathResolve (env, {param});
181+ if (scope == PermissionScope::kFileSystemRead ||
182+ scope == PermissionScope::kFileSystem ) {
183+ if (!allow_all_in_) {
184+ RevokeAccess (PermissionScope::kFileSystemRead , resolved);
185+ }
186+ }
187+ if (scope == PermissionScope::kFileSystemWrite ||
188+ scope == PermissionScope::kFileSystem ) {
189+ if (!allow_all_out_) {
190+ RevokeAccess (PermissionScope::kFileSystemWrite , resolved);
191+ }
192+ }
193+ }
194+
195+ void FSPermission::RevokeAccess (PermissionScope perm,
196+ const std::string& res) {
197+ const std::string path = WildcardIfDir (res);
198+ if (perm == PermissionScope::kFileSystemRead ) {
199+ auto it = std::find (granted_paths_in_.begin (),
200+ granted_paths_in_.end (), path);
201+ if (it != granted_paths_in_.end ()) {
202+ granted_paths_in_.erase (it);
203+ RebuildTree (PermissionScope::kFileSystemRead );
204+ }
205+ } else if (perm == PermissionScope::kFileSystemWrite ) {
206+ auto it = std::find (granted_paths_out_.begin (),
207+ granted_paths_out_.end (), path);
208+ if (it != granted_paths_out_.end ()) {
209+ granted_paths_out_.erase (it);
210+ RebuildTree (PermissionScope::kFileSystemWrite );
211+ }
212+ }
213+ }
214+
215+ void FSPermission::RebuildTree (PermissionScope scope) {
216+ if (scope == PermissionScope::kFileSystemRead ) {
217+ granted_in_fs_.Clear ();
218+ if (granted_paths_in_.empty ()) {
219+ deny_all_in_ = true ;
220+ } else {
221+ for (const auto & path : granted_paths_in_) {
222+ granted_in_fs_.Insert (path);
223+ }
224+ }
225+ } else if (scope == PermissionScope::kFileSystemWrite ) {
226+ granted_out_fs_.Clear ();
227+ if (granted_paths_out_.empty ()) {
228+ deny_all_out_ = true ;
229+ } else {
230+ for (const auto & path : granted_paths_out_) {
231+ granted_out_fs_.Insert (path);
232+ }
233+ }
234+ }
235+ }
236+
157237void FSPermission::GrantAccess (PermissionScope perm, const std::string& res) {
158238 const std::string path = WildcardIfDir (res);
159239 if (perm == PermissionScope::kFileSystemRead &&
160240 !granted_in_fs_.Lookup (path)) {
161241 granted_in_fs_.Insert (path);
242+ granted_paths_in_.push_back (path);
162243 deny_all_in_ = false ;
163244 } else if (perm == PermissionScope::kFileSystemWrite &&
164245 !granted_out_fs_.Lookup (path)) {
165246 granted_out_fs_.Insert (path);
247+ granted_paths_out_.push_back (path);
166248 deny_all_out_ = false ;
167249 }
168250}
@@ -196,6 +278,16 @@ FSPermission::RadixTree::~RadixTree() {
196278 FreeRecursivelyNode (root_node_);
197279}
198280
281+ void FSPermission::RadixTree::Clear () {
282+ for (auto & c : root_node_->children ) {
283+ FreeRecursivelyNode (c.second );
284+ }
285+ root_node_->children .clear ();
286+ delete root_node_->wildcard_child ;
287+ root_node_->wildcard_child = nullptr ;
288+ root_node_->is_leaf = false ;
289+ }
290+
199291bool FSPermission::RadixTree::Lookup (const std::string_view& s,
200292 bool when_empty_return) const {
201293 FSPermission::RadixTree::Node* current_node = root_node_;
0 commit comments