summaryrefslogtreecommitdiffstats
path: root/components/proximity_auth
diff options
context:
space:
mode:
authortengs <tengs@chromium.org>2015-07-28 09:52:06 -0700
committerCommit bot <commit-bot@chromium.org>2015-07-28 16:52:48 +0000
commit757fd84c95ee5a34252150bc3ffe8ec415f285c2 (patch)
tree4b5d6d5593ae9b5bf29e8b38a6c5f16cd528a964 /components/proximity_auth
parentb3d575b166091d2a3e948520d3ca30de090ca7a7 (diff)
downloadchromium_src-757fd84c95ee5a34252150bc3ffe8ec415f285c2.zip
chromium_src-757fd84c95ee5a34252150bc3ffe8ec415f285c2.tar.gz
chromium_src-757fd84c95ee5a34252150bc3ffe8ec415f285c2.tar.bz2
Hook up CryptAuthGCMManager to the enrollment and device sync managers.
CryptAuth enrollment now performs a GCM registration if no previous registration has been completed. GCM push messages can now trigger enrollment and device sync attempts. BUG=512230 TEST=unit tests Review URL: https://codereview.chromium.org/1248533003 Cr-Commit-Position: refs/heads/master@{#340704}
Diffstat (limited to 'components/proximity_auth')
-rw-r--r--components/proximity_auth/cryptauth/BUILD.gn2
-rw-r--r--components/proximity_auth/cryptauth/cryptauth_device_manager.cc12
-rw-r--r--components/proximity_auth/cryptauth/cryptauth_device_manager.h16
-rw-r--r--components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc27
-rw-r--r--components/proximity_auth/cryptauth/cryptauth_enrollment_manager.cc35
-rw-r--r--components/proximity_auth/cryptauth/cryptauth_enrollment_manager.h19
-rw-r--r--components/proximity_auth/cryptauth/cryptauth_enrollment_manager_unittest.cc73
-rw-r--r--components/proximity_auth/cryptauth/cryptauth_gcm_manager_impl.h2
-rw-r--r--components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.cc50
-rw-r--r--components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.h64
-rw-r--r--components/proximity_auth/webui/proximity_auth_ui_delegate.h7
-rw-r--r--components/proximity_auth/webui/proximity_auth_webui_handler.cc13
-rw-r--r--components/proximity_auth/webui/proximity_auth_webui_handler.h3
13 files changed, 310 insertions, 13 deletions
diff --git a/components/proximity_auth/cryptauth/BUILD.gn b/components/proximity_auth/cryptauth/BUILD.gn
index b2e210f..a272435 100644
--- a/components/proximity_auth/cryptauth/BUILD.gn
+++ b/components/proximity_auth/cryptauth/BUILD.gn
@@ -55,6 +55,8 @@ source_set("test_support") {
testonly = true
sources = [
+ "fake_cryptauth_gcm_manager.cc",
+ "fake_cryptauth_gcm_manager.h",
"fake_secure_message_delegate.cc",
"fake_secure_message_delegate.h",
"mock_cryptauth_client.cc",
diff --git a/components/proximity_auth/cryptauth/cryptauth_device_manager.cc b/components/proximity_auth/cryptauth/cryptauth_device_manager.cc
index 396d191..3e641bb 100644
--- a/components/proximity_auth/cryptauth/cryptauth_device_manager.cc
+++ b/components/proximity_auth/cryptauth/cryptauth_device_manager.cc
@@ -88,14 +88,16 @@ bool DictionaryToUnlockKey(const base::DictionaryValue& dictionary,
CryptAuthDeviceManager::CryptAuthDeviceManager(
scoped_ptr<base::Clock> clock,
scoped_ptr<CryptAuthClientFactory> client_factory,
+ CryptAuthGCMManager* gcm_manager,
PrefService* pref_service)
: clock_(clock.Pass()),
client_factory_(client_factory.Pass()),
+ gcm_manager_(gcm_manager),
pref_service_(pref_service),
- weak_ptr_factory_(this) {
-}
+ weak_ptr_factory_(this) {}
CryptAuthDeviceManager::~CryptAuthDeviceManager() {
+ gcm_manager_->RemoveObserver(this);
}
// static
@@ -112,6 +114,8 @@ void CryptAuthDeviceManager::RegisterPrefs(PrefRegistrySimple* registry) {
void CryptAuthDeviceManager::Start() {
UpdateUnlockKeysFromPrefs();
+ gcm_manager_->AddObserver(this);
+
base::Time last_successful_sync = GetLastSyncTime();
base::TimeDelta elapsed_time_since_last_sync =
clock_->Now() - last_successful_sync;
@@ -216,6 +220,10 @@ scoped_ptr<SyncScheduler> CryptAuthDeviceManager::CreateSyncScheduler() {
kDeviceSyncMaxJitterRatio, "CryptAuth DeviceSync"));
}
+void CryptAuthDeviceManager::OnResyncMessage() {
+ ForceSyncNow(cryptauth::INVOCATION_REASON_SERVER_INITIATED);
+}
+
void CryptAuthDeviceManager::UpdateUnlockKeysFromPrefs() {
const base::ListValue* unlock_key_list =
pref_service_->GetList(prefs::kCryptAuthDeviceSyncUnlockKeys);
diff --git a/components/proximity_auth/cryptauth/cryptauth_device_manager.h b/components/proximity_auth/cryptauth/cryptauth_device_manager.h
index f1dfebe..ea16cd0 100644
--- a/components/proximity_auth/cryptauth/cryptauth_device_manager.h
+++ b/components/proximity_auth/cryptauth/cryptauth_device_manager.h
@@ -10,6 +10,7 @@
#include "base/observer_list.h"
#include "base/time/clock.h"
#include "base/time/time.h"
+#include "components/proximity_auth/cryptauth/cryptauth_gcm_manager.h"
#include "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h"
#include "components/proximity_auth/cryptauth/sync_scheduler.h"
@@ -27,7 +28,8 @@ class CryptAuthClientFactory;
// The manager periodically syncs the user's devices from CryptAuth to keep the
// list of unlock keys fresh. If a sync attempts fails, the manager will
// schedule the next sync more aggressively to recover.
-class CryptAuthDeviceManager : public SyncScheduler::Delegate {
+class CryptAuthDeviceManager : public SyncScheduler::Delegate,
+ public CryptAuthGCMManager::Observer {
public:
// Respresents the success result of a sync attempt.
enum class SyncResult { SUCCESS, FAILURE };
@@ -56,11 +58,14 @@ class CryptAuthDeviceManager : public SyncScheduler::Delegate {
// Creates the manager:
// |clock|: Used to determine the time between sync attempts.
// |client_factory|: Creates CryptAuthClient instances to perform each sync.
+ // |gcm_manager|: Notifies when GCM push messages trigger device syncs.
+ // Not owned and must outlive this instance.
// |pref_service|: Stores syncing metadata and unlock key information to
// persist across browser restarts. Must already be registered
// with RegisterPrefs().
CryptAuthDeviceManager(scoped_ptr<base::Clock> clock,
scoped_ptr<CryptAuthClientFactory> client_factory,
+ CryptAuthGCMManager* gcm_manager,
PrefService* pref_service);
~CryptAuthDeviceManager() override;
@@ -108,6 +113,9 @@ class CryptAuthDeviceManager : public SyncScheduler::Delegate {
virtual scoped_ptr<SyncScheduler> CreateSyncScheduler();
private:
+ // CryptAuthGCMManager::Observer:
+ void OnResyncMessage() override;
+
// Updates |unlock_keys_| by fetching the list stored in |pref_service_|.
void UpdateUnlockKeysFromPrefs();
@@ -125,7 +133,11 @@ class CryptAuthDeviceManager : public SyncScheduler::Delegate {
// Creates CryptAuthClient instances for each sync attempt.
scoped_ptr<CryptAuthClientFactory> client_factory_;
- // Contains perferences that outlive the lifetime of this object and across
+ // Notifies when GCM push messages trigger device sync. Not owned and must
+ // outlive this instance.
+ CryptAuthGCMManager* gcm_manager_;
+
+ // Contains preferences that outlive the lifetime of this object and across
// process restarts. |pref_service_| must outlive the lifetime of this
// instance.
PrefService* const pref_service_;
diff --git a/components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc b/components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc
index bd02b2f..091d190 100644
--- a/components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc
+++ b/components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc
@@ -10,6 +10,7 @@
#include "base/strings/stringprintf.h"
#include "base/test/simple_test_clock.h"
#include "components/proximity_auth/cryptauth/base64url.h"
+#include "components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.h"
#include "components/proximity_auth/cryptauth/mock_cryptauth_client.h"
#include "components/proximity_auth/cryptauth/mock_sync_scheduler.h"
#include "components/proximity_auth/cryptauth/pref_names.h"
@@ -104,9 +105,11 @@ class TestCryptAuthDeviceManager : public CryptAuthDeviceManager {
public:
TestCryptAuthDeviceManager(scoped_ptr<base::Clock> clock,
scoped_ptr<CryptAuthClientFactory> client_factory,
+ CryptAuthGCMManager* gcm_manager,
PrefService* pref_service)
: CryptAuthDeviceManager(clock.Pass(),
client_factory.Pass(),
+ gcm_manager,
pref_service),
scoped_sync_scheduler_(new NiceMock<MockSyncScheduler>()),
weak_sync_scheduler_factory_(scoped_sync_scheduler_.get()) {}
@@ -147,8 +150,10 @@ class ProximityAuthCryptAuthDeviceManagerTest
: clock_(new base::SimpleTestClock()),
client_factory_(new MockCryptAuthClientFactory(
MockCryptAuthClientFactory::MockType::MAKE_STRICT_MOCKS)),
+ gcm_manager_("existing gcm registration id"),
device_manager_(make_scoped_ptr(clock_),
make_scoped_ptr(client_factory_),
+ &gcm_manager_,
&pref_service_) {
client_factory_->AddObserver(this);
}
@@ -261,6 +266,8 @@ class ProximityAuthCryptAuthDeviceManagerTest
TestingPrefServiceSimple pref_service_;
+ FakeCryptAuthGCMManager gcm_manager_;
+
TestCryptAuthDeviceManager device_manager_;
cryptauth::GetMyDevicesResponse get_my_devices_response_;
@@ -323,7 +330,7 @@ TEST_F(ProximityAuthCryptAuthDeviceManagerTest, InitWithDefaultPrefs) {
clock.Pass(),
make_scoped_ptr(new MockCryptAuthClientFactory(
MockCryptAuthClientFactory::MockType::MAKE_STRICT_MOCKS)),
- &pref_service);
+ &gcm_manager_, &pref_service);
EXPECT_CALL(
*(device_manager.GetSyncScheduler()),
@@ -525,4 +532,22 @@ TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncTwoUnlockKeys) {
device_manager_.unlock_keys(), pref_service_);
}
+TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncOnGCMPushMessage) {
+ device_manager_.Start();
+
+ EXPECT_CALL(*sync_scheduler(), ForceSync());
+ gcm_manager_.PushResyncMessage();
+
+ FireSchedulerForSync(cryptauth::INVOCATION_REASON_SERVER_INITIATED);
+
+ EXPECT_CALL(*this, OnSyncFinishedProxy(
+ CryptAuthDeviceManager::SyncResult::SUCCESS,
+ CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
+ success_callback_.Run(get_my_devices_response_);
+
+ ExpectUnlockKeysAndPrefAreEqual(std::vector<cryptauth::ExternalDeviceInfo>(
+ 1, get_my_devices_response_.devices(0)),
+ device_manager_.unlock_keys(), pref_service_);
+}
+
} // namespace proximity_auth
diff --git a/components/proximity_auth/cryptauth/cryptauth_enrollment_manager.cc b/components/proximity_auth/cryptauth/cryptauth_enrollment_manager.cc
index 2b87229..6c08073 100644
--- a/components/proximity_auth/cryptauth/cryptauth_enrollment_manager.cc
+++ b/components/proximity_auth/cryptauth/cryptauth_enrollment_manager.cc
@@ -41,17 +41,19 @@ CryptAuthEnrollmentManager::CryptAuthEnrollmentManager(
const std::string& user_public_key,
const std::string& user_private_key,
const cryptauth::GcmDeviceInfo& device_info,
+ CryptAuthGCMManager* gcm_manager,
PrefService* pref_service)
: clock_(clock.Pass()),
enroller_factory_(enroller_factory.Pass()),
user_public_key_(user_public_key),
user_private_key_(user_private_key),
device_info_(device_info),
+ gcm_manager_(gcm_manager),
pref_service_(pref_service),
- weak_ptr_factory_(this) {
-}
+ weak_ptr_factory_(this) {}
CryptAuthEnrollmentManager::~CryptAuthEnrollmentManager() {
+ gcm_manager_->RemoveObserver(this);
}
// static
@@ -65,6 +67,8 @@ void CryptAuthEnrollmentManager::RegisterPrefs(PrefRegistrySimple* registry) {
}
void CryptAuthEnrollmentManager::Start() {
+ gcm_manager_->AddObserver(this);
+
bool is_recovering_from_failure =
pref_service_->GetBoolean(
prefs::kCryptAuthEnrollmentIsRecoveringFromFailure) ||
@@ -150,13 +154,37 @@ scoped_ptr<SyncScheduler> CryptAuthEnrollmentManager::CreateSyncScheduler() {
kEnrollmentMaxJitterRatio, "CryptAuth Enrollment"));
}
+void CryptAuthEnrollmentManager::OnGCMRegistrationResult(bool success) {
+ if (!sync_request_)
+ return;
+
+ PA_LOG(INFO) << "GCM registration for CryptAuth Enrollment completed: "
+ << success;
+ if (success)
+ DoCryptAuthEnrollment();
+ else
+ OnEnrollmentFinished(false);
+}
+
+void CryptAuthEnrollmentManager::OnReenrollMessage() {
+ ForceEnrollmentNow(cryptauth::INVOCATION_REASON_SERVER_INITIATED);
+}
+
void CryptAuthEnrollmentManager::OnSyncRequested(
scoped_ptr<SyncScheduler::SyncRequest> sync_request) {
FOR_EACH_OBSERVER(Observer, observers_, OnEnrollmentStarted());
sync_request_ = sync_request.Pass();
- cryptauth_enroller_ = enroller_factory_->CreateInstance();
+ if (gcm_manager_->GetRegistrationId().empty()) {
+ gcm_manager_->RegisterWithGCM();
+ } else {
+ DoCryptAuthEnrollment();
+ }
+}
+
+void CryptAuthEnrollmentManager::DoCryptAuthEnrollment() {
+ DCHECK(sync_request_);
cryptauth::InvocationReason invocation_reason =
cryptauth::INVOCATION_REASON_UNKNOWN;
@@ -180,6 +208,7 @@ void CryptAuthEnrollmentManager::OnSyncRequested(
}
PA_LOG(INFO) << "Making enrollment with reason: " << invocation_reason;
+ cryptauth_enroller_ = enroller_factory_->CreateInstance();
cryptauth_enroller_->Enroll(
user_public_key_, user_private_key_, device_info_, invocation_reason,
base::Bind(&CryptAuthEnrollmentManager::OnEnrollmentFinished,
diff --git a/components/proximity_auth/cryptauth/cryptauth_enrollment_manager.h b/components/proximity_auth/cryptauth/cryptauth_enrollment_manager.h
index f5558bc..4dd8d17 100644
--- a/components/proximity_auth/cryptauth/cryptauth_enrollment_manager.h
+++ b/components/proximity_auth/cryptauth/cryptauth_enrollment_manager.h
@@ -9,6 +9,7 @@
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
+#include "components/proximity_auth/cryptauth/cryptauth_gcm_manager.h"
#include "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h"
#include "components/proximity_auth/cryptauth/sync_scheduler.h"
@@ -29,7 +30,8 @@ class CryptAuthEnrollerFactory;
// re-enrolling to keep the state on the server fresh. If an enrollment fails,
// the manager will schedule the next enrollment more aggressively to recover
// from the failure.
-class CryptAuthEnrollmentManager : public SyncScheduler::Delegate {
+class CryptAuthEnrollmentManager : public SyncScheduler::Delegate,
+ public CryptAuthGCMManager::Observer {
public:
class Observer {
public:
@@ -51,6 +53,9 @@ class CryptAuthEnrollmentManager : public SyncScheduler::Delegate {
// |user_private_key|: The corresponding private key to |user_public_key|.
// |device_info|: Contains information about the local device that will be
// uploaded to CryptAuth with each enrollment request.
+ // |gcm_manager|: Used to perform GCM registrations and also notifies when GCM
+ // push messages trigger re-enrollments.
+ // Not owned and must outlive this instance.
// |pref_service|: Contains preferences across browser restarts, and should
// have been registered through RegisterPrefs().
CryptAuthEnrollmentManager(
@@ -59,6 +64,7 @@ class CryptAuthEnrollmentManager : public SyncScheduler::Delegate {
const std::string& user_public_key,
const std::string& user_private_key,
const cryptauth::GcmDeviceInfo& device_info,
+ CryptAuthGCMManager* gcm_manager,
PrefService* pref_service);
~CryptAuthEnrollmentManager() override;
@@ -105,10 +111,17 @@ class CryptAuthEnrollmentManager : public SyncScheduler::Delegate {
virtual scoped_ptr<SyncScheduler> CreateSyncScheduler();
private:
+ // CryptAuthGCMManager::Observer:
+ void OnGCMRegistrationResult(bool success) override;
+ void OnReenrollMessage() override;
+
// SyncScheduler::Delegate:
void OnSyncRequested(
scoped_ptr<SyncScheduler::SyncRequest> sync_request) override;
+ // Starts a CryptAuth enrollment attempt.
+ void DoCryptAuthEnrollment();
+
// Callback when |cryptauth_enroller_| completes.
void OnEnrollmentFinished(bool success);
@@ -125,6 +138,10 @@ class CryptAuthEnrollmentManager : public SyncScheduler::Delegate {
// The local device information to upload to CryptAuth.
const cryptauth::GcmDeviceInfo device_info_;
+ // Used to perform GCM registrations and also notifies when GCM push messages
+ // trigger re-enrollments. Not owned and must outlive this instance.
+ CryptAuthGCMManager* gcm_manager_;
+
// Contains perferences that outlive the lifetime of this object and across
// process restarts.
// Not owned and must outlive this instance.
diff --git a/components/proximity_auth/cryptauth/cryptauth_enrollment_manager_unittest.cc b/components/proximity_auth/cryptauth/cryptauth_enrollment_manager_unittest.cc
index b387ea6..f06a4df 100644
--- a/components/proximity_auth/cryptauth/cryptauth_enrollment_manager_unittest.cc
+++ b/components/proximity_auth/cryptauth/cryptauth_enrollment_manager_unittest.cc
@@ -10,6 +10,7 @@
#include "base/time/clock.h"
#include "base/time/time.h"
#include "components/proximity_auth/cryptauth/cryptauth_enroller.h"
+#include "components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.h"
#include "components/proximity_auth/cryptauth/mock_sync_scheduler.h"
#include "components/proximity_auth/cryptauth/pref_names.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -24,6 +25,9 @@ namespace proximity_auth {
namespace {
+// The GCM registration id from a successful registration.
+const char kGCMRegistrationId[] = "new gcm registration id";
+
// The user's persistent key pair identifying the local device.
const char kUserPublicKey[] = "user public key";
const char kUserPrivateKey[] = "user private key";
@@ -93,12 +97,14 @@ class TestCryptAuthEnrollmentManager : public CryptAuthEnrollmentManager {
scoped_ptr<base::Clock> clock,
scoped_ptr<CryptAuthEnrollerFactory> enroller_factory,
const cryptauth::GcmDeviceInfo& device_info,
+ CryptAuthGCMManager* gcm_manager,
PrefService* pref_service)
: CryptAuthEnrollmentManager(clock.Pass(),
enroller_factory.Pass(),
kUserPublicKey,
kUserPrivateKey,
device_info,
+ gcm_manager,
pref_service),
scoped_sync_scheduler_(new NiceMock<MockSyncScheduler>()),
weak_sync_scheduler_factory_(scoped_sync_scheduler_.get()) {}
@@ -137,9 +143,11 @@ class ProximityAuthCryptAuthEnrollmentManagerTest
ProximityAuthCryptAuthEnrollmentManagerTest()
: clock_(new base::SimpleTestClock()),
enroller_factory_(new MockCryptAuthEnrollerFactory()),
+ gcm_manager_(kGCMRegistrationId),
enrollment_manager_(make_scoped_ptr(clock_),
make_scoped_ptr(enroller_factory_),
device_info_,
+ &gcm_manager_,
&pref_service_) {}
// testing::Test:
@@ -218,6 +226,8 @@ class ProximityAuthCryptAuthEnrollmentManagerTest
TestingPrefServiceSimple pref_service_;
+ FakeCryptAuthGCMManager gcm_manager_;
+
TestCryptAuthEnrollmentManager enrollment_manager_;
DISALLOW_COPY_AND_ASSIGN(ProximityAuthCryptAuthEnrollmentManagerTest);
@@ -268,7 +278,7 @@ TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest, InitWithDefaultPrefs) {
TestCryptAuthEnrollmentManager enrollment_manager(
clock.Pass(), make_scoped_ptr(new MockCryptAuthEnrollerFactory()),
- device_info_, &pref_service);
+ device_info_, &gcm_manager_, &pref_service);
EXPECT_CALL(
*enrollment_manager.GetSyncScheduler(),
@@ -370,4 +380,65 @@ TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest,
prefs::kCryptAuthEnrollmentIsRecoveringFromFailure));
}
+TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest,
+ EnrollWithoutGCMRegistrationId) {
+ // Initialize |enrollment_manager_|.
+ ON_CALL(*sync_scheduler(), GetStrategy())
+ .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH));
+ gcm_manager_.set_registration_id(std::string());
+ enrollment_manager_.Start();
+
+ // Trigger a sync request.
+ EXPECT_CALL(*this, OnEnrollmentStartedProxy());
+ auto sync_request = make_scoped_ptr(
+ new SyncScheduler::SyncRequest(enrollment_manager_.GetSyncScheduler()));
+ static_cast<SyncScheduler::Delegate*>(&enrollment_manager_)
+ ->OnSyncRequested(sync_request.Pass());
+
+ // Complete GCM registration successfully.
+ CryptAuthEnroller::EnrollmentFinishedCallback enrollment_callback;
+ EXPECT_CALL(*next_cryptauth_enroller(),
+ Enroll(kUserPublicKey, kUserPrivateKey, _,
+ cryptauth::INVOCATION_REASON_PERIODIC, _))
+ .WillOnce(SaveArg<4>(&enrollment_callback));
+ ASSERT_TRUE(gcm_manager_.registration_in_progress());
+ gcm_manager_.CompleteRegistration(kGCMRegistrationId);
+
+ // Complete CryptAuth enrollment.
+ ASSERT_FALSE(enrollment_callback.is_null());
+ EXPECT_CALL(*this, OnEnrollmentFinishedProxy(true));
+ enrollment_callback.Run(true);
+}
+
+TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest, GCMRegistrationFails) {
+ // Initialize |enrollment_manager_|.
+ ON_CALL(*sync_scheduler(), GetStrategy())
+ .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH));
+ gcm_manager_.set_registration_id(std::string());
+ enrollment_manager_.Start();
+
+ // Trigger a sync request.
+ EXPECT_CALL(*this, OnEnrollmentStartedProxy());
+ auto sync_request = make_scoped_ptr(
+ new SyncScheduler::SyncRequest(enrollment_manager_.GetSyncScheduler()));
+ static_cast<SyncScheduler::Delegate*>(&enrollment_manager_)
+ ->OnSyncRequested(sync_request.Pass());
+
+ // Complete GCM registration with failure.
+ EXPECT_CALL(*this, OnEnrollmentFinishedProxy(false));
+ gcm_manager_.CompleteRegistration(std::string());
+}
+
+TEST_F(ProximityAuthCryptAuthEnrollmentManagerTest, ReenrollOnGCMPushMessage) {
+ enrollment_manager_.Start();
+
+ // Simulate receiving a GCM push message, forcing the device to re-enroll.
+ gcm_manager_.PushReenrollMessage();
+ auto completion_callback =
+ FireSchedulerForEnrollment(cryptauth::INVOCATION_REASON_SERVER_INITIATED);
+
+ EXPECT_CALL(*this, OnEnrollmentFinishedProxy(true));
+ completion_callback.Run(true);
+}
+
} // namespace proximity_auth
diff --git a/components/proximity_auth/cryptauth/cryptauth_gcm_manager_impl.h b/components/proximity_auth/cryptauth/cryptauth_gcm_manager_impl.h
index c58fa45..6bf93f0 100644
--- a/components/proximity_auth/cryptauth/cryptauth_gcm_manager_impl.h
+++ b/components/proximity_auth/cryptauth/cryptauth_gcm_manager_impl.h
@@ -31,7 +31,7 @@ class CryptAuthGCMManagerImpl : public CryptAuthGCMManager,
// |pref_service|: Contains preferences across browser restarts, and should
// have been registered through RegisterPrefs(). The service is not owned
// and must outlive this instance.
- CryptAuthGCMManagerImpl(gcm::GCMDriver* gcm_deriver,
+ CryptAuthGCMManagerImpl(gcm::GCMDriver* gcm_driver,
PrefService* pref_service);
~CryptAuthGCMManagerImpl() override;
diff --git a/components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.cc b/components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.cc
new file mode 100644
index 0000000..806e1be
--- /dev/null
+++ b/components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.cc
@@ -0,0 +1,50 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.h"
+
+namespace proximity_auth {
+
+FakeCryptAuthGCMManager::FakeCryptAuthGCMManager(
+ const std::string& registration_id)
+ : registration_in_progress_(false), registration_id_(registration_id) {}
+
+FakeCryptAuthGCMManager::~FakeCryptAuthGCMManager() {}
+
+void FakeCryptAuthGCMManager::StartListening() {}
+
+void FakeCryptAuthGCMManager::RegisterWithGCM() {
+ registration_in_progress_ = true;
+}
+
+std::string FakeCryptAuthGCMManager::GetRegistrationId() {
+ return registration_id_;
+}
+
+void FakeCryptAuthGCMManager::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void FakeCryptAuthGCMManager::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void FakeCryptAuthGCMManager::CompleteRegistration(
+ const std::string& registration_id) {
+ DCHECK(registration_in_progress_);
+ registration_in_progress_ = false;
+ registration_id_ = registration_id;
+ bool success = !registration_id_.empty();
+ FOR_EACH_OBSERVER(Observer, observers_, OnGCMRegistrationResult(success));
+}
+
+void FakeCryptAuthGCMManager::PushReenrollMessage() {
+ FOR_EACH_OBSERVER(Observer, observers_, OnReenrollMessage());
+}
+
+void FakeCryptAuthGCMManager::PushResyncMessage() {
+ FOR_EACH_OBSERVER(Observer, observers_, OnResyncMessage());
+}
+
+} // namespace proximity_auth
diff --git a/components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.h b/components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.h
new file mode 100644
index 0000000..b25eb83
--- /dev/null
+++ b/components/proximity_auth/cryptauth/fake_cryptauth_gcm_manager.h
@@ -0,0 +1,64 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PROXIMITY_AUTH_FAKE_CRYPTAUTH_FAKE_CRYPTAUTH_GCM_MANAGER_H
+#define COMPONENTS_PROXIMITY_AUTH_FAKE_CRYPTAUTH_FAKE_CRYPTAUTH_GCM_MANAGER_H
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "components/proximity_auth/cryptauth/cryptauth_gcm_manager.h"
+
+namespace proximity_auth {
+
+// CryptAuthGCMManager implementation for testing purposes.
+class FakeCryptAuthGCMManager : public CryptAuthGCMManager {
+ public:
+ // Creates the instance:
+ // |registration_id|: The GCM registration id from a previous successful
+ // enrollment. Pass in an empty |registration_id| to simulate never having
+ // registered successfully.
+ explicit FakeCryptAuthGCMManager(const std::string& registration_id);
+
+ ~FakeCryptAuthGCMManager() override;
+
+ // CryptAuthGCMManager:
+ void StartListening() override;
+ void RegisterWithGCM() override;
+ std::string GetRegistrationId() override;
+ void AddObserver(Observer* observer) override;
+ void RemoveObserver(Observer* observer) override;
+
+ // Simulates completing a GCM registration with the resulting
+ // |registration_id|. Passing an empty |registration_id| will simulate a
+ // registration failure.
+ // A registration attempt must currently be in progress.
+ void CompleteRegistration(const std::string& registration_id);
+
+ // Simulates receiving a re-enroll push message from GCM.
+ void PushReenrollMessage();
+
+ // Simulates receiving a re-sync push message from GCM.
+ void PushResyncMessage();
+
+ bool registration_in_progress() { return registration_in_progress_; }
+
+ void set_registration_id(const std::string& registration_id) {
+ registration_id_ = registration_id;
+ }
+
+ private:
+ // Whether a registration attempt is currently in progress.
+ bool registration_in_progress_;
+
+ // The registration id obtained from the last successful registration.
+ std::string registration_id_;
+
+ base::ObserverList<Observer> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeCryptAuthGCMManager);
+};
+
+} // namespace proximity_auth
+
+#endif // COMPONENTS_PROXIMITY_FAKE_CRYPTAUTH_FAKE_CRYPTAUTH_GCM_MANAGER_H
diff --git a/components/proximity_auth/webui/proximity_auth_ui_delegate.h b/components/proximity_auth/webui/proximity_auth_ui_delegate.h
index 6de61e7..bbb3787 100644
--- a/components/proximity_auth/webui/proximity_auth_ui_delegate.h
+++ b/components/proximity_auth/webui/proximity_auth_ui_delegate.h
@@ -10,6 +10,10 @@
class PrefService;
+namespace gcm {
+class GCMDriver;
+}
+
namespace proximity_auth {
class CryptAuthClientFactory;
@@ -33,6 +37,9 @@ class ProximityAuthUIDelegate {
// Constructs the DeviceClassifier message that is sent to CryptAuth for all
// API requests.
virtual cryptauth::DeviceClassifier GetDeviceClassifier() = 0;
+
+ // Returns the GCMDriver instance used by Chrome.
+ virtual gcm::GCMDriver* GetGCMDriver() = 0;
};
} // namespace proximity_auth
diff --git a/components/proximity_auth/webui/proximity_auth_webui_handler.cc b/components/proximity_auth/webui/proximity_auth_webui_handler.cc
index f660c8f..c71f04c 100644
--- a/components/proximity_auth/webui/proximity_auth_webui_handler.cc
+++ b/components/proximity_auth/webui/proximity_auth_webui_handler.cc
@@ -11,6 +11,7 @@
#include "base/values.h"
#include "components/proximity_auth/cryptauth/base64url.h"
#include "components/proximity_auth/cryptauth/cryptauth_enrollment_manager.h"
+#include "components/proximity_auth/cryptauth/cryptauth_gcm_manager_impl.h"
#include "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h"
#include "components/proximity_auth/logging/logging.h"
#include "components/proximity_auth/webui/cryptauth_enroller_factory_impl.h"
@@ -151,6 +152,8 @@ void ProximityAuthWebUIHandler::RegisterMessages() {
base::Unretained(this)));
LogBuffer::GetInstance()->AddObserver(this);
+
+ InitGCMManager();
InitEnrollmentManager();
InitDeviceManager();
}
@@ -240,6 +243,11 @@ void ProximityAuthWebUIHandler::ForceDeviceSync(const base::ListValue* args) {
device_manager_->ForceSyncNow(cryptauth::INVOCATION_REASON_MANUAL);
}
+void ProximityAuthWebUIHandler::InitGCMManager() {
+ gcm_manager_.reset(new CryptAuthGCMManagerImpl(delegate_->GetGCMDriver(),
+ delegate_->GetPrefService()));
+}
+
void ProximityAuthWebUIHandler::InitEnrollmentManager() {
#if defined(OS_CHROMEOS)
// TODO(tengs): We initialize a CryptAuthEnrollmentManager here for
@@ -294,7 +302,7 @@ void ProximityAuthWebUIHandler::InitEnrollmentManager() {
enrollment_manager_.reset(new CryptAuthEnrollmentManager(
make_scoped_ptr(new base::DefaultClock()),
make_scoped_ptr(new CryptAuthEnrollerFactoryImpl(delegate_)),
- user_public_key, user_private_key, device_info,
+ user_public_key, user_private_key, device_info, gcm_manager_.get(),
delegate_->GetPrefService()));
enrollment_manager_->AddObserver(this);
enrollment_manager_->Start();
@@ -306,7 +314,8 @@ void ProximityAuthWebUIHandler::InitDeviceManager() {
// development and testing purposes until it is ready to be moved into Chrome.
device_manager_.reset(new CryptAuthDeviceManager(
make_scoped_ptr(new base::DefaultClock()),
- delegate_->CreateCryptAuthClientFactory(), delegate_->GetPrefService()));
+ delegate_->CreateCryptAuthClientFactory(), gcm_manager_.get(),
+ delegate_->GetPrefService()));
device_manager_->AddObserver(this);
device_manager_->Start();
}
diff --git a/components/proximity_auth/webui/proximity_auth_webui_handler.h b/components/proximity_auth/webui/proximity_auth_webui_handler.h
index 860fecf..70e9894 100644
--- a/components/proximity_auth/webui/proximity_auth_webui_handler.h
+++ b/components/proximity_auth/webui/proximity_auth_webui_handler.h
@@ -10,6 +10,7 @@
#include "components/proximity_auth/cryptauth/cryptauth_client.h"
#include "components/proximity_auth/cryptauth/cryptauth_device_manager.h"
#include "components/proximity_auth/cryptauth/cryptauth_enrollment_manager.h"
+#include "components/proximity_auth/cryptauth/cryptauth_gcm_manager.h"
#include "components/proximity_auth/logging/log_buffer.h"
#include "components/proximity_auth/webui/proximity_auth_ui_delegate.h"
#include "content/public/browser/web_ui_message_handler.h"
@@ -57,6 +58,7 @@ class ProximityAuthWebUIHandler : public content::WebUIMessageHandler,
void ForceDeviceSync(const base::ListValue* args);
// Initializes CryptAuth managers, used for development purposes.
+ void InitGCMManager();
void InitEnrollmentManager();
void InitDeviceManager();
@@ -84,6 +86,7 @@ class ProximityAuthWebUIHandler : public content::WebUIMessageHandler,
// TODO(tengs): These members are temporarily used for development.
scoped_ptr<PrefService> pref_service;
+ scoped_ptr<CryptAuthGCMManager> gcm_manager_;
scoped_ptr<CryptAuthEnrollmentManager> enrollment_manager_;
scoped_ptr<CryptAuthDeviceManager> device_manager_;