Commit 98ef0278 authored by ckehoe@chromium.org's avatar ckehoe@chromium.org

Using API key specified from js

BUG=400617

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

Cr-Commit-Position: refs/heads/master@{#289511}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289511 0039d316-1c4b-4281-b951-d872f2087c98
parent a6222c50
...@@ -33,11 +33,9 @@ const char kShuttingDownMessage[] = "Shutting down."; ...@@ -33,11 +33,9 @@ const char kShuttingDownMessage[] = "Shutting down.";
// CopresenceService implementation: // CopresenceService implementation:
CopresenceService::CopresenceService(content::BrowserContext* context) CopresenceService::CopresenceService(content::BrowserContext* context)
: is_shutting_down_(false), browser_context_(context) { : is_shutting_down_(false), browser_context_(context) {}
}
CopresenceService::~CopresenceService() { CopresenceService::~CopresenceService() {}
}
copresence::CopresenceClient* CopresenceService::client() { copresence::CopresenceClient* CopresenceService::client() {
if (!client_ && !is_shutting_down_) if (!client_ && !is_shutting_down_)
...@@ -109,6 +107,10 @@ const std::string CopresenceService::GetPlatformVersionString() const { ...@@ -109,6 +107,10 @@ const std::string CopresenceService::GetPlatformVersionString() const {
return chrome::VersionInfo().CreateVersionString(); return chrome::VersionInfo().CreateVersionString();
} }
const std::string CopresenceService::GetAPIKey() const {
return api_key_;
}
copresence::WhispernetClient* CopresenceService::GetWhispernetClient() { copresence::WhispernetClient* CopresenceService::GetWhispernetClient() {
return whispernet_client(); return whispernet_client();
} }
...@@ -163,8 +165,9 @@ ExtensionFunction::ResponseAction CopresenceSetApiKeyFunction::Run() { ...@@ -163,8 +165,9 @@ ExtensionFunction::ResponseAction CopresenceSetApiKeyFunction::Run() {
api::copresence::SetApiKey::Params::Create(*args_)); api::copresence::SetApiKey::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get()); EXTENSION_FUNCTION_VALIDATE(params.get());
// TODO(rkc): Use the API key set by this function for this app. // The api key may be set to empty, to clear it.
// http://crbug.com/400617. CopresenceService::GetFactoryInstance()->Get(browser_context())
->set_api_key(params->api_key);
return RespondNow(NoArguments()); return RespondNow(NoArguments());
} }
......
...@@ -43,6 +43,8 @@ class CopresenceService : public BrowserContextKeyedAPI, ...@@ -43,6 +43,8 @@ class CopresenceService : public BrowserContextKeyedAPI,
return apps_by_subscription_id_; return apps_by_subscription_id_;
} }
void set_api_key(const std::string& api_key) { api_key_ = api_key; }
// BrowserContextKeyedAPI implementation. // BrowserContextKeyedAPI implementation.
static BrowserContextKeyedAPIFactory<CopresenceService>* GetFactoryInstance(); static BrowserContextKeyedAPIFactory<CopresenceService>* GetFactoryInstance();
...@@ -56,6 +58,7 @@ class CopresenceService : public BrowserContextKeyedAPI, ...@@ -56,6 +58,7 @@ class CopresenceService : public BrowserContextKeyedAPI,
const std::vector<copresence::Message>& message) OVERRIDE; const std::vector<copresence::Message>& message) OVERRIDE;
virtual net::URLRequestContextGetter* GetRequestContext() const OVERRIDE; virtual net::URLRequestContextGetter* GetRequestContext() const OVERRIDE;
virtual const std::string GetPlatformVersionString() const OVERRIDE; virtual const std::string GetPlatformVersionString() const OVERRIDE;
virtual const std::string GetAPIKey() const OVERRIDE;
virtual copresence::WhispernetClient* GetWhispernetClient() OVERRIDE; virtual copresence::WhispernetClient* GetWhispernetClient() OVERRIDE;
// BrowserContextKeyedAPI implementation. // BrowserContextKeyedAPI implementation.
...@@ -65,6 +68,8 @@ class CopresenceService : public BrowserContextKeyedAPI, ...@@ -65,6 +68,8 @@ class CopresenceService : public BrowserContextKeyedAPI,
std::map<std::string, std::string> apps_by_subscription_id_; std::map<std::string, std::string> apps_by_subscription_id_;
content::BrowserContext* const browser_context_; content::BrowserContext* const browser_context_;
std::string api_key_;
scoped_ptr<copresence::CopresenceClient> client_; scoped_ptr<copresence::CopresenceClient> client_;
scoped_ptr<copresence::WhispernetClient> whispernet_client_; scoped_ptr<copresence::WhispernetClient> whispernet_client_;
......
...@@ -5,4 +5,5 @@ include_rules = [ ...@@ -5,4 +5,5 @@ include_rules = [
"+google_apis", "+google_apis",
"+media", "+media",
"+net", "+net",
"+url",
] ]
...@@ -29,6 +29,12 @@ message Token { ...@@ -29,6 +29,12 @@ message Token {
optional TokenStatus status = 3; optional TokenStatus status = 3;
optional Debug debug = 4; optional Debug debug = 4;
} }
message DeviceFingerprint {
optional string manufacturer = 1;
optional string model = 2;
optional PlatformType type = 3;
optional string platform_version = 4;
}
message TokenTechnology { message TokenTechnology {
optional TokenMedium medium = 1; optional TokenMedium medium = 1;
repeated TokenInstructionType instruction_type = 2; repeated TokenInstructionType instruction_type = 2;
......
...@@ -52,6 +52,13 @@ enum TokenInstructionType { ...@@ -52,6 +52,13 @@ enum TokenInstructionType {
TRANSMIT = 1; TRANSMIT = 1;
RECEIVE = 2; RECEIVE = 2;
} }
enum PlatformType {
UNKNOWN_PLATFORM_TYPE = 0;
CHROMECAST_PLATFORM_TYPE = 5;
ANDROID_PLATFORM_TYPE = 6;
IOS_PLATFORM_TYPE = 7;
CHROME_PLATFORM_TYPE = 8;
}
enum InstructionType { enum InstructionType {
UNKNOWN_INSTRUCTION_TYPE = 0; UNKNOWN_INSTRUCTION_TYPE = 0;
TOKEN = 1; TOKEN = 1;
......
...@@ -10,6 +10,7 @@ message RequestHeader { ...@@ -10,6 +10,7 @@ message RequestHeader {
optional int64 current_time_millis = 6; optional int64 current_time_millis = 6;
optional string registered_device_id = 7; optional string registered_device_id = 7;
repeated string experiment_override = 8; repeated string experiment_override = 8;
optional DeviceFingerprint device_fingerprint = 10;
optional string configuration_etag = 11; optional string configuration_etag = 11;
} }
message ResponseHeader { message ResponseHeader {
......
...@@ -38,6 +38,8 @@ class CopresenceClientDelegate { ...@@ -38,6 +38,8 @@ class CopresenceClientDelegate {
virtual const std::string GetPlatformVersionString() const = 0; virtual const std::string GetPlatformVersionString() const = 0;
virtual const std::string GetAPIKey() const = 0;
virtual WhispernetClient* GetWhispernetClient() = 0; virtual WhispernetClient* GetWhispernetClient() = 0;
}; };
......
...@@ -14,42 +14,39 @@ ...@@ -14,42 +14,39 @@
#include "net/http/http_status_code.h" #include "net/http/http_status_code.h"
#include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
#include "url/gurl.h"
namespace copresence { namespace copresence {
// TODO(ckehoe): Come up with a better fix for Chromium. const char HttpPost::kApiKeyField[] = "key";
#ifdef GOOGLE_CHROME_BUILD
namespace {
const char kApiKeyField[] = "key";
} // namespace
#endif
const char HttpPost::kTracingTokenField[] = "trace"; const char HttpPost::kTracingTokenField[] = "trace";
HttpPost::HttpPost(net::URLRequestContextGetter* url_context_getter, HttpPost::HttpPost(net::URLRequestContextGetter* url_context_getter,
const std::string& server_host, const std::string& server_host,
const std::string& rpc_name, const std::string& rpc_name,
const std::string& tracing_token, const std::string& tracing_token,
std::string api_key,
const google::protobuf::MessageLite& request_proto) { const google::protobuf::MessageLite& request_proto) {
// Create the base URL to call. // Create the base URL to call.
GURL url(server_host + "/" + rpc_name); GURL url(server_host + "/" + rpc_name);
// Add the Chrome API key.
// TODO(ckehoe): Replace this with an app-specific key once the
// server API supports it. Also fix the Chromium case.
#ifdef GOOGLE_CHROME_BUILD
DCHECK(google_apis::HasKeysConfigured());
url = net::AppendQueryParameter(url, kApiKeyField, google_apis::GetAPIKey());
#endif
// Add the tracing token, if specified. // Add the tracing token, if specified.
if (!tracing_token.empty()) { if (!tracing_token.empty()) {
url = net::AppendQueryParameter( url = net::AppendQueryParameter(
url, kTracingTokenField, "token:" + tracing_token); url, kTracingTokenField, "token:" + tracing_token);
} }
// If no API key is specified, use the Chrome API key.
if (api_key.empty()) {
#ifdef GOOGLE_CHROME_BUILD
DCHECK(google_apis::HasKeysConfigured());
api_key = google_apis::GetAPIKey();
#else
LOG(ERROR) << "No Copresence API key provided";
#endif
}
url = net::AppendQueryParameter(url, kApiKeyField, api_key);
// Serialize the proto for transmission. // Serialize the proto for transmission.
std::string request_data; std::string request_data;
bool serialize_success = request_proto.SerializeToString(&request_data); bool serialize_success = request_proto.SerializeToString(&request_data);
......
...@@ -36,19 +36,14 @@ class HttpPost : public net::URLFetcherDelegate { ...@@ -36,19 +36,14 @@ class HttpPost : public net::URLFetcherDelegate {
typedef base::Callback<void(int, const std::string&)> typedef base::Callback<void(int, const std::string&)>
ResponseCallback; ResponseCallback;
// An id for testing url fetching. // Create a request to the Copresence server.
static const int kUrlFetcherId = 1; // |url_context_getter| is owned by the caller,
// and the context it provides must be available until the request completes.
// The query parameter to send Apiary tracing tokens.
static const char kTracingTokenField[];
// Create a request to the Copresence server. |url_context_getter|
// is owned by the caller, and the context it provides must be available
// until the request completes.
HttpPost(net::URLRequestContextGetter* url_context_getter, HttpPost(net::URLRequestContextGetter* url_context_getter,
const std::string& server_host, const std::string& server_host,
const std::string& rpc_name, const std::string& rpc_name,
const std::string& tracing_token, const std::string& tracing_token,
std::string api_key, // If blank, we overwrite with a default.
const google::protobuf::MessageLite& request_proto); const google::protobuf::MessageLite& request_proto);
// HTTP requests are cancelled on delete. // HTTP requests are cancelled on delete.
...@@ -58,10 +53,17 @@ class HttpPost : public net::URLFetcherDelegate { ...@@ -58,10 +53,17 @@ class HttpPost : public net::URLFetcherDelegate {
void Start(const ResponseCallback& response_callback); void Start(const ResponseCallback& response_callback);
private: private:
static const int kUrlFetcherId = 1;
static const char kApiKeyField[];
static const char kTracingTokenField[];
friend class HttpPostTest;
// Overridden from net::URLFetcherDelegate. // Overridden from net::URLFetcherDelegate.
virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
ResponseCallback response_callback_; ResponseCallback response_callback_;
scoped_ptr<net::URLFetcher> url_fetcher_; scoped_ptr<net::URLFetcher> url_fetcher_;
DISALLOW_COPY_AND_ASSIGN(HttpPost); DISALLOW_COPY_AND_ASSIGN(HttpPost);
......
...@@ -11,12 +11,14 @@ ...@@ -11,12 +11,14 @@
#include "net/url_request/test_url_fetcher_factory.h" #include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_test_util.h" #include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace { namespace {
const char kFakeServerHost[] = "test.server.google.com"; const char kFakeServerHost[] = "test.server.google.com";
const char kRPCName[] = "testRpc"; const char kRPCName[] = "testRpc";
const char kTracingToken[] = "trace me!"; const char kTracingToken[] = "trace me!";
const char kApiKey[] = "unlock ALL the APIz";
} // namespace } // namespace
...@@ -48,6 +50,7 @@ class HttpPostTest : public testing::Test { ...@@ -48,6 +50,7 @@ class HttpPostTest : public testing::Test {
std::string("http://") + kFakeServerHost, std::string("http://") + kFakeServerHost,
kRPCName, kRPCName,
"", "",
kApiKey,
proto_); proto_);
pending_post_->Start(base::Bind(&HttpPostTest::TestResponseCallback, pending_post_->Start(base::Bind(&HttpPostTest::TestResponseCallback,
base::Unretained(this))); base::Unretained(this)));
...@@ -61,6 +64,26 @@ class HttpPostTest : public testing::Test { ...@@ -61,6 +64,26 @@ class HttpPostTest : public testing::Test {
received_response_ == response; received_response_ == response;
} }
net::TestURLFetcher* GetFetcher() {
return fetcher_factory_.GetFetcherByID(HttpPost::kUrlFetcherId);
}
const std::string GetApiKeySent() {
std::string api_key_sent;
net::GetValueForKeyInQuery(GetFetcher()->GetOriginalURL(),
HttpPost::kApiKeyField,
&api_key_sent);
return api_key_sent;
}
const std::string GetTracingTokenSent() {
std::string tracing_token_sent;
net::GetValueForKeyInQuery(GetFetcher()->GetOriginalURL(),
HttpPost::kTracingTokenField,
&tracing_token_sent);
return tracing_token_sent;
}
net::TestURLFetcherFactory fetcher_factory_; net::TestURLFetcherFactory fetcher_factory_;
scoped_refptr<net::TestURLRequestContextGetter> context_getter_; scoped_refptr<net::TestURLRequestContextGetter> context_getter_;
...@@ -79,28 +102,29 @@ TEST_F(HttpPostTest, OKResponse) { ...@@ -79,28 +102,29 @@ TEST_F(HttpPostTest, OKResponse) {
std::string("http://") + kFakeServerHost, std::string("http://") + kFakeServerHost,
kRPCName, kRPCName,
kTracingToken, kTracingToken,
kApiKey,
proto_); proto_);
post->Start(base::Bind(&HttpPostTest::TestResponseCallback, post->Start(base::Bind(&HttpPostTest::TestResponseCallback,
base::Unretained(this))); base::Unretained(this)));
// Verify that the right data got sent to the right place. // Verify that the data was sent to the right place.
net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID( GURL requested_url = GetFetcher()->GetOriginalURL();
HttpPost::kUrlFetcherId); EXPECT_EQ(kFakeServerHost, requested_url.host());
EXPECT_EQ(kFakeServerHost, fetcher->GetOriginalURL().host()); EXPECT_EQ(std::string("/") + kRPCName, requested_url.path());
EXPECT_EQ(std::string("/") + kRPCName, fetcher->GetOriginalURL().path());
std::string tracing_token_sent; // Check query parameters.
EXPECT_TRUE(net::GetValueForKeyInQuery(fetcher->GetOriginalURL(), EXPECT_EQ(kApiKey, GetApiKeySent());
HttpPost::kTracingTokenField, EXPECT_EQ(std::string("token:") + kTracingToken, GetTracingTokenSent());
&tracing_token_sent));
EXPECT_EQ(std::string("token:") + kTracingToken, tracing_token_sent); // Verify that the right data was sent.
std::string upload_data; std::string upload_data;
ASSERT_TRUE(proto_.SerializeToString(&upload_data)); ASSERT_TRUE(proto_.SerializeToString(&upload_data));
EXPECT_EQ(upload_data, fetcher->upload_data()); EXPECT_EQ(upload_data, GetFetcher()->upload_data());
// Send a response and check that it's passed along correctly. // Send a response and check that it's passed along correctly.
fetcher->set_response_code(net::HTTP_OK); GetFetcher()->set_response_code(net::HTTP_OK);
fetcher->SetResponseString("Hello World!"); GetFetcher()->SetResponseString("Hello World!");
fetcher->delegate()->OnURLFetchComplete(fetcher); GetFetcher()->delegate()->OnURLFetchComplete(GetFetcher());
EXPECT_EQ(net::HTTP_OK, received_response_code_); EXPECT_EQ(net::HTTP_OK, received_response_code_);
EXPECT_EQ("Hello World!", received_response_); EXPECT_EQ("Hello World!", received_response_);
delete post; delete post;
......
...@@ -521,8 +521,8 @@ RequestHeader* RpcHandler::CreateRequestHeader( ...@@ -521,8 +521,8 @@ RequestHeader* RpcHandler::CreateRequestHeader(
const std::string& client_name) const { const std::string& client_name) const {
RequestHeader* header = new RequestHeader; RequestHeader* header = new RequestHeader;
header->set_allocated_framework_version( header->set_allocated_framework_version(CreateVersion(
CreateVersion("Chrome", delegate_->GetPlatformVersionString())); "Chrome", delegate_->GetPlatformVersionString()));
if (!client_name.empty()) { if (!client_name.empty()) {
header->set_allocated_client_version( header->set_allocated_client_version(
CreateVersion(client_name, std::string())); CreateVersion(client_name, std::string()));
...@@ -530,6 +530,11 @@ RequestHeader* RpcHandler::CreateRequestHeader( ...@@ -530,6 +530,11 @@ RequestHeader* RpcHandler::CreateRequestHeader(
header->set_current_time_millis(base::Time::Now().ToJsTime()); header->set_current_time_millis(base::Time::Now().ToJsTime());
header->set_registered_device_id(device_id_); header->set_registered_device_id(device_id_);
DeviceFingerprint* fingerprint = new DeviceFingerprint;
fingerprint->set_platform_version(delegate_->GetPlatformVersionString());
fingerprint->set_type(CHROME_PLATFORM_TYPE);
header->set_allocated_device_fingerprint(fingerprint);
return header; return header;
} }
...@@ -558,13 +563,14 @@ void RpcHandler::SendHttpPost(net::URLRequestContextGetter* url_context_getter, ...@@ -558,13 +563,14 @@ void RpcHandler::SendHttpPost(net::URLRequestContextGetter* url_context_getter,
kDefaultCopresenceServer; kDefaultCopresenceServer;
// Create the request and keep a pointer until it completes. // Create the request and keep a pointer until it completes.
const std::string& tracing_token = HttpPost* http_post = new HttpPost(
command_line->GetSwitchValueASCII(switches::kCopresenceTracingToken); url_context_getter,
HttpPost* http_post = new HttpPost(url_context_getter,
copresence_server_host, copresence_server_host,
rpc_name, rpc_name,
tracing_token, command_line->GetSwitchValueASCII(switches::kCopresenceTracingToken),
delegate_->GetAPIKey(),
*request_proto); *request_proto);
http_post->Start(base::Bind(callback, http_post)); http_post->Start(base::Bind(callback, http_post));
pending_posts_.insert(http_post); pending_posts_.insert(http_post);
} }
......
...@@ -25,6 +25,8 @@ namespace copresence { ...@@ -25,6 +25,8 @@ namespace copresence {
namespace { namespace {
const char kChromeVersion[] = "Chrome Version String";
void AddMessageWithStrategy(ReportRequest* report, void AddMessageWithStrategy(ReportRequest* report,
BroadcastScanConfiguration strategy) { BroadcastScanConfiguration strategy) {
report->mutable_manage_messages_request()->add_message_to_publish() report->mutable_manage_messages_request()->add_message_to_publish()
...@@ -83,7 +85,7 @@ class FakeDirectiveHandler : public DirectiveHandler { ...@@ -83,7 +85,7 @@ class FakeDirectiveHandler : public DirectiveHandler {
class RpcHandlerTest : public testing::Test, public CopresenceClientDelegate { class RpcHandlerTest : public testing::Test, public CopresenceClientDelegate {
public: public:
RpcHandlerTest() : rpc_handler_(this), status_(SUCCESS) { RpcHandlerTest() : rpc_handler_(this), status_(SUCCESS), api_key_("API key") {
rpc_handler_.server_post_callback_ = rpc_handler_.server_post_callback_ =
base::Bind(&RpcHandlerTest::CaptureHttpPost, base::Unretained(this)); base::Bind(&RpcHandlerTest::CaptureHttpPost, base::Unretained(this));
rpc_handler_.device_id_ = "Device ID"; rpc_handler_.device_id_ = "Device ID";
...@@ -168,7 +170,11 @@ class RpcHandlerTest : public testing::Test, public CopresenceClientDelegate { ...@@ -168,7 +170,11 @@ class RpcHandlerTest : public testing::Test, public CopresenceClientDelegate {
} }
virtual const std::string GetPlatformVersionString() const OVERRIDE { virtual const std::string GetPlatformVersionString() const OVERRIDE {
return "Version String"; return kChromeVersion;
}
virtual const std::string GetAPIKey() const OVERRIDE {
return api_key_;
} }
virtual WhispernetClient* GetWhispernetClient() OVERRIDE { virtual WhispernetClient* GetWhispernetClient() OVERRIDE {
...@@ -180,10 +186,11 @@ class RpcHandlerTest : public testing::Test, public CopresenceClientDelegate { ...@@ -180,10 +186,11 @@ class RpcHandlerTest : public testing::Test, public CopresenceClientDelegate {
base::MessageLoop message_loop_; base::MessageLoop message_loop_;
RpcHandler rpc_handler_; RpcHandler rpc_handler_;
CopresenceStatus status_;
std::string api_key_;
std::string rpc_name_; std::string rpc_name_;
scoped_ptr<MessageLite> request_proto_; scoped_ptr<MessageLite> request_proto_;
CopresenceStatus status_;
std::map<std::string, std::vector<Message> > messages_by_subscription_; std::map<std::string, std::vector<Message> > messages_by_subscription_;
}; };
...@@ -287,11 +294,14 @@ TEST_F(RpcHandlerTest, CreateRequestHeader) { ...@@ -287,11 +294,14 @@ TEST_F(RpcHandlerTest, CreateRequestHeader) {
StatusCallback()); StatusCallback());
EXPECT_EQ(RpcHandler::kReportRequestRpcName, rpc_name_); EXPECT_EQ(RpcHandler::kReportRequestRpcName, rpc_name_);
ReportRequest* report = static_cast<ReportRequest*>(request_proto_.get()); ReportRequest* report = static_cast<ReportRequest*>(request_proto_.get());
EXPECT_TRUE(report->header().has_framework_version()); EXPECT_EQ(kChromeVersion,
report->header().framework_version().version_name());
EXPECT_EQ("CreateRequestHeader App ID", EXPECT_EQ("CreateRequestHeader App ID",
report->header().client_version().client()); report->header().client_version().client());
EXPECT_EQ("CreateRequestHeader Device ID", EXPECT_EQ("CreateRequestHeader Device ID",
report->header().registered_device_id()); report->header().registered_device_id());
EXPECT_EQ(CHROME_PLATFORM_TYPE,
report->header().device_fingerprint().type());
} }
// TODO(ckehoe): Renable these after https://codereview.chromium.org/453203002/ // TODO(ckehoe): Renable these after https://codereview.chromium.org/453203002/
......
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