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

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 // CreateDirectory returns true if the directory already exists.
69 return file_util::CreateDirectory(path);
benwells 2013/08/29 00:04:24 I'm not sure about this. Can we return file_util::
Sam McNally 2013/08/29 00:16:08 Done.
70
67 // Create the file if it doesn't already exist. 71 // Create the file if it doesn't already exist.
68 base::PlatformFileError error = base::PLATFORM_FILE_OK; 72 base::PlatformFileError error = base::PLATFORM_FILE_OK;
69 int creation_flags = base::PLATFORM_FILE_CREATE | 73 int creation_flags = base::PLATFORM_FILE_CREATE |
70 base::PLATFORM_FILE_READ | 74 base::PLATFORM_FILE_READ |
71 base::PLATFORM_FILE_WRITE; 75 base::PLATFORM_FILE_WRITE;
72 base::PlatformFile file = base::CreatePlatformFile(path, creation_flags, 76 base::PlatformFile file = base::CreatePlatformFile(path, creation_flags,
73 NULL, &error); 77 NULL, &error);
74 // Close the file so we don't keep a lock open. 78 // Close the file so we don't keep a lock open.
75 if (file != base::kInvalidPlatformFileValue) 79 if (file != base::kInvalidPlatformFileValue)
76 base::ClosePlatformFile(file); 80 base::ClosePlatformFile(file);
77 if (error != base::PLATFORM_FILE_OK && 81 if (error != base::PLATFORM_FILE_OK &&
78 error != base::PLATFORM_FILE_ERROR_EXISTS) { 82 error != base::PLATFORM_FILE_ERROR_EXISTS) {
79 return false; 83 return false;
80 } 84 }
81 85
82 return true; 86 return true;
83 } 87 }
84 88
85 // Checks whether a list of paths are all OK for writing and calls a provided 89 // 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 90 // 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; 91 // 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. 92 // files are created if they do not exist.
89 class WritableFileChecker 93 class WritableFileChecker
90 : public base::RefCountedThreadSafe<WritableFileChecker> { 94 : public base::RefCountedThreadSafe<WritableFileChecker> {
91 public: 95 public:
92 WritableFileChecker( 96 WritableFileChecker(
93 const std::vector<base::FilePath>& paths, 97 const std::vector<base::FilePath>& paths,
94 Profile* profile, 98 Profile* profile,
99 bool is_directory,
95 const base::Closure& on_success, 100 const base::Closure& on_success,
96 const base::Callback<void(const base::FilePath&)>& on_failure); 101 const base::Callback<void(const base::FilePath&)>& on_failure);
97 102
98 void Check(); 103 void Check();
99 104
100 private: 105 private:
101 friend class base::RefCountedThreadSafe<WritableFileChecker>; 106 friend class base::RefCountedThreadSafe<WritableFileChecker>;
102 virtual ~WritableFileChecker(); 107 virtual ~WritableFileChecker();
103 108
104 // Called when a work item is completed. If all work items are done, this 109 // Called when a work item is completed. If all work items are done, this
105 // calls the success or failure callback. 110 // calls the success or failure callback.
106 void TaskDone(); 111 void TaskDone();
107 112
108 // Reports an error in completing a work item. This may be called more than 113 // Reports an error in completing a work item. This may be called more than
109 // once, but only the last message will be retained. 114 // once, but only the last message will be retained.
110 void Error(const base::FilePath& error_path); 115 void Error(const base::FilePath& error_path);
111 116
112 void CheckLocalWritableFiles(); 117 void CheckLocalWritableFiles();
113 118
114 #if defined(OS_CHROMEOS) 119 #if defined(OS_CHROMEOS)
115 void CheckRemoteWritableFile(const base::FilePath& remote_path, 120 void CheckRemoteWritableFile(const base::FilePath& remote_path,
116 drive::FileError error, 121 drive::FileError error,
117 const base::FilePath& local_path); 122 const base::FilePath& local_path);
118 #endif 123 #endif
119 124
120 const std::vector<base::FilePath> paths_; 125 const std::vector<base::FilePath> paths_;
121 Profile* profile_; 126 Profile* profile_;
127 const bool is_directory_;
122 int outstanding_tasks_; 128 int outstanding_tasks_;
123 base::FilePath error_path_; 129 base::FilePath error_path_;
124 base::Closure on_success_; 130 base::Closure on_success_;
125 base::Callback<void(const base::FilePath&)> on_failure_; 131 base::Callback<void(const base::FilePath&)> on_failure_;
126 }; 132 };
127 133
128 WritableFileChecker::WritableFileChecker( 134 WritableFileChecker::WritableFileChecker(
129 const std::vector<base::FilePath>& paths, 135 const std::vector<base::FilePath>& paths,
130 Profile* profile, 136 Profile* profile,
137 bool is_directory,
131 const base::Closure& on_success, 138 const base::Closure& on_success,
132 const base::Callback<void(const base::FilePath&)>& on_failure) 139 const base::Callback<void(const base::FilePath&)>& on_failure)
133 : paths_(paths), 140 : paths_(paths),
134 profile_(profile), 141 profile_(profile),
142 is_directory_(is_directory),
135 outstanding_tasks_(1), 143 outstanding_tasks_(1),
136 on_success_(on_success), 144 on_success_(on_success),
137 on_failure_(on_failure) {} 145 on_failure_(on_failure) {}
138 146
139 void WritableFileChecker::Check() { 147 void WritableFileChecker::Check() {
140 #if defined(OS_CHROMEOS) 148 #if defined(OS_CHROMEOS)
141 if (drive::util::IsUnderDriveMountPoint(paths_[0])) { 149 if (drive::util::IsUnderDriveMountPoint(paths_[0])) {
142 outstanding_tasks_ = paths_.size(); 150 outstanding_tasks_ = paths_.size();
143 for (std::vector<base::FilePath>::const_iterator it = paths_.begin(); 151 for (std::vector<base::FilePath>::const_iterator it = paths_.begin();
144 it != paths_.end(); 152 it != paths_.end();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 error_path_ = error_path; 185 error_path_ = error_path;
178 TaskDone(); 186 TaskDone();
179 } 187 }
180 188
181 void WritableFileChecker::CheckLocalWritableFiles() { 189 void WritableFileChecker::CheckLocalWritableFiles() {
182 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 190 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
183 std::string error; 191 std::string error;
184 for (std::vector<base::FilePath>::const_iterator it = paths_.begin(); 192 for (std::vector<base::FilePath>::const_iterator it = paths_.begin();
185 it != paths_.end(); 193 it != paths_.end();
186 ++it) { 194 ++it) {
187 if (!DoCheckWritableFile(*it)) { 195 if (!DoCheckWritableFile(*it, is_directory_)) {
188 content::BrowserThread::PostTask( 196 content::BrowserThread::PostTask(
189 content::BrowserThread::UI, 197 content::BrowserThread::UI,
190 FROM_HERE, 198 FROM_HERE,
191 base::Bind(&WritableFileChecker::Error, this, *it)); 199 base::Bind(&WritableFileChecker::Error, this, *it));
192 return; 200 return;
193 } 201 }
194 } 202 }
195 content::BrowserThread::PostTask( 203 content::BrowserThread::PostTask(
196 content::BrowserThread::UI, 204 content::BrowserThread::UI,
197 FROM_HERE, 205 FROM_HERE,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 const std::string& mime_type, 291 const std::string& mime_type,
284 const base::FilePath& path) { 292 const base::FilePath& path) {
285 return FileHandlerCanHandleFileWithMimeType(handler, mime_type) || 293 return FileHandlerCanHandleFileWithMimeType(handler, mime_type) ||
286 FileHandlerCanHandleFileWithExtension(handler, path); 294 FileHandlerCanHandleFileWithExtension(handler, path);
287 } 295 }
288 296
289 GrantedFileEntry CreateFileEntry( 297 GrantedFileEntry CreateFileEntry(
290 Profile* profile, 298 Profile* profile,
291 const Extension* extension, 299 const Extension* extension,
292 int renderer_id, 300 int renderer_id,
293 const base::FilePath& path) { 301 const base::FilePath& path,
302 bool is_directory) {
294 GrantedFileEntry result; 303 GrantedFileEntry result;
295 fileapi::IsolatedContext* isolated_context = 304 fileapi::IsolatedContext* isolated_context =
296 fileapi::IsolatedContext::GetInstance(); 305 fileapi::IsolatedContext::GetInstance();
297 DCHECK(isolated_context); 306 DCHECK(isolated_context);
298 307
299 result.filesystem_id = isolated_context->RegisterFileSystemForPath( 308 result.filesystem_id = isolated_context->RegisterFileSystemForPath(
300 fileapi::kFileSystemTypeNativeForPlatformApp, path, 309 fileapi::kFileSystemTypeNativeForPlatformApp, path,
301 &result.registered_name); 310 &result.registered_name);
302 311
303 content::ChildProcessSecurityPolicy* policy = 312 content::ChildProcessSecurityPolicy* policy =
304 content::ChildProcessSecurityPolicy::GetInstance(); 313 content::ChildProcessSecurityPolicy::GetInstance();
305 policy->GrantReadFileSystem(renderer_id, result.filesystem_id); 314 policy->GrantReadFileSystem(renderer_id, result.filesystem_id);
306 if (HasFileSystemWritePermission(extension)) 315 if (HasFileSystemWritePermission(extension)) {
307 policy->GrantWriteFileSystem(renderer_id, result.filesystem_id); 316 policy->GrantWriteFileSystem(renderer_id, result.filesystem_id);
317 if (is_directory)
318 policy->GrantCreateFileForFileSystem(renderer_id, result.filesystem_id);
319 }
308 320
309 result.id = result.filesystem_id + ":" + result.registered_name; 321 result.id = result.filesystem_id + ":" + result.registered_name;
310 return result; 322 return result;
311 } 323 }
312 324
313 void CheckWritableFiles( 325 void CheckWritableFiles(
314 const std::vector<base::FilePath>& paths, 326 const std::vector<base::FilePath>& paths,
315 Profile* profile, 327 Profile* profile,
328 bool is_directory,
316 const base::Closure& on_success, 329 const base::Closure& on_success,
317 const base::Callback<void(const base::FilePath&)>& on_failure) { 330 const base::Callback<void(const base::FilePath&)>& on_failure) {
318 scoped_refptr<WritableFileChecker> checker( 331 scoped_refptr<WritableFileChecker> checker(new WritableFileChecker(
319 new WritableFileChecker(paths, profile, on_success, on_failure)); 332 paths, profile, is_directory, on_success, on_failure));
320 checker->Check(); 333 checker->Check();
321 } 334 }
322 335
336 GrantedFileEntry::GrantedFileEntry() {}
337
323 bool HasFileSystemWritePermission(const Extension* extension) { 338 bool HasFileSystemWritePermission(const Extension* extension) {
324 return extension->HasAPIPermission(APIPermission::kFileSystemWrite); 339 return extension->HasAPIPermission(APIPermission::kFileSystemWrite);
325 } 340 }
326 341
327 } // namespace app_file_handler_util 342 } // namespace app_file_handler_util
328 343
329 } // namespace extensions 344 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698