1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CONTENT_PUBLIC_BROWSER_NATIVE_FILE_SYSTEM_PERMISSION_CONTEXT_H_
6 #define CONTENT_PUBLIC_BROWSER_NATIVE_FILE_SYSTEM_PERMISSION_CONTEXT_H_
7 
8 #include "base/files/file_path.h"
9 #include "content/public/browser/global_routing_id.h"
10 #include "content/public/browser/native_file_system_permission_grant.h"
11 #include "content/public/browser/native_file_system_write_item.h"
12 #include "url/origin.h"
13 
14 namespace content {
15 
16 // Entry point to an embedder implemented permission context for the Native File
17 // System API. Instances of this class can be retrieved via a BrowserContext.
18 // All these methods must always be called on the UI thread.
19 class NativeFileSystemPermissionContext {
20  public:
21   // The type of action a user took that resulted in needing a permission grant
22   // for a particular path. This is used to signal to the permission context if
23   // the path was the result of a "save" operation, which an implementation can
24   // use to automatically grant write access to the path.
25   enum class UserAction {
26     // The path for which a permission grant is requested was the result of a
27     // "open" dialog. As such, only read access to files should be automatically
28     // granted, but read access to directories as well as write access to files
29     // or directories should not be granted without needing to request it.
30     kOpen,
31     // The path for which a permission grant is requested was the result of a
32     // "save" dialog, and as such it could make sense to return a grant that
33     // immediately allows write access without needing to request it.
34     kSave,
35     // The path for which a permission grant is requested was the result of
36     // loading a handle from storage. As such the grant should not start out
37     // as granted, even for read access.
38     kLoadFromStorage,
39     // The path for which a permission grant is requested was the result of a
40     // drag&drop operation. Read access should start out granted, but write
41     // access will require a prompt.
42     kDragAndDrop,
43   };
44 
45   // This enum helps distinguish between file or directory Native File System
46   // handles.
47   enum class HandleType { kFile, kDirectory };
48 
49   enum class PathType {
50     // A path on the local file system. Files with these paths can be operated
51     // on by base::File.
52     kLocal,
53 
54     // A path on an "external" file system. These paths can only be accessed via
55     // the filesystem abstraction in //storage/browser/file_system, and a
56     // storage::FileSystemURL of type storage::kFileSystemTypeExternal.
57     // This path type should be used for paths retrieved via the `virtual_path`
58     // member of a ui::SelectedFileInfo struct.
59     kExternal
60   };
61 
62   // Returns the read permission grant to use for a particular path.
63   virtual scoped_refptr<NativeFileSystemPermissionGrant> GetReadPermissionGrant(
64       const url::Origin& origin,
65       const base::FilePath& path,
66       HandleType handle_type,
67       UserAction user_action) = 0;
68 
69   // Returns the permission grant to use for a particular path. This could be a
70   // grant that applies to more than just the path passed in, for example if a
71   // user has already granted write access to a directory, this method could
72   // return that existing grant when figuring the grant to use for a file in
73   // that directory.
74   virtual scoped_refptr<NativeFileSystemPermissionGrant>
75   GetWritePermissionGrant(const url::Origin& origin,
76                           const base::FilePath& path,
77                           HandleType handle_type,
78                           UserAction user_action) = 0;
79 
80   // These values are persisted to logs. Entries should not be renumbered and
81   // numeric values should never be reused.
82   enum class SensitiveDirectoryResult {
83     kAllowed = 0,   // Access to directory is okay.
84     kTryAgain = 1,  // User should pick a different directory.
85     kAbort = 2,     // Abandon entirely, as if picking was cancelled.
86     kMaxValue = kAbort
87   };
88   // Checks if access to the given |path| should be allowed or blocked. This is
89   // used to implement blocks for certain sensitive directories such as the
90   // "Windows" system directory, as well as the root of the "home" directory.
91   // Calls |callback| with the result of the check, after potentially showing
92   // some UI to the user if the path should not be accessed.
93   virtual void ConfirmSensitiveDirectoryAccess(
94       const url::Origin& origin,
95       PathType path_type,
96       const base::FilePath& path,
97       HandleType handle_type,
98       GlobalFrameRoutingId frame_id,
99       base::OnceCallback<void(SensitiveDirectoryResult)> callback) = 0;
100 
101   enum class AfterWriteCheckResult { kAllow, kBlock };
102   // Runs a recently finished write operation through checks such as malware
103   // or other security checks to determine if the write should be allowed.
104   virtual void PerformAfterWriteChecks(
105       std::unique_ptr<NativeFileSystemWriteItem> item,
106       GlobalFrameRoutingId frame_id,
107       base::OnceCallback<void(AfterWriteCheckResult)> callback) = 0;
108 
109   // Returns whether the give |origin| already allows read permission, or it is
110   // possible to request one. This is used to block file dialogs from being
111   // shown if permission won't be granted anyway.
112   virtual bool CanObtainReadPermission(const url::Origin& origin) = 0;
113 
114   // Returns whether the give |origin| already allows write permission, or it is
115   // possible to request one. This is used to block save file dialogs from being
116   // shown if there is no need to ask for it.
117   virtual bool CanObtainWritePermission(const url::Origin& origin) = 0;
118 
119   // Store the directory recently chosen using a file picker.
120   virtual void SetLastPickedDirectory(const url::Origin& origin,
121                                       const base::FilePath& path) = 0;
122   // Returns the directory recently chosen using a file picker.
123   virtual base::FilePath GetLastPickedDirectory(const url::Origin& origin) = 0;
124   // Return the default directory used by the File System Access API.
125   virtual base::FilePath GetDefaultDirectory() = 0;
126 
127  protected:
128   virtual ~NativeFileSystemPermissionContext() = default;
129 };
130 
131 }  // namespace content
132 
133 #endif  // CONTENT_PUBLIC_BROWSER_NATIVE_FILE_SYSTEM_PERMISSION_CONTEXT_H_
134