Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: chrome/browser/extensions/api/file_handlers/app_file_handler_util.cc

Issue 23146016: Add support for directory access to the file system API. (Closed) Base URL: http://git.chromium.org/chromium/src.git@simpler-write-permissions
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" 5 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "chrome/browser/extensions/extension_prefs.h" 9 #include "chrome/browser/extensions/extension_prefs.h"
10 #include "content/public/browser/browser_thread.h" 10 #include "content/public/browser/browser_thread.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 const FileHandlerInfo& handler, 52 const FileHandlerInfo& handler,
53 const std::string& mime_type) { 53 const std::string& mime_type) {
54 for (std::set<std::string>::const_iterator type = handler.types.begin(); 54 for (std::set<std::string>::const_iterator type = handler.types.begin();
55 type != handler.types.end(); ++type) { 55 type != handler.types.end(); ++type) {
56 if (net::MatchesMimeType(*type, mime_type)) 56 if (net::MatchesMimeType(*type, mime_type))
57 return true; 57 return true;
58 } 58 }
59 return false; 59 return false;
60 } 60 }
61 61
62 bool DoCheckWritableFile(const base::FilePath& path) { 62 bool DoCheckWritableFile(const base::FilePath& path, bool is_directory) {
63 // Don't allow links. 63 // Don't allow links.
64 if (base::PathExists(path) && file_util::IsLink(path)) 64 if (base::PathExists(path) && file_util::IsLink(path))
65 return false; 65 return false;
66 66
67 if (is_directory)
68 return base::DirectoryExists(path);
69
67 // Create the file if it doesn't already exist. 70 // Create the file if it doesn't already exist.
68 base::PlatformFileError error = base::PLATFORM_FILE_OK; 71 base::PlatformFileError error = base::PLATFORM_FILE_OK;
69 int creation_flags = base::PLATFORM_FILE_CREATE | 72 int creation_flags = base::PLATFORM_FILE_CREATE |
70 base::PLATFORM_FILE_READ | 73 base::PLATFORM_FILE_READ |
71 base::PLATFORM_FILE_WRITE; 74 base::PLATFORM_FILE_WRITE;
72 base::PlatformFile file = base::CreatePlatformFile(path, creation_flags, 75 base::PlatformFile file = base::CreatePlatformFile(path, creation_flags,
73 NULL, &error); 76 NULL, &error);
74 // Close the file so we don't keep a lock open. 77 // Close the file so we don't keep a lock open.
75 if (file != base::kInvalidPlatformFileValue) 78 if (file != base::kInvalidPlatformFileValue)
76 base::ClosePlatformFile(file); 79 base::ClosePlatformFile(file);
77 if (error != base::PLATFORM_FILE_OK && 80 if (error != base::PLATFORM_FILE_OK &&
78 error != base::PLATFORM_FILE_ERROR_EXISTS) { 81 error != base::PLATFORM_FILE_ERROR_EXISTS) {
79 return false; 82 return false;
80 } 83 }
81 84
82 return true; 85 return true;
83 } 86 }
84 87
85 // Checks whether a list of paths are all OK for writing and calls a provided 88 // Checks whether a list of paths are all OK for writing and calls a provided
86 // on_success or on_failure callback when done. A file is OK for writing if it 89 // on_success or on_failure callback when done. A file is OK for writing if it
87 // is not a symlink, is not in a blacklisted path and can be opened for writing; 90 // is not a symlink, is not in a blacklisted path and can be opened for writing;
88 // files are created if they do not exist. 91 // files are created if they do not exist.
89 class WritableFileChecker 92 class WritableFileChecker
90 : public base::RefCountedThreadSafe<WritableFileChecker> { 93 : public base::RefCountedThreadSafe<WritableFileChecker> {
91 public: 94 public:
92 WritableFileChecker( 95 WritableFileChecker(
93 const std::vector<base::FilePath>& paths, 96 const std::vector<base::FilePath>& paths,
94 Profile* profile, 97 Profile* profile,
98 bool is_directory,
95 const base::Closure& on_success, 99 const base::Closure& on_success,
96 const base::Callback<void(const base::FilePath&)>& on_failure); 100 const base::Callback<void(const base::FilePath&)>& on_failure);
97 101
98 void Check(); 102 void Check();
99 103
100 private: 104 private:
101 friend class base::RefCountedThreadSafe<WritableFileChecker>; 105 friend class base::RefCountedThreadSafe<WritableFileChecker>;
102 virtual ~WritableFileChecker(); 106 virtual ~WritableFileChecker();
103 107
104 // Called when a work item is completed. If all work items are done, this 108 // Called when a work item is completed. If all work items are done, this
105 // calls the success or failure callback. 109 // calls the success or failure callback.
106 void TaskDone(); 110 void TaskDone();
107 111
108 // Reports an error in completing a work item. This may be called more than 112 // Reports an error in completing a work item. This may be called more than
109 // once, but only the last message will be retained. 113 // once, but only the last message will be retained.
110 void Error(const base::FilePath& error_path); 114 void Error(const base::FilePath& error_path);
111 115
112 void CheckLocalWritableFiles(); 116 void CheckLocalWritableFiles();
113 117
114 #if defined(OS_CHROMEOS) 118 #if defined(OS_CHROMEOS)
115 void CheckRemoteWritableFile(const base::FilePath& remote_path, 119 void CheckRemoteWritableFile(const base::FilePath& remote_path,
116 drive::FileError error, 120 drive::FileError error,
117 const base::FilePath& local_path); 121 const base::FilePath& local_path);
118 #endif 122 #endif
119 123
120 const std::vector<base::FilePath> paths_; 124 const std::vector<base::FilePath> paths_;
121 Profile* profile_; 125 Profile* profile_;
126 const bool is_directory_;
122 int outstanding_tasks_; 127 int outstanding_tasks_;
123 base::FilePath error_path_; 128 base::FilePath error_path_;
124 base::Closure on_success_; 129 base::Closure on_success_;
125 base::Callback<void(const base::FilePath&)> on_failure_; 130 base::Callback<void(const base::FilePath&)> on_failure_;
126 }; 131 };
127 132
128 WritableFileChecker::WritableFileChecker( 133 WritableFileChecker::WritableFileChecker(
129 const std::vector<base::FilePath>& paths, 134 const std::vector<base::FilePath>& paths,
130 Profile* profile, 135 Profile* profile,
136 bool is_directory,
131 const base::Closure& on_success, 137 const base::Closure& on_success,
132 const base::Callback<void(const base::FilePath&)>& on_failure) 138 const base::Callback<void(const base::FilePath&)>& on_failure)
133 : paths_(paths), 139 : paths_(paths),
134 profile_(profile), 140 profile_(profile),
141 is_directory_(is_directory),
135 outstanding_tasks_(1), 142 outstanding_tasks_(1),
136 on_success_(on_success), 143 on_success_(on_success),
137 on_failure_(on_failure) {} 144 on_failure_(on_failure) {}
138 145
139 void WritableFileChecker::Check() { 146 void WritableFileChecker::Check() {
140 #if defined(OS_CHROMEOS) 147 #if defined(OS_CHROMEOS)
141 if (drive::util::IsUnderDriveMountPoint(paths_[0])) { 148 if (drive::util::IsUnderDriveMountPoint(paths_[0])) {
142 outstanding_tasks_ = paths_.size(); 149 outstanding_tasks_ = paths_.size();
143 for (std::vector<base::FilePath>::const_iterator it = paths_.begin(); 150 for (std::vector<base::FilePath>::const_iterator it = paths_.begin();
144 it != paths_.end(); 151 it != paths_.end();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 error_path_ = error_path; 184 error_path_ = error_path;
178 TaskDone(); 185 TaskDone();
179 } 186 }
180 187
181 void WritableFileChecker::CheckLocalWritableFiles() { 188 void WritableFileChecker::CheckLocalWritableFiles() {
182 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 189 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
183 std::string error; 190 std::string error;
184 for (std::vector<base::FilePath>::const_iterator it = paths_.begin(); 191 for (std::vector<base::FilePath>::const_iterator it = paths_.begin();
185 it != paths_.end(); 192 it != paths_.end();
186 ++it) { 193 ++it) {
187 if (!DoCheckWritableFile(*it)) { 194 if (!DoCheckWritableFile(*it, is_directory_)) {
188 content::BrowserThread::PostTask( 195 content::BrowserThread::PostTask(
189 content::BrowserThread::UI, 196 content::BrowserThread::UI,
190 FROM_HERE, 197 FROM_HERE,
191 base::Bind(&WritableFileChecker::Error, this, *it)); 198 base::Bind(&WritableFileChecker::Error, this, *it));
192 return; 199 return;
193 } 200 }
194 } 201 }
195 content::BrowserThread::PostTask( 202 content::BrowserThread::PostTask(
196 content::BrowserThread::UI, 203 content::BrowserThread::UI,
197 FROM_HERE, 204 FROM_HERE,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 const std::string& mime_type, 290 const std::string& mime_type,
284 const base::FilePath& path) { 291 const base::FilePath& path) {
285 return FileHandlerCanHandleFileWithMimeType(handler, mime_type) || 292 return FileHandlerCanHandleFileWithMimeType(handler, mime_type) ||
286 FileHandlerCanHandleFileWithExtension(handler, path); 293 FileHandlerCanHandleFileWithExtension(handler, path);
287 } 294 }
288 295
289 GrantedFileEntry CreateFileEntry( 296 GrantedFileEntry CreateFileEntry(
290 Profile* profile, 297 Profile* profile,
291 const Extension* extension, 298 const Extension* extension,
292 int renderer_id, 299 int renderer_id,
293 const base::FilePath& path) { 300 const base::FilePath& path,
301 bool is_directory) {
294 GrantedFileEntry result; 302 GrantedFileEntry result;
295 fileapi::IsolatedContext* isolated_context = 303 fileapi::IsolatedContext* isolated_context =
296 fileapi::IsolatedContext::GetInstance(); 304 fileapi::IsolatedContext::GetInstance();
297 DCHECK(isolated_context); 305 DCHECK(isolated_context);
298 306
299 result.filesystem_id = isolated_context->RegisterFileSystemForPath( 307 result.filesystem_id = isolated_context->RegisterFileSystemForPath(
300 fileapi::kFileSystemTypeNativeForPlatformApp, path, 308 fileapi::kFileSystemTypeNativeForPlatformApp, path,
301 &result.registered_name); 309 &result.registered_name);
302 310
303 content::ChildProcessSecurityPolicy* policy = 311 content::ChildProcessSecurityPolicy* policy =
304 content::ChildProcessSecurityPolicy::GetInstance(); 312 content::ChildProcessSecurityPolicy::GetInstance();
305 policy->GrantReadFileSystem(renderer_id, result.filesystem_id); 313 policy->GrantReadFileSystem(renderer_id, result.filesystem_id);
306 if (HasFileSystemWritePermission(extension)) 314 if (HasFileSystemWritePermission(extension)) {
307 policy->GrantWriteFileSystem(renderer_id, result.filesystem_id); 315 policy->GrantWriteFileSystem(renderer_id, result.filesystem_id);
316 if (is_directory)
317 policy->GrantCreateFileForFileSystem(renderer_id, result.filesystem_id);
318 }
308 319
309 result.id = result.filesystem_id + ":" + result.registered_name; 320 result.id = result.filesystem_id + ":" + result.registered_name;
310 return result; 321 return result;
311 } 322 }
312 323
313 void CheckWritableFiles( 324 void CheckWritableFiles(
314 const std::vector<base::FilePath>& paths, 325 const std::vector<base::FilePath>& paths,
315 Profile* profile, 326 Profile* profile,
327 bool is_directory,
316 const base::Closure& on_success, 328 const base::Closure& on_success,
317 const base::Callback<void(const base::FilePath&)>& on_failure) { 329 const base::Callback<void(const base::FilePath&)>& on_failure) {
318 scoped_refptr<WritableFileChecker> checker( 330 scoped_refptr<WritableFileChecker> checker(new WritableFileChecker(
319 new WritableFileChecker(paths, profile, on_success, on_failure)); 331 paths, profile, is_directory, on_success, on_failure));
320 checker->Check(); 332 checker->Check();
321 } 333 }
322 334
335 GrantedFileEntry::GrantedFileEntry() {}
336
323 bool HasFileSystemWritePermission(const Extension* extension) { 337 bool HasFileSystemWritePermission(const Extension* extension) {
324 return extension->HasAPIPermission(APIPermission::kFileSystemWrite); 338 return extension->HasAPIPermission(APIPermission::kFileSystemWrite);
325 } 339 }
326 340
327 } // namespace app_file_handler_util 341 } // namespace app_file_handler_util
328 342
329 } // namespace extensions 343 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698