diff --git a/chrome/browser/chromeos/file_system_provider/operations/copy_entry.cc b/chrome/browser/chromeos/file_system_provider/operations/copy_entry.cc index 56fd67d0a43c1c..a89cfc606c520f 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/copy_entry.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/copy_entry.cc @@ -28,6 +28,9 @@ CopyEntry::~CopyEntry() { } bool CopyEntry::Execute(int request_id) { + if (!file_system_info_.writable()) + return false; + scoped_ptr values(new base::DictionaryValue); values->SetString("sourcePath", source_path_.AsUTF8Unsafe()); values->SetString("targetPath", target_path_.AsUTF8Unsafe()); diff --git a/chrome/browser/chromeos/file_system_provider/operations/copy_entry_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/copy_entry_unittest.cc index 1144a74d803407..20f75cd7a48b77 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/copy_entry_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/copy_entry_unittest.cc @@ -108,6 +108,29 @@ TEST_F(FileSystemProviderOperationsCopyEntryTest, Execute_NoListener) { EXPECT_FALSE(copy_entry.Execute(kRequestId)); } +TEST_F(FileSystemProviderOperationsCopyEntryTest, Execute_ReadOnly) { + util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); + util::StatusCallbackLog callback_log; + + const ProvidedFileSystemInfo read_only_file_system_info( + kExtensionId, + kFileSystemId, + "" /* file_system_name */, + false /* writable */, + base::FilePath() /* mount_path */); + + CopyEntry copy_entry(NULL, + read_only_file_system_info, + base::FilePath::FromUTF8Unsafe(kSourcePath), + base::FilePath::FromUTF8Unsafe(kTargetPath), + base::Bind(&util::LogStatusCallback, &callback_log)); + copy_entry.SetDispatchEventImplForTesting( + base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_FALSE(copy_entry.Execute(kRequestId)); +} + TEST_F(FileSystemProviderOperationsCopyEntryTest, OnSuccess) { util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); util::StatusCallbackLog callback_log; diff --git a/chrome/browser/chromeos/file_system_provider/operations/create_directory.cc b/chrome/browser/chromeos/file_system_provider/operations/create_directory.cc index bacd7364bf5120..77984affa1a986 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/create_directory.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/create_directory.cc @@ -31,6 +31,9 @@ CreateDirectory::~CreateDirectory() { } bool CreateDirectory::Execute(int request_id) { + if (!file_system_info_.writable()) + return false; + scoped_ptr values(new base::DictionaryValue); values->SetString("directoryPath", directory_path_.AsUTF8Unsafe()); values->SetBoolean("exclusive", exclusive_); diff --git a/chrome/browser/chromeos/file_system_provider/operations/create_directory_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/create_directory_unittest.cc index 6d1869a18b4bf9..e4f191bb91a607 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/create_directory_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/create_directory_unittest.cc @@ -115,6 +115,31 @@ TEST_F(FileSystemProviderOperationsCreateDirectoryTest, Execute_NoListener) { EXPECT_FALSE(create_directory.Execute(kRequestId)); } +TEST_F(FileSystemProviderOperationsCreateDirectoryTest, Execute_ReadOnly) { + util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); + util::StatusCallbackLog callback_log; + + const ProvidedFileSystemInfo read_only_file_system_info( + kExtensionId, + kFileSystemId, + "" /* file_system_name */, + false /* writable */, + base::FilePath() /* mount_path */); + + CreateDirectory create_directory( + NULL, + read_only_file_system_info, + base::FilePath::FromUTF8Unsafe(kDirectoryPath), + false /* exclusive */, + true /* recursive */, + base::Bind(&util::LogStatusCallback, &callback_log)); + create_directory.SetDispatchEventImplForTesting( + base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_FALSE(create_directory.Execute(kRequestId)); +} + TEST_F(FileSystemProviderOperationsCreateDirectoryTest, OnSuccess) { util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); util::StatusCallbackLog callback_log; diff --git a/chrome/browser/chromeos/file_system_provider/operations/create_file.cc b/chrome/browser/chromeos/file_system_provider/operations/create_file.cc index 9f861c78029498..27fb164a9a2c9c 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/create_file.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/create_file.cc @@ -26,6 +26,9 @@ CreateFile::~CreateFile() { } bool CreateFile::Execute(int request_id) { + if (!file_system_info_.writable()) + return false; + scoped_ptr values(new base::DictionaryValue); values->SetString("filePath", file_path_.AsUTF8Unsafe()); diff --git a/chrome/browser/chromeos/file_system_provider/operations/create_file_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/create_file_unittest.cc index 1dbce12445c432..37f77cbd8c436c 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/create_file_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/create_file_unittest.cc @@ -101,6 +101,28 @@ TEST_F(FileSystemProviderOperationsCreateFileTest, Execute_NoListener) { EXPECT_FALSE(create_file.Execute(kRequestId)); } +TEST_F(FileSystemProviderOperationsCreateFileTest, Execute_ReadOnly) { + util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); + util::StatusCallbackLog callback_log; + + const ProvidedFileSystemInfo read_only_file_system_info( + kExtensionId, + kFileSystemId, + "" /* file_system_name */, + false /* writable */, + base::FilePath() /* mount_path */); + + CreateFile create_file(NULL, + read_only_file_system_info, + base::FilePath::FromUTF8Unsafe(kFilePath), + base::Bind(&util::LogStatusCallback, &callback_log)); + create_file.SetDispatchEventImplForTesting( + base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_FALSE(create_file.Execute(kRequestId)); +} + TEST_F(FileSystemProviderOperationsCreateFileTest, OnSuccess) { util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); util::StatusCallbackLog callback_log; diff --git a/chrome/browser/chromeos/file_system_provider/operations/delete_entry.cc b/chrome/browser/chromeos/file_system_provider/operations/delete_entry.cc index 867653c2660741..513b3fdf7362af 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/delete_entry.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/delete_entry.cc @@ -28,6 +28,9 @@ DeleteEntry::~DeleteEntry() { } bool DeleteEntry::Execute(int request_id) { + if (!file_system_info_.writable()) + return false; + scoped_ptr values(new base::DictionaryValue); values->SetString("entryPath", entry_path_.AsUTF8Unsafe()); values->SetBoolean("recursive", recursive_); diff --git a/chrome/browser/chromeos/file_system_provider/operations/delete_entry_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/delete_entry_unittest.cc index c70dc2d2f42457..9a40423918839b 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/delete_entry_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/delete_entry_unittest.cc @@ -41,7 +41,7 @@ class FileSystemProviderOperationsDeleteEntryTest : public testing::Test { ProvidedFileSystemInfo(kExtensionId, kFileSystemId, "" /* file_system_name */, - false /* writable */, + true /* writable */, base::FilePath() /* mount_path */); } @@ -107,6 +107,29 @@ TEST_F(FileSystemProviderOperationsDeleteEntryTest, Execute_NoListener) { EXPECT_FALSE(delete_entry.Execute(kRequestId)); } +TEST_F(FileSystemProviderOperationsDeleteEntryTest, Execute_ReadOnly) { + util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); + util::StatusCallbackLog callback_log; + + const ProvidedFileSystemInfo read_only_file_system_info( + kExtensionId, + kFileSystemId, + "" /* file_system_name */, + false /* writable */, + base::FilePath() /* mount_path */); + + DeleteEntry delete_entry(NULL, + read_only_file_system_info, + base::FilePath::FromUTF8Unsafe(kEntryPath), + true /* recursive */, + base::Bind(&util::LogStatusCallback, &callback_log)); + delete_entry.SetDispatchEventImplForTesting( + base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_FALSE(delete_entry.Execute(kRequestId)); +} + TEST_F(FileSystemProviderOperationsDeleteEntryTest, OnSuccess) { util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); util::StatusCallbackLog callback_log; diff --git a/chrome/browser/chromeos/file_system_provider/operations/move_entry.cc b/chrome/browser/chromeos/file_system_provider/operations/move_entry.cc index ec5ec7a146a491..909bb35676c3a0 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/move_entry.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/move_entry.cc @@ -28,6 +28,9 @@ MoveEntry::~MoveEntry() { } bool MoveEntry::Execute(int request_id) { + if (!file_system_info_.writable()) + return false; + scoped_ptr values(new base::DictionaryValue); values->SetString("sourcePath", source_path_.AsUTF8Unsafe()); values->SetString("targetPath", target_path_.AsUTF8Unsafe()); diff --git a/chrome/browser/chromeos/file_system_provider/operations/move_entry_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/move_entry_unittest.cc index d8e1a211637c91..857cbf4fbb35fc 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/move_entry_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/move_entry_unittest.cc @@ -108,6 +108,29 @@ TEST_F(FileSystemProviderOperationsMoveEntryTest, Execute_NoListener) { EXPECT_FALSE(move_entry.Execute(kRequestId)); } +TEST_F(FileSystemProviderOperationsMoveEntryTest, Execute_ReadOnly) { + util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); + util::StatusCallbackLog callback_log; + + const ProvidedFileSystemInfo read_only_file_system_info( + kExtensionId, + kFileSystemId, + "" /* file_system_name */, + false /* writable */, + base::FilePath() /* mount_path */); + + MoveEntry move_entry(NULL, + read_only_file_system_info, + base::FilePath::FromUTF8Unsafe(kSourcePath), + base::FilePath::FromUTF8Unsafe(kTargetPath), + base::Bind(&util::LogStatusCallback, &callback_log)); + move_entry.SetDispatchEventImplForTesting( + base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_FALSE(move_entry.Execute(kRequestId)); +} + TEST_F(FileSystemProviderOperationsMoveEntryTest, OnSuccess) { util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); util::StatusCallbackLog callback_log; diff --git a/chrome/browser/chromeos/file_system_provider/operations/open_file.cc b/chrome/browser/chromeos/file_system_provider/operations/open_file.cc index 8a1a3617f8e4d4..93c930f4fed32c 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/open_file.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/open_file.cc @@ -29,6 +29,11 @@ OpenFile::~OpenFile() { } bool OpenFile::Execute(int request_id) { + if (!file_system_info_.writable() && + mode_ == ProvidedFileSystemInterface::OPEN_FILE_MODE_WRITE) { + return false; + } + scoped_ptr values(new base::DictionaryValue); values->SetString("filePath", file_path_.AsUTF8Unsafe()); diff --git a/chrome/browser/chromeos/file_system_provider/operations/open_file_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/open_file_unittest.cc index db3d84d96ef40d..749f40249d01e6 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/open_file_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/open_file_unittest.cc @@ -147,6 +147,48 @@ TEST_F(FileSystemProviderOperationsOpenFileTest, Execute_NoListener) { EXPECT_FALSE(open_file.Execute(kRequestId)); } +TEST_F(FileSystemProviderOperationsOpenFileTest, Execute_ReadOnly) { + util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); + CallbackLogger callback_logger; + + const ProvidedFileSystemInfo read_only_file_system_info( + kExtensionId, + kFileSystemId, + "" /* file_system_name */, + false /* writable */, + base::FilePath() /* mount_path */); + + // Opening for read on a read-only file system is allowed. + { + OpenFile open_file(NULL, + read_only_file_system_info, + base::FilePath::FromUTF8Unsafe(kFilePath), + ProvidedFileSystemInterface::OPEN_FILE_MODE_READ, + base::Bind(&CallbackLogger::OnOpenFile, + base::Unretained(&callback_logger))); + open_file.SetDispatchEventImplForTesting( + base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_TRUE(open_file.Execute(kRequestId)); + } + + // Opening for write on a read-only file system is forbidden and must fail. + { + OpenFile open_file(NULL, + read_only_file_system_info, + base::FilePath::FromUTF8Unsafe(kFilePath), + ProvidedFileSystemInterface::OPEN_FILE_MODE_WRITE, + base::Bind(&CallbackLogger::OnOpenFile, + base::Unretained(&callback_logger))); + open_file.SetDispatchEventImplForTesting( + base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_FALSE(open_file.Execute(kRequestId)); + } +} + TEST_F(FileSystemProviderOperationsOpenFileTest, OnSuccess) { util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); CallbackLogger callback_logger; diff --git a/chrome/browser/chromeos/file_system_provider/operations/truncate.cc b/chrome/browser/chromeos/file_system_provider/operations/truncate.cc index c7537a46aab256..f167aef1a3be7e 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/truncate.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/truncate.cc @@ -28,6 +28,9 @@ Truncate::~Truncate() { } bool Truncate::Execute(int request_id) { + if (!file_system_info_.writable()) + return false; + scoped_ptr values(new base::DictionaryValue); values->SetString("filePath", file_path_.AsUTF8Unsafe()); values->SetDouble("length", length_); diff --git a/chrome/browser/chromeos/file_system_provider/operations/truncate_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/truncate_unittest.cc index 66e2adcbede4aa..1ba6a14c29f743 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/truncate_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/truncate_unittest.cc @@ -108,6 +108,29 @@ TEST_F(FileSystemProviderOperationsTruncateTest, Execute_NoListener) { EXPECT_FALSE(truncate.Execute(kRequestId)); } +TEST_F(FileSystemProviderOperationsTruncateTest, Execute_ReadOnly) { + util::LoggingDispatchEventImpl dispatcher(false /* dispatch_reply */); + util::StatusCallbackLog callback_log; + + const ProvidedFileSystemInfo read_only_file_system_info( + kExtensionId, + kFileSystemId, + "" /* file_system_name */, + false /* writable */, + base::FilePath() /* mount_path */); + + Truncate truncate(NULL, + file_system_info_, + base::FilePath::FromUTF8Unsafe(kFilePath), + kTruncateLength, + base::Bind(&util::LogStatusCallback, &callback_log)); + truncate.SetDispatchEventImplForTesting( + base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl, + base::Unretained(&dispatcher))); + + EXPECT_FALSE(truncate.Execute(kRequestId)); +} + TEST_F(FileSystemProviderOperationsTruncateTest, OnSuccess) { util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */); util::StatusCallbackLog callback_log; diff --git a/chrome/test/data/extensions/api_test/file_system_provider/test_util/test_util.js b/chrome/test/data/extensions/api_test/file_system_provider/test_util/test_util.js index 047e4c89a5c061..2ce6ce00d9c289 100644 --- a/chrome/test/data/extensions/api_test/file_system_provider/test_util/test_util.js +++ b/chrome/test/data/extensions/api_test/file_system_provider/test_util/test_util.js @@ -69,7 +69,8 @@ test_util.mountFileSystem = function(callback) { chrome.fileSystemProvider.mount( { fileSystemId: test_util.FILE_SYSTEM_ID, - displayName: test_util.FILE_SYSTEM_NAME + displayName: test_util.FILE_SYSTEM_NAME, + writable: true }, function() { var volumeId =