Commit 18d64ecb authored by noamsml's avatar noamsml Committed by Commit bot

API change to allow sticker authentication for devices

Change API to match protocol that may allow sticker authentication
for devices. The PIN will not necessarily be available at provision
time, and the client will need to send a user-typed PIN at
code verification time.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#291988}
parent 6b6cd502
...@@ -124,7 +124,9 @@ class GcdPrivateAPIImpl : public EventRouter::Observer, ...@@ -124,7 +124,9 @@ class GcdPrivateAPIImpl : public EventRouter::Observer,
int port, int port,
ConfirmationCodeCallback callback); ConfirmationCodeCallback callback);
void ConfirmCode(int session_id, SessionEstablishedCallback callback); void ConfirmCode(int session_id,
const std::string& code,
SessionEstablishedCallback callback);
void SendMessage(int session_id, void SendMessage(int session_id,
const std::string& api, const std::string& api,
...@@ -229,6 +231,7 @@ class GcdPrivateSessionHolder ...@@ -229,6 +231,7 @@ class GcdPrivateSessionHolder
void Start(const ConfirmationCodeCallback& callback); void Start(const ConfirmationCodeCallback& callback);
void ConfirmCode( void ConfirmCode(
const std::string& code,
const GcdPrivateAPIImpl::SessionEstablishedCallback& callback); const GcdPrivateAPIImpl::SessionEstablishedCallback& callback);
void SendMessage(const std::string& api, void SendMessage(const std::string& api,
...@@ -240,9 +243,9 @@ class GcdPrivateSessionHolder ...@@ -240,9 +243,9 @@ class GcdPrivateSessionHolder
private: private:
// local_discovery::PrivetV3Session::Delegate implementation. // local_discovery::PrivetV3Session::Delegate implementation.
virtual void OnSetupConfirmationNeeded( virtual void OnSetupConfirmationNeeded(
const std::string& confirmation_code) OVERRIDE; const std::string& confirmation_code,
virtual void OnSessionEstablished() OVERRIDE; api::gcd_private::ConfirmationType confirmation_type) OVERRIDE;
virtual void OnCannotEstablishSession() OVERRIDE; virtual void OnSessionStatus(api::gcd_private::Status status) OVERRIDE;
scoped_ptr<local_discovery::PrivetHTTPClient> http_client_; scoped_ptr<local_discovery::PrivetHTTPClient> http_client_;
scoped_ptr<local_discovery::PrivetV3Session> privet_session_; scoped_ptr<local_discovery::PrivetV3Session> privet_session_;
...@@ -371,6 +374,7 @@ void GcdPrivateAPIImpl::EstablishSession(const std::string& ip_address, ...@@ -371,6 +374,7 @@ void GcdPrivateAPIImpl::EstablishSession(const std::string& ip_address,
} }
void GcdPrivateAPIImpl::ConfirmCode(int session_id, void GcdPrivateAPIImpl::ConfirmCode(int session_id,
const std::string& code,
SessionEstablishedCallback callback) { SessionEstablishedCallback callback) {
GCDSessionMap::iterator found = sessions_.find(session_id); GCDSessionMap::iterator found = sessions_.find(session_id);
...@@ -379,7 +383,7 @@ void GcdPrivateAPIImpl::ConfirmCode(int session_id, ...@@ -379,7 +383,7 @@ void GcdPrivateAPIImpl::ConfirmCode(int session_id,
return; return;
} }
found->second->ConfirmCode(callback); found->second->ConfirmCode(code, callback);
} }
void GcdPrivateAPIImpl::SendMessage(int session_id, void GcdPrivateAPIImpl::SendMessage(int session_id,
...@@ -551,9 +555,10 @@ void GcdPrivateSessionHolder::Start(const ConfirmationCodeCallback& callback) { ...@@ -551,9 +555,10 @@ void GcdPrivateSessionHolder::Start(const ConfirmationCodeCallback& callback) {
} }
void GcdPrivateSessionHolder::ConfirmCode( void GcdPrivateSessionHolder::ConfirmCode(
const std::string& code,
const GcdPrivateAPIImpl::SessionEstablishedCallback& callback) { const GcdPrivateAPIImpl::SessionEstablishedCallback& callback) {
session_established_callback_ = callback; session_established_callback_ = callback;
privet_session_->ConfirmCode(); privet_session_->ConfirmCode(code);
} }
void GcdPrivateSessionHolder::SendMessage( void GcdPrivateSessionHolder::SendMessage(
...@@ -578,22 +583,16 @@ void GcdPrivateSessionHolder::DeleteRequest(GcdPrivateRequest* request) { ...@@ -578,22 +583,16 @@ void GcdPrivateSessionHolder::DeleteRequest(GcdPrivateRequest* request) {
} }
void GcdPrivateSessionHolder::OnSetupConfirmationNeeded( void GcdPrivateSessionHolder::OnSetupConfirmationNeeded(
const std::string& confirmation_code) { const std::string& confirmation_code,
confirm_callback_.Run(gcd_private::STATUS_SUCCESS, gcd_private::ConfirmationType confirmation_type) {
confirmation_code, confirm_callback_.Run(
gcd_private::CONFIRMATION_TYPE_DISPLAYCODE); gcd_private::STATUS_SUCCESS, confirmation_code, confirmation_type);
confirm_callback_.Reset(); confirm_callback_.Reset();
} }
void GcdPrivateSessionHolder::OnSessionEstablished() { void GcdPrivateSessionHolder::OnSessionStatus(gcd_private::Status status) {
session_established_callback_.Run(gcd_private::STATUS_SUCCESS); session_established_callback_.Run(status);
session_established_callback_.Reset();
}
void GcdPrivateSessionHolder::OnCannotEstablishSession() {
session_established_callback_.Run(gcd_private::STATUS_SESSIONERROR);
session_established_callback_.Reset(); session_established_callback_.Reset();
} }
...@@ -774,8 +773,15 @@ void GcdPrivateEstablishSessionFunction::OnConfirmCodeCallback( ...@@ -774,8 +773,15 @@ void GcdPrivateEstablishSessionFunction::OnConfirmCodeCallback(
gcd_private::Status status, gcd_private::Status status,
const std::string& confirm_code, const std::string& confirm_code,
gcd_private::ConfirmationType confirmation_type) { gcd_private::ConfirmationType confirmation_type) {
results_ = gcd_private::EstablishSession::Results::Create( gcd_private::ConfirmationInfo info;
session_id, status, confirm_code, confirmation_type);
info.type = confirmation_type;
if (!confirm_code.empty()) {
info.code.reset(new std::string(confirm_code));
}
results_ =
gcd_private::EstablishSession::Results::Create(session_id, status, info);
SendResponse(true); SendResponse(true);
} }
...@@ -796,6 +802,7 @@ bool GcdPrivateConfirmCodeFunction::RunAsync() { ...@@ -796,6 +802,7 @@ bool GcdPrivateConfirmCodeFunction::RunAsync() {
gcd_api->ConfirmCode( gcd_api->ConfirmCode(
params->session_id, params->session_id,
params->code,
base::Bind(&GcdPrivateConfirmCodeFunction::OnSessionEstablishedCallback, base::Bind(&GcdPrivateConfirmCodeFunction::OnSessionEstablishedCallback,
this)); this));
......
...@@ -16,6 +16,8 @@ namespace { ...@@ -16,6 +16,8 @@ namespace {
const char kUrlPlaceHolder[] = "http://host/"; const char kUrlPlaceHolder[] = "http://host/";
const char kStubPrivetCode[] = "01234";
GURL CreatePrivetURL(const std::string& path) { GURL CreatePrivetURL(const std::string& path) {
GURL url(kUrlPlaceHolder); GURL url(kUrlPlaceHolder);
GURL::Replacements replacements; GURL::Replacements replacements;
...@@ -105,9 +107,14 @@ void PrivetV3Session::Start() { ...@@ -105,9 +107,14 @@ void PrivetV3Session::Start() {
base::TimeDelta::FromSeconds(1)); base::TimeDelta::FromSeconds(1));
} }
void PrivetV3Session::ConfirmCode() { void PrivetV3Session::ConfirmCode(const std::string& code) {
if (code == kStubPrivetCode) {
code_confirmed_ = true; code_confirmed_ = true;
delegate_->OnSessionEstablished(); delegate_->OnSessionStatus(extensions::api::gcd_private::STATUS_SUCCESS);
} else {
delegate_->OnSessionStatus(
extensions::api::gcd_private::STATUS_BADCONFIRMATIONCODEERROR);
}
} }
void PrivetV3Session::StartRequest(Request* request) { void PrivetV3Session::StartRequest(Request* request) {
...@@ -130,7 +137,9 @@ void PrivetV3Session::StartRequest(Request* request) { ...@@ -130,7 +137,9 @@ void PrivetV3Session::StartRequest(Request* request) {
} }
void PrivetV3Session::ConfirmFakeCode() { void PrivetV3Session::ConfirmFakeCode() {
delegate_->OnSetupConfirmationNeeded("01234"); delegate_->OnSetupConfirmationNeeded(
kStubPrivetCode,
extensions::api::gcd_private::CONFIRMATION_TYPE_DISPLAYCODE);
} }
} // namespace local_discovery } // namespace local_discovery
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "chrome/browser/local_discovery/privet_url_fetcher.h" #include "chrome/browser/local_discovery/privet_url_fetcher.h"
#include "chrome/common/extensions/api/gcd_private.h"
namespace base { namespace base {
class DictionaryValue; class DictionaryValue;
...@@ -32,14 +33,11 @@ class PrivetV3Session { ...@@ -32,14 +33,11 @@ class PrivetV3Session {
// Called when client code should prompt user to check |confirmation_code|. // Called when client code should prompt user to check |confirmation_code|.
virtual void OnSetupConfirmationNeeded( virtual void OnSetupConfirmationNeeded(
const std::string& confirmation_code) = 0; const std::string& confirmation_code,
extensions::api::gcd_private::ConfirmationType confirmation_type) = 0;
// Called when session successfully establish and client code my call virtual void OnSessionStatus(
// |CreateRequest| method. extensions::api::gcd_private::Status status) = 0;
virtual void OnSessionEstablished() = 0;
// Called when session setup fails.
virtual void OnCannotEstablishSession() = 0;
}; };
// Represents request in progress using secure session. // Represents request in progress using secure session.
...@@ -66,7 +64,7 @@ class PrivetV3Session { ...@@ -66,7 +64,7 @@ class PrivetV3Session {
// |OnSessionEstablished|. // |OnSessionEstablished|.
void Start(); void Start();
void ConfirmCode(); void ConfirmCode(const std::string& code);
// Create a single /privet/v3/session/call request. // Create a single /privet/v3/session/call request.
void StartRequest(Request* request); void StartRequest(Request* request);
......
...@@ -21,9 +21,10 @@ using testing::_; ...@@ -21,9 +21,10 @@ using testing::_;
class MockDelegate : public PrivetV3Session::Delegate { class MockDelegate : public PrivetV3Session::Delegate {
public: public:
MOCK_METHOD1(OnSetupConfirmationNeeded, void(const std::string&)); MOCK_METHOD2(OnSetupConfirmationNeeded,
MOCK_METHOD0(OnSessionEstablished, void()); void(const std::string&,
MOCK_METHOD0(OnCannotEstablishSession, void()); extensions::api::gcd_private::ConfirmationType));
MOCK_METHOD1(OnSessionStatus, void(extensions::api::gcd_private::Status));
}; };
class PrivetV3SessionTest : public testing::Test { class PrivetV3SessionTest : public testing::Test {
...@@ -37,12 +38,16 @@ class PrivetV3SessionTest : public testing::Test { ...@@ -37,12 +38,16 @@ class PrivetV3SessionTest : public testing::Test {
base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure_); base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure_);
} }
void ConfirmCode(const std::string& code,
extensions::api::gcd_private::ConfirmationType type) {
session_.ConfirmCode(code);
}
protected: protected:
virtual void SetUp() OVERRIDE { virtual void SetUp() OVERRIDE {
quit_closure_ = run_loop_.QuitClosure(); quit_closure_ = run_loop_.QuitClosure();
EXPECT_CALL(delegate_, OnSetupConfirmationNeeded(_)).Times(0); EXPECT_CALL(delegate_, OnSetupConfirmationNeeded(_, _)).Times(0);
EXPECT_CALL(delegate_, OnSessionEstablished()).Times(0); EXPECT_CALL(delegate_, OnSessionStatus(_)).Times(0);
EXPECT_CALL(delegate_, OnCannotEstablishSession()).Times(0);
} }
StrictMock<MockDelegate> delegate_; StrictMock<MockDelegate> delegate_;
...@@ -53,17 +58,19 @@ class PrivetV3SessionTest : public testing::Test { ...@@ -53,17 +58,19 @@ class PrivetV3SessionTest : public testing::Test {
}; };
TEST_F(PrivetV3SessionTest, NotConfirmed) { TEST_F(PrivetV3SessionTest, NotConfirmed) {
EXPECT_CALL(delegate_, OnSetupConfirmationNeeded(_)).Times(1).WillOnce( EXPECT_CALL(delegate_, OnSetupConfirmationNeeded(_, _)).Times(1).WillOnce(
InvokeWithoutArgs(this, &PrivetV3SessionTest::QuitLoop)); InvokeWithoutArgs(this, &PrivetV3SessionTest::QuitLoop));
session_.Start(); session_.Start();
run_loop_.Run(); run_loop_.Run();
} }
TEST_F(PrivetV3SessionTest, Confirmed) { TEST_F(PrivetV3SessionTest, Confirmed) {
EXPECT_CALL(delegate_, OnSessionEstablished()).Times(1).WillOnce( EXPECT_CALL(delegate_,
InvokeWithoutArgs(this, &PrivetV3SessionTest::QuitLoop)); OnSessionStatus(extensions::api::gcd_private::STATUS_SUCCESS))
EXPECT_CALL(delegate_, OnSetupConfirmationNeeded(_)).Times(1).WillOnce( .Times(1)
InvokeWithoutArgs(&session_, &PrivetV3Session::ConfirmCode)); .WillOnce(InvokeWithoutArgs(this, &PrivetV3SessionTest::QuitLoop));
EXPECT_CALL(delegate_, OnSetupConfirmationNeeded(_, _)).Times(1).WillOnce(
Invoke(this, &PrivetV3SessionTest::ConfirmCode));
session_.Start(); session_.Start();
run_loop_.Run(); run_loop_.Run();
} }
......
...@@ -109,19 +109,22 @@ void PrivetV3SetupFlow::SetupWifiAndRegister(const std::string& device_ssid) { ...@@ -109,19 +109,22 @@ void PrivetV3SetupFlow::SetupWifiAndRegister(const std::string& device_ssid) {
#endif // ENABLE_WIFI_BOOTSTRAPPING #endif // ENABLE_WIFI_BOOTSTRAPPING
void PrivetV3SetupFlow::OnSetupConfirmationNeeded( void PrivetV3SetupFlow::OnSetupConfirmationNeeded(
const std::string& confirmation_code) { const std::string& confirmation_code,
extensions::api::gcd_private::ConfirmationType confirmation_type) {
delegate_->ConfirmSecurityCode(confirmation_code, delegate_->ConfirmSecurityCode(confirmation_code,
base::Bind(&PrivetV3SetupFlow::OnCodeConfirmed, base::Bind(&PrivetV3SetupFlow::OnCodeConfirmed,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr(),
confirmation_code));
} }
void PrivetV3SetupFlow::OnSessionEstablished() { void PrivetV3SetupFlow::OnSessionStatus(
extensions::api::gcd_private::Status status) {
if (status == extensions::api::gcd_private::STATUS_SUCCESS) {
DCHECK(setup_request_); DCHECK(setup_request_);
session_->StartRequest(setup_request_.get()); session_->StartRequest(setup_request_.get());
} } else {
void PrivetV3SetupFlow::OnCannotEstablishSession() {
OnSetupError(); OnSetupError();
}
} }
void PrivetV3SetupFlow::OnSetupError() { void PrivetV3SetupFlow::OnSetupError() {
...@@ -159,10 +162,10 @@ void PrivetV3SetupFlow::OnPrivetClientCreated( ...@@ -159,10 +162,10 @@ void PrivetV3SetupFlow::OnPrivetClientCreated(
session_->Start(); session_->Start();
} }
void PrivetV3SetupFlow::OnCodeConfirmed(bool success) { void PrivetV3SetupFlow::OnCodeConfirmed(const std::string& code, bool success) {
if (!success) if (!success)
return OnSetupError(); return OnSetupError();
session_->ConfirmCode(); session_->ConfirmCode(code);
} }
} // namespace local_discovery } // namespace local_discovery
...@@ -73,9 +73,11 @@ class PrivetV3SetupFlow : public PrivetV3Session::Delegate { ...@@ -73,9 +73,11 @@ class PrivetV3SetupFlow : public PrivetV3Session::Delegate {
// PrivetV3Session::Delegate implementation. // PrivetV3Session::Delegate implementation.
virtual void OnSetupConfirmationNeeded( virtual void OnSetupConfirmationNeeded(
const std::string& confirmation_code) OVERRIDE; const std::string& confirmation_code,
virtual void OnSessionEstablished() OVERRIDE; extensions::api::gcd_private::ConfirmationType confirmation_type)
virtual void OnCannotEstablishSession() OVERRIDE; OVERRIDE;
virtual void OnSessionStatus(
extensions::api::gcd_private::Status status) OVERRIDE;
void OnSetupError(); void OnSetupError();
void OnDeviceRegistered(); void OnDeviceRegistered();
...@@ -86,7 +88,7 @@ class PrivetV3SetupFlow : public PrivetV3Session::Delegate { ...@@ -86,7 +88,7 @@ class PrivetV3SetupFlow : public PrivetV3Session::Delegate {
void OnTicketCreated(const std::string& ticket_id, void OnTicketCreated(const std::string& ticket_id,
const std::string& device_id); const std::string& device_id);
void OnPrivetClientCreated(scoped_ptr<PrivetHTTPClient> privet_http_client); void OnPrivetClientCreated(scoped_ptr<PrivetHTTPClient> privet_http_client);
void OnCodeConfirmed(bool success); void OnCodeConfirmed(const std::string& code, bool success);
Delegate* delegate_; Delegate* delegate_;
std::string service_name_; std::string service_name_;
......
...@@ -46,13 +46,25 @@ namespace gcdPrivate { ...@@ -46,13 +46,25 @@ namespace gcdPrivate {
// Unknown session. // Unknown session.
unknownSessionError, unknownSessionError,
// Bad confirmation code. Ask user to retype.
badConfirmationCodeError,
// Success. // Success.
success success
}; };
enum ConfirmationType { enum ConfirmationType {
displayCode, displayCode,
audio stickerCode
};
// Information regarding the confirmation of a device.
dictionary ConfirmationInfo {
// Type of confirmation.
ConfirmationType type;
// Code if available.
DOMString? code;
}; };
callback CloudDeviceListCallback = void(GCDDevice[] devices); callback CloudDeviceListCallback = void(GCDDevice[] devices);
...@@ -75,12 +87,10 @@ namespace gcdPrivate { ...@@ -75,12 +87,10 @@ namespace gcdPrivate {
// Called when the confirmation code is available or on error. // Called when the confirmation code is available or on error.
// |sessionId| is the session ID (identifies the session for future calls) // |sessionId| is the session ID (identifies the session for future calls)
// |status| is the status (success or type of error) // |status| is the status (success or type of error)
// |code| is the confirmation code or empty on error // |confirmation| is the information about the confirmation.
// |confirmationType| is the type of confirmation required
callback ConfirmationCodeCallback = void(long sessionId, callback ConfirmationCodeCallback = void(long sessionId,
Status status, Status status,
DOMString code, ConfirmationInfo confirmation);
ConfirmationType type);
// Called to indicated the session is established. // Called to indicated the session is established.
// |status| is the status (success or type of error) // |status| is the status (success or type of error)
...@@ -124,8 +134,11 @@ namespace gcdPrivate { ...@@ -124,8 +134,11 @@ namespace gcdPrivate {
long port, long port,
ConfirmationCodeCallback callback); ConfirmationCodeCallback callback);
// Confirm that the code is correct. Device will still need to confirm. // Send confirmation code. Device will still need to confirm. |code| must be
// present and must match the code from the device, even when the code is
// supplied in the |ConfirmationInfo| object.
static void confirmCode(long sessionId, static void confirmCode(long sessionId,
DOMString code,
SessionEstablishedCallback callback); SessionEstablishedCallback callback);
// Send an encrypted message to the device. |api| is the API path and // Send an encrypted message to the device. |api| is the API path and
......
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
onload = function() { onload = function() {
chrome.test.runTests([ chrome.test.runTests([
function session() { function session() {
function onConfirmCode(sessionId, status, code, method) { function onConfirmCode(sessionId, status, confirmationInfo) {
chrome.test.assertEq("success", status); chrome.test.assertEq("success", status);
chrome.test.assertEq("01234", code); chrome.test.assertEq("01234", confirmationInfo.code);
chrome.test.assertEq("displayCode", confirmationInfo.type);
chrome.gcdPrivate.confirmCode(sessionId, chrome.gcdPrivate.confirmCode(sessionId,
"01234",
onSessionEstablished.bind(null, onSessionEstablished.bind(null,
sessionId)); sessionId));
} }
......
...@@ -6,10 +6,11 @@ onload = function() { ...@@ -6,10 +6,11 @@ onload = function() {
chrome.test.runTests([ chrome.test.runTests([
function wifiMessage() { function wifiMessage() {
var messages_needed = 3; var messages_needed = 3;
function onConfirmCode(sessionId, status, code, method) { function onConfirmCode(sessionId, status, confirmation) {
chrome.test.assertEq("success", status); chrome.test.assertEq("success", status);
chrome.test.assertEq("01234", code); chrome.test.assertEq("01234", confirmation.code);
chrome.gcdPrivate.confirmCode(sessionId, chrome.gcdPrivate.confirmCode(sessionId,
confirmation.code,
onSessionEstablished.bind(null, onSessionEstablished.bind(null,
sessionId)); sessionId));
} }
......
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