Add permission check to FakeDriveService

Add a new method SetUserPermission() to set the user's permission for a file.
Check the permission in DeleteResource(), TrashResource(), UpdateResource() and InitiateUploadExistingFile().

This change doesn't cover:
- Permission check for the parent when adding/removing entries to a directory.
- Cases where the permission is changed while upload is in progress. (even not sure what happens in the production)

BUG=340933
TEST=unit_tests --gtest_filter="FakeDriveServiceTest.*"

Review URL: https://codereview.chromium.org/445793003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288062 0039d316-1c4b-4281-b951-d872f2087c98
parent 5f2ad6d6
...@@ -50,6 +50,7 @@ using google_apis::GetContentCallback; ...@@ -50,6 +50,7 @@ using google_apis::GetContentCallback;
using google_apis::GetShareUrlCallback; using google_apis::GetShareUrlCallback;
using google_apis::HTTP_BAD_REQUEST; using google_apis::HTTP_BAD_REQUEST;
using google_apis::HTTP_CREATED; using google_apis::HTTP_CREATED;
using google_apis::HTTP_FORBIDDEN;
using google_apis::HTTP_NOT_FOUND; using google_apis::HTTP_NOT_FOUND;
using google_apis::HTTP_NO_CONTENT; using google_apis::HTTP_NO_CONTENT;
using google_apis::HTTP_PRECONDITION; using google_apis::HTTP_PRECONDITION;
...@@ -131,12 +132,30 @@ void FileListCallbackAdapter(const FileListCallback& callback, ...@@ -131,12 +132,30 @@ void FileListCallbackAdapter(const FileListCallback& callback,
callback.Run(error, file_list.Pass()); callback.Run(error, file_list.Pass());
} }
bool UserHasWriteAccess(google_apis::drive::PermissionRole user_permission) {
switch (user_permission) {
case google_apis::drive::PERMISSION_ROLE_OWNER:
case google_apis::drive::PERMISSION_ROLE_WRITER:
return true;
case google_apis::drive::PERMISSION_ROLE_READER:
case google_apis::drive::PERMISSION_ROLE_COMMENTER:
break;
}
return false;
}
} // namespace } // namespace
struct FakeDriveService::EntryInfo { struct FakeDriveService::EntryInfo {
EntryInfo() : user_permission(google_apis::drive::PERMISSION_ROLE_OWNER) {}
google_apis::ChangeResource change_resource; google_apis::ChangeResource change_resource;
GURL share_url; GURL share_url;
std::string content_data; std::string content_data;
// Behaves in the same way as "userPermission" described in
// https://developers.google.com/drive/v2/reference/files
google_apis::drive::PermissionRole user_permission;
}; };
struct FakeDriveService::UploadSession { struct FakeDriveService::UploadSession {
...@@ -609,6 +628,12 @@ CancelCallback FakeDriveService::DeleteResource( ...@@ -609,6 +628,12 @@ CancelCallback FakeDriveService::DeleteResource(
return CancelCallback(); return CancelCallback();
} }
if (entry->user_permission != google_apis::drive::PERMISSION_ROLE_OWNER) {
base::MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(callback, HTTP_FORBIDDEN));
return CancelCallback();
}
change->set_deleted(true); change->set_deleted(true);
AddNewChangestamp(change); AddNewChangestamp(change);
change->set_file(scoped_ptr<FileResource>()); change->set_file(scoped_ptr<FileResource>());
...@@ -641,6 +666,9 @@ CancelCallback FakeDriveService::TrashResource( ...@@ -641,6 +666,9 @@ CancelCallback FakeDriveService::TrashResource(
GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
if (change->is_deleted() || file->labels().is_trashed()) { if (change->is_deleted() || file->labels().is_trashed()) {
error = HTTP_NOT_FOUND; error = HTTP_NOT_FOUND;
} else if (entry->user_permission !=
google_apis::drive::PERMISSION_ROLE_OWNER) {
error = HTTP_FORBIDDEN;
} else { } else {
file->mutable_labels()->set_trashed(true); file->mutable_labels()->set_trashed(true);
AddNewChangestamp(change); AddNewChangestamp(change);
...@@ -814,6 +842,14 @@ CancelCallback FakeDriveService::UpdateResource( ...@@ -814,6 +842,14 @@ CancelCallback FakeDriveService::UpdateResource(
EntryInfo* entry = FindEntryByResourceId(resource_id); EntryInfo* entry = FindEntryByResourceId(resource_id);
if (entry) { if (entry) {
if (!UserHasWriteAccess(entry->user_permission)) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(callback, HTTP_FORBIDDEN,
base::Passed(scoped_ptr<FileResource>())));
return CancelCallback();
}
ChangeResource* change = &entry->change_resource; ChangeResource* change = &entry->change_resource;
FileResource* file = change->mutable_file(); FileResource* file = change->mutable_file();
...@@ -1000,6 +1036,13 @@ CancelCallback FakeDriveService::InitiateUploadExistingFile( ...@@ -1000,6 +1036,13 @@ CancelCallback FakeDriveService::InitiateUploadExistingFile(
return CancelCallback(); return CancelCallback();
} }
if (!UserHasWriteAccess(entry->user_permission)) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(callback, HTTP_FORBIDDEN, GURL()));
return CancelCallback();
}
FileResource* file = entry->change_resource.mutable_file(); FileResource* file = entry->change_resource.mutable_file();
if (!options.etag.empty() && options.etag != file->etag()) { if (!options.etag.empty() && options.etag != file->etag()) {
base::MessageLoop::current()->PostTask( base::MessageLoop::current()->PostTask(
...@@ -1316,6 +1359,19 @@ void FakeDriveService::SetLastModifiedTime( ...@@ -1316,6 +1359,19 @@ void FakeDriveService::SetLastModifiedTime(
base::Passed(make_scoped_ptr(new FileResource(*file))))); base::Passed(make_scoped_ptr(new FileResource(*file)))));
} }
google_apis::GDataErrorCode FakeDriveService::SetUserPermission(
const std::string& resource_id,
google_apis::drive::PermissionRole user_permission) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
EntryInfo* entry = FindEntryByResourceId(resource_id);
if (!entry)
return HTTP_NOT_FOUND;
entry->user_permission = user_permission;
return HTTP_SUCCESS;
}
FakeDriveService::EntryInfo* FakeDriveService::FindEntryByResourceId( FakeDriveService::EntryInfo* FakeDriveService::FindEntryByResourceId(
const std::string& resource_id) { const std::string& resource_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
......
...@@ -284,6 +284,11 @@ class FakeDriveService : public DriveServiceInterface { ...@@ -284,6 +284,11 @@ class FakeDriveService : public DriveServiceInterface {
const base::Time& last_modified_time, const base::Time& last_modified_time,
const google_apis::FileResourceCallback& callback); const google_apis::FileResourceCallback& callback);
// Sets the user's permission for an entry specified by |resource_id|.
google_apis::GDataErrorCode SetUserPermission(
const std::string& resource_id,
google_apis::drive::PermissionRole user_permission);
private: private:
struct EntryInfo; struct EntryInfo;
struct UploadSession; struct UploadSession;
......
...@@ -31,6 +31,7 @@ using google_apis::GDATA_OTHER_ERROR; ...@@ -31,6 +31,7 @@ using google_apis::GDATA_OTHER_ERROR;
using google_apis::GDataErrorCode; using google_apis::GDataErrorCode;
using google_apis::GetContentCallback; using google_apis::GetContentCallback;
using google_apis::HTTP_CREATED; using google_apis::HTTP_CREATED;
using google_apis::HTTP_FORBIDDEN;
using google_apis::HTTP_NOT_FOUND; using google_apis::HTTP_NOT_FOUND;
using google_apis::HTTP_NO_CONTENT; using google_apis::HTTP_NO_CONTENT;
using google_apis::HTTP_PRECONDITION; using google_apis::HTTP_PRECONDITION;
...@@ -901,6 +902,21 @@ TEST_F(FakeDriveServiceTest, DeleteResource_Offline) { ...@@ -901,6 +902,21 @@ TEST_F(FakeDriveServiceTest, DeleteResource_Offline) {
EXPECT_EQ(GDATA_NO_CONNECTION, error); EXPECT_EQ(GDATA_NO_CONNECTION, error);
} }
TEST_F(FakeDriveServiceTest, DeleteResource_Forbidden) {
ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_));
EXPECT_EQ(HTTP_SUCCESS, fake_service_.SetUserPermission(
"2_file_resource_id", google_apis::drive::PERMISSION_ROLE_READER));
GDataErrorCode error = GDATA_OTHER_ERROR;
fake_service_.DeleteResource("2_file_resource_id",
std::string(), // etag
test_util::CreateCopyResultCallback(&error));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(HTTP_FORBIDDEN, error);
}
TEST_F(FakeDriveServiceTest, TrashResource_ExistingFile) { TEST_F(FakeDriveServiceTest, TrashResource_ExistingFile) {
ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_)); ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_));
...@@ -947,6 +963,20 @@ TEST_F(FakeDriveServiceTest, TrashResource_Offline) { ...@@ -947,6 +963,20 @@ TEST_F(FakeDriveServiceTest, TrashResource_Offline) {
EXPECT_EQ(GDATA_NO_CONNECTION, error); EXPECT_EQ(GDATA_NO_CONNECTION, error);
} }
TEST_F(FakeDriveServiceTest, TrashResource_Forbidden) {
ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_));
EXPECT_EQ(HTTP_SUCCESS, fake_service_.SetUserPermission(
"2_file_resource_id", google_apis::drive::PERMISSION_ROLE_READER));
GDataErrorCode error = GDATA_OTHER_ERROR;
fake_service_.TrashResource("2_file_resource_id",
test_util::CreateCopyResultCallback(&error));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(HTTP_FORBIDDEN, error);
}
TEST_F(FakeDriveServiceTest, DownloadFile_ExistingFile) { TEST_F(FakeDriveServiceTest, DownloadFile_ExistingFile) {
ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_)); ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_));
...@@ -1228,6 +1258,28 @@ TEST_F(FakeDriveServiceTest, UpdateResource_Offline) { ...@@ -1228,6 +1258,28 @@ TEST_F(FakeDriveServiceTest, UpdateResource_Offline) {
EXPECT_FALSE(entry); EXPECT_FALSE(entry);
} }
TEST_F(FakeDriveServiceTest, UpdateResource_Forbidden) {
ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_));
const std::string kResourceId = "2_file_resource_id";
EXPECT_EQ(HTTP_SUCCESS, fake_service_.SetUserPermission(
kResourceId, google_apis::drive::PERMISSION_ROLE_READER));
GDataErrorCode error = GDATA_OTHER_ERROR;
scoped_ptr<FileResource> entry;
fake_service_.UpdateResource(
kResourceId,
std::string(),
"new title",
base::Time(),
base::Time(),
test_util::CreateCopyResultCallback(&error, &entry));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(HTTP_FORBIDDEN, error);
EXPECT_FALSE(entry);
}
TEST_F(FakeDriveServiceTest, AddResourceToDirectory_FileInRootDirectory) { TEST_F(FakeDriveServiceTest, AddResourceToDirectory_FileInRootDirectory) {
ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_)); ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_));
...@@ -1648,6 +1700,26 @@ TEST_F(FakeDriveServiceTest, InitiateUploadExistingFile_Offline) { ...@@ -1648,6 +1700,26 @@ TEST_F(FakeDriveServiceTest, InitiateUploadExistingFile_Offline) {
EXPECT_TRUE(upload_location.is_empty()); EXPECT_TRUE(upload_location.is_empty());
} }
TEST_F(FakeDriveServiceTest, InitiateUploadExistingFile_Forbidden) {
ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_));
EXPECT_EQ(HTTP_SUCCESS, fake_service_.SetUserPermission(
"2_file_resource_id", google_apis::drive::PERMISSION_ROLE_READER));
GDataErrorCode error = GDATA_OTHER_ERROR;
GURL upload_location;
fake_service_.InitiateUploadExistingFile(
"test/foo",
13,
"2_file_resource_id",
FakeDriveService::InitiateUploadExistingFileOptions(),
test_util::CreateCopyResultCallback(&error, &upload_location));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(HTTP_FORBIDDEN, error);
EXPECT_TRUE(upload_location.is_empty());
}
TEST_F(FakeDriveServiceTest, InitiateUploadExistingFile_NotFound) { TEST_F(FakeDriveServiceTest, InitiateUploadExistingFile_NotFound) {
ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_)); ASSERT_TRUE(test_util::SetUpTestEntries(&fake_service_));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment