Skip to content

Commit

Permalink
Fetch file metadata of files under Team Drives.
Browse files Browse the repository at this point in the history
The function is hidden behind a flag (--team-drives).
After this change, the Files app. will be able to search files in
Team Drives of which the user has access right.

BUG=649911
TEST=google_apis_unittests
TEST=manual test by searching a Team Drive file/folder in My Drive.

Review-Url: https://codereview.chromium.org/2693093002
Cr-Commit-Position: refs/heads/master@{#452033}
  • Loading branch information
yamaguchi authored and Commit bot committed Feb 22, 2017
1 parent 3b70458 commit eb24cc5
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "content/public/browser/browser_thread.h"
#include "google_apis/drive/auth_service.h"
#include "google_apis/drive/drive_api_url_generator.h"
#include "google_apis/drive/drive_switches.h"
#include "storage/common/fileapi/file_system_info.h"
#include "storage/common/fileapi/file_system_util.h"
#include "url/gurl.h"
Expand Down Expand Up @@ -100,7 +101,8 @@ void FillEntryPropertiesValueForDrive(const drive::ResourceEntry& entry_proto,
DriveApiUrlGenerator url_generator(
(GURL(google_apis::DriveApiUrlGenerator::kBaseUrlForProduction)),
(GURL(google_apis::DriveApiUrlGenerator::
kBaseThumbnailUrlForProduction)));
kBaseThumbnailUrlForProduction)),
google_apis::GetTeamDrivesIntegrationSwitch());
properties->thumbnail_url.reset(new std::string(
url_generator.GetThumbnailUrl(entry_proto.resource_id(),
500 /* width */, 500 /* height */,
Expand Down Expand Up @@ -1114,7 +1116,8 @@ void FileManagerPrivateInternalGetDownloadUrlFunction::OnGetResourceEntry(
DriveApiUrlGenerator url_generator(
(GURL(google_apis::DriveApiUrlGenerator::kBaseUrlForProduction)),
(GURL(
google_apis::DriveApiUrlGenerator::kBaseThumbnailUrlForProduction)));
google_apis::DriveApiUrlGenerator::kBaseThumbnailUrlForProduction)),
google_apis::GetTeamDrivesIntegrationSwitch());
download_url_ = url_generator.GenerateDownloadFileUrl(entry->resource_id());

ProfileOAuth2TokenService* oauth2_token_service =
Expand Down
3 changes: 2 additions & 1 deletion components/drive/service/drive_api_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ DriveAPIService::DriveAPIService(
: oauth2_token_service_(oauth2_token_service),
url_request_context_getter_(url_request_context_getter),
blocking_task_runner_(blocking_task_runner),
url_generator_(base_url, base_thumbnail_url),
url_generator_(base_url, base_thumbnail_url,
google_apis::GetTeamDrivesIntegrationSwitch()),
custom_user_agent_(custom_user_agent) {
}

Expand Down
3 changes: 2 additions & 1 deletion components/drive/service/drive_api_service_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class TestAuthService : public google_apis::DummyAuthService {

TEST(DriveAPIServiceTest, BatchRequestConfiguratorWithAuthFailure) {
const GURL test_base_url("http://localhost/");
google_apis::DriveApiUrlGenerator url_generator(test_base_url, test_base_url);
google_apis::DriveApiUrlGenerator url_generator(test_base_url, test_base_url,
google_apis::TEAM_DRIVES_INTEGRATION_DISABLED);
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner();
scoped_refptr<net::TestURLRequestContextGetter> request_context_getter =
Expand Down
2 changes: 2 additions & 0 deletions google_apis/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ template("google_apis_tmpl") {
"drive/drive_api_url_generator.cc",
"drive/drive_api_url_generator.h",
"drive/drive_common_callbacks.h",
"drive/drive_switches.cc",
"drive/drive_switches.h",
"drive/files_list_request_runner.cc",
"drive/files_list_request_runner.h",
"drive/request_sender.cc",
Expand Down
3 changes: 2 additions & 1 deletion google_apis/drive/drive_api_requests_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ class DriveApiRequestsTest : public testing::Test {

GURL test_base_url = test_util::GetBaseUrlForTesting(test_server_.port());
url_generator_.reset(
new DriveApiUrlGenerator(test_base_url, test_base_url));
new DriveApiUrlGenerator(test_base_url, test_base_url,
TEAM_DRIVES_INTEGRATION_DISABLED));

// Reset the server's expected behavior just in case.
ResetExpectedResponse();
Expand Down
60 changes: 50 additions & 10 deletions google_apis/drive/drive_api_url_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

#include "google_apis/drive/drive_api_url_generator.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "google_apis/drive/drive_switches.h"
#include "google_apis/google_api_keys.h"
#include "net/base/escape.h"
#include "net/base/url_util.h"
Expand All @@ -16,11 +18,16 @@ namespace google_apis {
namespace {

// Hard coded URLs for communication with a google drive server.
// TODO(yamaguchi): Make a utility function to compose some of these URLs by a
// version and a resource name.
const char kDriveV2AboutUrl[] = "drive/v2/about";
const char kDriveV2AppsUrl[] = "drive/v2/apps";
const char kDriveV2ChangelistUrl[] = "drive/v2/changes";
const char kDriveV2BetaChangelistUrl[] = "drive/v2beta/changes";
const char kDriveV2FilesUrl[] = "drive/v2/files";
const char kDriveV2BetaFilesUrl[] = "drive/v2beta/files";
const char kDriveV2FileUrlPrefix[] = "drive/v2/files/";
const char kDriveV2BetaFileUrlPrefix[] = "drive/v2beta/files/";
const char kDriveV2ChildrenUrlFormat[] = "drive/v2/files/%s/children";
const char kDriveV2ChildrenUrlForRemovalFormat[] =
"drive/v2/files/%s/children/%s";
Expand All @@ -35,6 +42,9 @@ const char kDriveV2DownloadUrlFormat[] = "drive/v2/files/%s?alt=media";
const char kDriveV2ThumbnailUrlFormat[] = "d/%s=w%d-h%d";
const char kDriveV2ThumbnailUrlWithCropFormat[] = "d/%s=w%d-h%d-c";

const char kIncludeTeamDriveItems[] = "includeTeamDriveItems";
const char kSupportsTeamDrives[] = "supportsTeamDrives";

// apps.delete and file.authorize API is exposed through a special endpoint
// v2internal that is accessible only by the official API key for Chrome.
const char kDriveV2InternalAppsUrl[] = "drive/v2internal/apps";
Expand All @@ -53,13 +63,19 @@ GURL AddMultipartUploadParam(const GURL& url) {

} // namespace

DriveApiUrlGenerator::DriveApiUrlGenerator(const GURL& base_url,
const GURL& base_thumbnail_url)
DriveApiUrlGenerator::DriveApiUrlGenerator(
const GURL& base_url, const GURL& base_thumbnail_url,
TeamDrivesIntegrationStatus team_drives_integration)
: base_url_(base_url),
base_thumbnail_url_(base_thumbnail_url) {
base_thumbnail_url_(base_thumbnail_url),
enable_team_drives_(
team_drives_integration == TEAM_DRIVES_INTEGRATION_ENABLED) {
// Do nothing.
}

DriveApiUrlGenerator::DriveApiUrlGenerator(const DriveApiUrlGenerator& src) =
default;

DriveApiUrlGenerator::~DriveApiUrlGenerator() {
// Do nothing.
}
Expand Down Expand Up @@ -87,9 +103,19 @@ GURL DriveApiUrlGenerator::GetAppsDeleteUrl(const std::string& app_id) const {
GURL DriveApiUrlGenerator::GetFilesGetUrl(const std::string& file_id,
bool use_internal_endpoint,
const GURL& embed_origin) const {
GURL url = base_url_.Resolve(use_internal_endpoint ?
kDriveV2InternalFileUrlPrefix + net::EscapePath(file_id) :
kDriveV2FileUrlPrefix + net::EscapePath(file_id));
const char* url_prefix = nullptr;
if (use_internal_endpoint)
url_prefix = kDriveV2InternalFileUrlPrefix;
else if (enable_team_drives_)
url_prefix = kDriveV2BetaFileUrlPrefix;
else
url_prefix = kDriveV2FileUrlPrefix;

GURL url = base_url_.Resolve(url_prefix + net::EscapePath(file_id));

if (enable_team_drives_)
url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true");

if (!embed_origin.is_empty()) {
// Construct a valid serialized embed origin from an url, according to
// WD-html5-20110525. Such string has to be built manually, since
Expand Down Expand Up @@ -155,8 +181,15 @@ GURL DriveApiUrlGenerator::GetFilesCopyUrl(
GURL DriveApiUrlGenerator::GetFilesListUrl(int max_results,
const std::string& page_token,
const std::string& q) const {
GURL url = base_url_.Resolve(kDriveV2FilesUrl);

GURL url;
if (enable_team_drives_) {
url = base_url_.Resolve(kDriveV2BetaFilesUrl);
url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true");
url = net::AppendOrReplaceQueryParameter(url, kIncludeTeamDriveItems,
"true");
} else {
url = base_url_.Resolve(kDriveV2FilesUrl);
}
// maxResults is 100 by default.
if (max_results != 100) {
url = net::AppendOrReplaceQueryParameter(
Expand Down Expand Up @@ -188,8 +221,15 @@ GURL DriveApiUrlGenerator::GetChangesListUrl(bool include_deleted,
int64_t start_change_id) const {
DCHECK_GE(start_change_id, 0);

GURL url = base_url_.Resolve(kDriveV2ChangelistUrl);

GURL url;
if (enable_team_drives_) {
url = base_url_.Resolve(kDriveV2BetaChangelistUrl);
url = net::AppendOrReplaceQueryParameter(url, kSupportsTeamDrives, "true");
url = net::AppendOrReplaceQueryParameter(url, kIncludeTeamDriveItems,
"true");
} else {
url = base_url_.Resolve(kDriveV2ChangelistUrl);
}
// includeDeleted is "true" by default.
if (!include_deleted)
url = net::AppendOrReplaceQueryParameter(url, "includeDeleted", "false");
Expand Down
6 changes: 5 additions & 1 deletion google_apis/drive/drive_api_url_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <string>

#include "base/macros.h"
#include "google_apis/drive/drive_switches.h"
#include "url/gurl.h"

namespace google_apis {
Expand All @@ -21,7 +22,9 @@ class DriveApiUrlGenerator {
// |base_url| is the path to the target drive api server.
// Note that this is an injecting point for a testing server.
DriveApiUrlGenerator(const GURL& base_url,
const GURL& base_thumbnail_url);
const GURL& base_thumbnail_url,
TeamDrivesIntegrationStatus team_drives_integration);
DriveApiUrlGenerator(const DriveApiUrlGenerator& src);
~DriveApiUrlGenerator();

// The base URL for communicating with the production drive api server.
Expand Down Expand Up @@ -126,6 +129,7 @@ class DriveApiUrlGenerator {
const GURL base_url_;
const GURL base_download_url_;
const GURL base_thumbnail_url_;
const bool enable_team_drives_;

// This class is copyable hence no DISALLOW_COPY_AND_ASSIGN here.
};
Expand Down
113 changes: 75 additions & 38 deletions google_apis/drive/drive_api_url_generator_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@ class DriveApiUrlGeneratorTest : public testing::Test {
public:
DriveApiUrlGeneratorTest()
: url_generator_(GURL(kBaseUrlForTesting),
GURL(kBaseThumbnailUrlForTesting)) {}
GURL(kBaseThumbnailUrlForTesting),
TEAM_DRIVES_INTEGRATION_DISABLED),
team_drives_url_generator_(GURL(kBaseUrlForTesting),
GURL(kBaseThumbnailUrlForTesting),
TEAM_DRIVES_INTEGRATION_ENABLED) {}

protected:
DriveApiUrlGenerator url_generator_;
DriveApiUrlGenerator team_drives_url_generator_;
};

// Make sure the hard-coded urls are returned.
Expand Down Expand Up @@ -59,6 +64,10 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesGetUrl) {
EXPECT_EQ(
"https://www.example.com/drive/v2/files/file%3Afile_id",
url_generator_.GetFilesGetUrl("file:file_id", false, GURL()).spec());
EXPECT_EQ("https://www.example.com/drive/v2beta/files/0Bz0bd074"
"?supportsTeamDrives=true",
team_drives_url_generator_.GetFilesGetUrl(
"0Bz0bd074", false, GURL()).spec());

// If |use_internal_endpoint| is true, the generated url should point to the
// v2internal.
Expand Down Expand Up @@ -156,25 +165,38 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesListUrl) {
};
const TestPattern kTestPatterns[] = {
{ 100, "", "", "" },
{ 150, "", "", "?maxResults=150" },
{ 10, "", "", "?maxResults=10" },
{ 100, "token", "", "?pageToken=token" },
{ 150, "token", "", "?maxResults=150&pageToken=token" },
{ 10, "token", "", "?maxResults=10&pageToken=token" },
{ 100, "", "query", "?q=query" },
{ 150, "", "query", "?maxResults=150&q=query" },
{ 10, "", "query", "?maxResults=10&q=query" },
{ 100, "token", "query", "?pageToken=token&q=query" },
{ 150, "token", "query", "?maxResults=150&pageToken=token&q=query" },
{ 10, "token", "query", "?maxResults=10&pageToken=token&q=query" },
{ 150, "", "", "maxResults=150" },
{ 10, "", "", "maxResults=10" },
{ 100, "token", "", "pageToken=token" },
{ 150, "token", "", "maxResults=150&pageToken=token" },
{ 10, "token", "", "maxResults=10&pageToken=token" },
{ 100, "", "query", "q=query" },
{ 150, "", "query", "maxResults=150&q=query" },
{ 10, "", "query", "maxResults=10&q=query" },
{ 100, "token", "query", "pageToken=token&q=query" },
{ 150, "token", "query", "maxResults=150&pageToken=token&q=query" },
{ 10, "token", "query", "maxResults=10&pageToken=token&q=query" },
};
const std::string kV2FilesUrlPrefix =
"https://www.example.com/drive/v2/files";
const std::string kV2BetaFilesUrlPrefix =
"https://www.example.com/drive/v2beta/files?"
"supportsTeamDrives=true&includeTeamDriveItems=true";

for (size_t i = 0; i < arraysize(kTestPatterns); ++i) {
EXPECT_EQ("https://www.example.com/drive/v2/files" +
EXPECT_EQ(kV2FilesUrlPrefix +
(kTestPatterns[i].expected_query.empty() ? "" : "?") +
kTestPatterns[i].expected_query,
url_generator_.GetFilesListUrl(kTestPatterns[i].max_results,
kTestPatterns[i].page_token,
kTestPatterns[i].q).spec());
EXPECT_EQ(kV2BetaFilesUrlPrefix +
(kTestPatterns[i].expected_query.empty() ? "" : "&") +
kTestPatterns[i].expected_query,
team_drives_url_generator_.GetFilesListUrl(
kTestPatterns[i].max_results,
kTestPatterns[i].page_token,
kTestPatterns[i].q).spec());
}
}

Expand Down Expand Up @@ -208,53 +230,68 @@ TEST_F(DriveApiUrlGeneratorTest, GetChangesListUrl) {
};
const TestPattern kTestPatterns[] = {
{ true, 100, "", 0, "" },
{ false, 100, "", 0, "?includeDeleted=false" },
{ true, 150, "", 0, "?maxResults=150" },
{ false, 150, "", 0, "?includeDeleted=false&maxResults=150" },
{ true, 10, "", 0, "?maxResults=10" },
{ false, 10, "", 0, "?includeDeleted=false&maxResults=10" },

{ true, 100, "token", 0, "?pageToken=token" },
{ false, 100, "token", 0, "?includeDeleted=false&pageToken=token" },
{ true, 150, "token", 0, "?maxResults=150&pageToken=token" },
{ false, 100, "", 0, "includeDeleted=false" },
{ true, 150, "", 0, "maxResults=150" },
{ false, 150, "", 0, "includeDeleted=false&maxResults=150" },
{ true, 10, "", 0, "maxResults=10" },
{ false, 10, "", 0, "includeDeleted=false&maxResults=10" },

{ true, 100, "token", 0, "pageToken=token" },
{ false, 100, "token", 0, "includeDeleted=false&pageToken=token" },
{ true, 150, "token", 0, "maxResults=150&pageToken=token" },
{ false, 150, "token", 0,
"?includeDeleted=false&maxResults=150&pageToken=token" },
{ true, 10, "token", 0, "?maxResults=10&pageToken=token" },
"includeDeleted=false&maxResults=150&pageToken=token" },
{ true, 10, "token", 0, "maxResults=10&pageToken=token" },
{ false, 10, "token", 0,
"?includeDeleted=false&maxResults=10&pageToken=token" },
"includeDeleted=false&maxResults=10&pageToken=token" },

{ true, 100, "", 12345, "?startChangeId=12345" },
{ false, 100, "", 12345, "?includeDeleted=false&startChangeId=12345" },
{ true, 150, "", 12345, "?maxResults=150&startChangeId=12345" },
{ true, 100, "", 12345, "startChangeId=12345" },
{ false, 100, "", 12345, "includeDeleted=false&startChangeId=12345" },
{ true, 150, "", 12345, "maxResults=150&startChangeId=12345" },
{ false, 150, "", 12345,
"?includeDeleted=false&maxResults=150&startChangeId=12345" },
{ true, 10, "", 12345, "?maxResults=10&startChangeId=12345" },
"includeDeleted=false&maxResults=150&startChangeId=12345" },
{ true, 10, "", 12345, "maxResults=10&startChangeId=12345" },
{ false, 10, "", 12345,
"?includeDeleted=false&maxResults=10&startChangeId=12345" },
"includeDeleted=false&maxResults=10&startChangeId=12345" },

{ true, 100, "token", 12345, "?pageToken=token&startChangeId=12345" },
{ true, 100, "token", 12345, "pageToken=token&startChangeId=12345" },
{ false, 100, "token", 12345,
"?includeDeleted=false&pageToken=token&startChangeId=12345" },
"includeDeleted=false&pageToken=token&startChangeId=12345" },
{ true, 150, "token", 12345,
"?maxResults=150&pageToken=token&startChangeId=12345" },
"maxResults=150&pageToken=token&startChangeId=12345" },
{ false, 150, "token", 12345,
"?includeDeleted=false&maxResults=150&pageToken=token"
"includeDeleted=false&maxResults=150&pageToken=token"
"&startChangeId=12345" },
{ true, 10, "token", 12345,
"?maxResults=10&pageToken=token&startChangeId=12345" },
"maxResults=10&pageToken=token&startChangeId=12345" },
{ false, 10, "token", 12345,
"?includeDeleted=false&maxResults=10&pageToken=token"
"includeDeleted=false&maxResults=10&pageToken=token"
"&startChangeId=12345" },
};

const std::string kV2ChangesUrlPrefix =
"https://www.example.com/drive/v2/changes";
const std::string kV2BetaChangesUrlPrefix =
"https://www.example.com/drive/v2beta/changes?"
"supportsTeamDrives=true&includeTeamDriveItems=true";
for (size_t i = 0; i < arraysize(kTestPatterns); ++i) {
EXPECT_EQ("https://www.example.com/drive/v2/changes" +
EXPECT_EQ(kV2ChangesUrlPrefix +
(kTestPatterns[i].expected_query.empty() ? "" : "?") +
kTestPatterns[i].expected_query,
url_generator_.GetChangesListUrl(kTestPatterns[i].include_deleted,
kTestPatterns[i].max_results,
kTestPatterns[i].page_token,
kTestPatterns[i].start_change_id)
.spec());
EXPECT_EQ(kV2BetaChangesUrlPrefix +
(kTestPatterns[i].expected_query.empty() ? "" : "&") +
kTestPatterns[i].expected_query,
team_drives_url_generator_.GetChangesListUrl(
kTestPatterns[i].include_deleted,
kTestPatterns[i].max_results,
kTestPatterns[i].page_token,
kTestPatterns[i].start_change_id)
.spec());
}
}

Expand Down
Loading

0 comments on commit eb24cc5

Please sign in to comment.