Commit 9d917939 authored by kinaba@chromium.org's avatar kinaba@chromium.org

drive: Support authorizing third-party Drive apps for opening files.

Along the way, replace the official key check in DriveAppRegistry::IsUninstallSupported
by the new devoted function. (In fact, the macro is available
only during google_apis/ hence the previous code was not working well...)


BUG=332332

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245565 0039d316-1c4b-4281-b951-d872f2087c98
parent c8868c8b
......@@ -21,6 +21,7 @@
#include "google_apis/drive/gdata_wapi_parser.h"
#include "google_apis/drive/gdata_wapi_requests.h"
#include "google_apis/drive/request_sender.h"
#include "google_apis/google_api_keys.h"
#include "net/url_request/url_request_context_getter.h"
using content::BrowserThread;
......@@ -784,12 +785,28 @@ CancelCallback DriveAPIService::AuthorizeApp(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(!callback.is_null());
// Files.Authorize is only available for whitelisted clients like official
// Google Chrome. In other cases, we fall back to Files.Get that returns the
// same value as Files.Authorize without doing authorization. In that case,
// the app can open if it was authorized by other means (from whitelisted
// clients or drive.google.com web UI.)
if (google_apis::IsGoogleChromeAPIKeyUsed()) {
google_apis::drive::FilesAuthorizeRequest* request =
new google_apis::drive::FilesAuthorizeRequest(
sender_.get(), url_generator_,
base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
request->set_app_id(app_id);
request->set_file_id(resource_id);
request->set_fields(kFileResourceOpenWithLinksFields);
return sender_->StartRequestWithRetry(request);
} else {
FilesGetRequest* request = new FilesGetRequest(
sender_.get(), url_generator_,
base::Bind(&ExtractOpenUrlAndRun, app_id, callback));
request->set_file_id(resource_id);
request->set_fields(kFileResourceOpenWithLinksFields);
return sender_->StartRequestWithRetry(request);
}
}
CancelCallback DriveAPIService::UninstallApp(
......
......@@ -13,6 +13,7 @@
#include "chrome/browser/drive/drive_service_interface.h"
#include "content/public/browser/browser_thread.h"
#include "google_apis/drive/drive_api_parser.h"
#include "google_apis/google_api_keys.h"
using content::BrowserThread;
......@@ -205,11 +206,7 @@ void DriveAppRegistry::OnAppUninstalled(const std::string& app_id,
// static
bool DriveAppRegistry::IsAppUninstallSupported() {
#ifdef USE_OFFICIAL_GOOGLE_API_KEYS
return true;
#else
return false;
#endif
return google_apis::IsGoogleChromeAPIKeyUsed();
}
namespace util {
......
......@@ -162,6 +162,29 @@ GURL FilesGetRequest::GetURLInternal() const {
return url_generator_.GetFilesGetUrl(file_id_);
}
//============================ FilesAuthorizeRequest ===========================
FilesAuthorizeRequest::FilesAuthorizeRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const FileResourceCallback& callback)
: DriveApiDataRequest(
sender,
base::Bind(&ParseJsonAndRun<FileResource>, callback)),
url_generator_(url_generator) {
DCHECK(!callback.is_null());
}
FilesAuthorizeRequest::~FilesAuthorizeRequest() {}
net::URLFetcher::RequestType FilesAuthorizeRequest::GetRequestType() const {
return net::URLFetcher::POST;
}
GURL FilesAuthorizeRequest::GetURLInternal() const {
return url_generator_.GetFilesAuthorizeUrl(file_id_, app_id_);
}
//============================ FilesInsertRequest ============================
FilesInsertRequest::FilesInsertRequest(
......
......@@ -93,6 +93,38 @@ class FilesGetRequest : public DriveApiDataRequest {
DISALLOW_COPY_AND_ASSIGN(FilesGetRequest);
};
//============================ FilesAuthorizeRequest ===========================
// This class performs request for authorizing an app to access a file.
// This request is mapped to /drive/v2internal/file/authorize internal endpoint.
class FilesAuthorizeRequest : public DriveApiDataRequest {
public:
FilesAuthorizeRequest(RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const FileResourceCallback& callback);
virtual ~FilesAuthorizeRequest();
// Required parameter.
const std::string& file_id() const { return file_id_; }
void set_file_id(const std::string& file_id) { file_id_ = file_id; }
const std::string& app_id() const { return app_id_; }
void set_app_id(const std::string& app_id) { app_id_ = app_id; }
protected:
// Overridden from GetDataRequest.
virtual net::URLFetcher::RequestType GetRequestType() const OVERRIDE;
// Overridden from DriveApiDataRequest.
virtual GURL GetURLInternal() const OVERRIDE;
private:
const DriveApiUrlGenerator url_generator_;
std::string file_id_;
std::string app_id_;
DISALLOW_COPY_AND_ASSIGN(FilesAuthorizeRequest);
};
//============================ FilesInsertRequest =============================
// This class performs the request for creating a resource.
......
......@@ -17,9 +17,6 @@ namespace {
// Hard coded URLs for communication with a google drive server.
const char kDriveV2AboutUrl[] = "/drive/v2/about";
const char kDriveV2AppsUrl[] = "/drive/v2/apps";
// apps.delete API is exposed through a special endpoint v2internal that
// is accessible only by the official API key for Chrome.
const char kDriveV2AppsDeleteUrlFormat[] = "/drive/v2internal/apps/%s";
const char kDriveV2ChangelistUrl[] = "/drive/v2/changes";
const char kDriveV2FilesUrl[] = "/drive/v2/files";
const char kDriveV2FileUrlPrefix[] = "/drive/v2/files/";
......@@ -33,6 +30,12 @@ const char kDriveV2InitiateUploadNewFileUrl[] = "/upload/drive/v2/files";
const char kDriveV2InitiateUploadExistingFileUrlPrefix[] =
"/upload/drive/v2/files/";
// 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 kDriveV2AppsDeleteUrlFormat[] = "/drive/v2internal/apps/%s";
const char kDriveV2FilesAuthorizeUrlFormat[] =
"/drive/v2internal/files/%s/authorize?appId=%s";
GURL AddResumableUploadParam(const GURL& url) {
return net::AppendOrReplaceQueryParameter(url, "uploadType", "resumable");
}
......@@ -72,6 +75,14 @@ GURL DriveApiUrlGenerator::GetFilesGetUrl(const std::string& file_id) const {
return base_url_.Resolve(kDriveV2FileUrlPrefix + net::EscapePath(file_id));
}
GURL DriveApiUrlGenerator::GetFilesAuthorizeUrl(
const std::string& file_id,
const std::string& app_id) const {
return base_url_.Resolve(base::StringPrintf(kDriveV2FilesAuthorizeUrlFormat,
net::EscapePath(file_id).c_str(),
net::EscapePath(app_id).c_str()));
}
GURL DriveApiUrlGenerator::GetFilesInsertUrl() const {
return base_url_.Resolve(kDriveV2FilesUrl);
}
......
......@@ -38,6 +38,10 @@ class DriveApiUrlGenerator {
// Returns a URL to fetch a file metadata.
GURL GetFilesGetUrl(const std::string& file_id) const;
// Returns a URL to authorize an app to access a file.
GURL GetFilesAuthorizeUrl(const std::string& file_id,
const std::string& app_id) const;
// Returns a URL to create a resource.
GURL GetFilesInsertUrl() const;
......
......@@ -65,6 +65,15 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesGetUrl) {
test_url_generator_.GetFilesGetUrl("file:file_id").spec());
}
TEST_F(DriveApiUrlGeneratorTest, GetFilesAuthorizeUrl) {
EXPECT_EQ(
"https://www.googleapis.com/drive/v2internal/files/aa/authorize?appId=bb",
url_generator_.GetFilesAuthorizeUrl("aa", "bb").spec());
EXPECT_EQ(
"http://127.0.0.1:12345/drive/v2internal/files/foo/authorize?appId=bar",
test_url_generator_.GetFilesAuthorizeUrl("foo", "bar").spec());
}
TEST_F(DriveApiUrlGeneratorTest, GetFilesInsertUrl) {
EXPECT_EQ("https://www.googleapis.com/drive/v2/files",
url_generator_.GetFilesInsertUrl().spec());
......
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