diff options
Diffstat (limited to 'components')
6 files changed, 174 insertions, 67 deletions
diff --git a/components/proximity_auth/cryptauth/cryptauth_device_manager.cc b/components/proximity_auth/cryptauth/cryptauth_device_manager.cc index 709161e..396d191 100644 --- a/components/proximity_auth/cryptauth/cryptauth_device_manager.cc +++ b/components/proximity_auth/cryptauth/cryptauth_device_manager.cc @@ -7,6 +7,7 @@ #include "base/prefs/pref_registry_simple.h" #include "base/prefs/pref_service.h" #include "base/prefs/scoped_user_pref_update.h" +#include "components/proximity_auth/cryptauth/base64url.h" #include "components/proximity_auth/cryptauth/cryptauth_client.h" #include "components/proximity_auth/cryptauth/pref_names.h" #include "components/proximity_auth/cryptauth/sync_scheduler_impl.h" @@ -37,11 +38,18 @@ const char kExternalDeviceKeyBluetoothAddress[] = "bluetooth_address"; scoped_ptr<base::DictionaryValue> UnlockKeyToDictionary( const cryptauth::ExternalDeviceInfo& device) { scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue()); - dictionary->SetString(kExternalDeviceKeyPublicKey, device.public_key()); - dictionary->SetString(kExternalDeviceKeyDeviceName, - device.friendly_device_name()); + + // We store the device information in Base64Url form because dictionary values + // must be valid UTF8 strings. + std::string public_key_b64, device_name_b64, bluetooth_address_b64; + Base64UrlEncode(device.public_key(), &public_key_b64); + Base64UrlEncode(device.friendly_device_name(), &device_name_b64); + Base64UrlEncode(device.bluetooth_address(), &bluetooth_address_b64); + + dictionary->SetString(kExternalDeviceKeyPublicKey, public_key_b64); + dictionary->SetString(kExternalDeviceKeyDeviceName, device_name_b64); dictionary->SetString(kExternalDeviceKeyBluetoothAddress, - device.bluetooth_address()); + bluetooth_address_b64); return dictionary.Pass(); } @@ -50,11 +58,20 @@ scoped_ptr<base::DictionaryValue> UnlockKeyToDictionary( // parsed proto is written to |external_device|. bool DictionaryToUnlockKey(const base::DictionaryValue& dictionary, cryptauth::ExternalDeviceInfo* external_device) { - std::string public_key, device_name, bluetooth_address; - if (!dictionary.GetString(kExternalDeviceKeyPublicKey, &public_key) || - !dictionary.GetString(kExternalDeviceKeyDeviceName, &device_name) || + std::string public_key_b64, device_name_b64, bluetooth_address_b64; + if (!dictionary.GetString(kExternalDeviceKeyPublicKey, &public_key_b64) || + !dictionary.GetString(kExternalDeviceKeyDeviceName, &device_name_b64) || !dictionary.GetString(kExternalDeviceKeyBluetoothAddress, - &bluetooth_address)) { + &bluetooth_address_b64)) { + return false; + } + + // We store the device information in Base64Url form because dictionary values + // must be valid UTF8 strings. + std::string public_key, device_name, bluetooth_address; + if (!Base64UrlDecode(public_key_b64, &public_key) || + !Base64UrlDecode(device_name_b64, &device_name) || + !Base64UrlDecode(bluetooth_address_b64, &bluetooth_address)) { return false; } diff --git a/components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc b/components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc index 5574d83..bd02b2f 100644 --- a/components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc +++ b/components/proximity_auth/cryptauth/cryptauth_device_manager_unittest.cc @@ -9,6 +9,7 @@ #include "base/prefs/testing_pref_service.h" #include "base/strings/stringprintf.h" #include "base/test/simple_test_clock.h" +#include "components/proximity_auth/cryptauth/base64url.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" @@ -76,11 +77,18 @@ void ExpectUnlockKeysAndPrefAreEqual( static_cast<int>(i))); const base::DictionaryValue* unlock_key_dictionary; EXPECT_TRUE(unlock_keys_pref->GetDictionary(i, &unlock_key_dictionary)); + std::string public_key_b64, device_name_b64, bluetooth_address_b64; + ASSERT_TRUE( + unlock_key_dictionary->GetString("public_key", &public_key_b64)); + ASSERT_TRUE( + unlock_key_dictionary->GetString("device_name", &device_name_b64)); + ASSERT_TRUE(unlock_key_dictionary->GetString("bluetooth_address", + &bluetooth_address_b64)); + std::string public_key, device_name, bluetooth_address; - EXPECT_TRUE(unlock_key_dictionary->GetString("public_key", &public_key)); - EXPECT_TRUE(unlock_key_dictionary->GetString("device_name", &device_name)); - EXPECT_TRUE(unlock_key_dictionary->GetString("bluetooth_address", - &bluetooth_address)); + ASSERT_TRUE(Base64UrlDecode(public_key_b64, &public_key)); + ASSERT_TRUE(Base64UrlDecode(device_name_b64, &device_name)); + ASSERT_TRUE(Base64UrlDecode(bluetooth_address_b64, &bluetooth_address)); const auto& expected_unlock_key = expected_unlock_keys[i]; EXPECT_EQ(expected_unlock_key.public_key(), public_key); @@ -166,10 +174,16 @@ class ProximityAuthCryptAuthDeviceManagerTest scoped_ptr<base::DictionaryValue> unlock_key_dictionary( new base::DictionaryValue()); - unlock_key_dictionary->SetString("public_key", kStoredPublicKey); - unlock_key_dictionary->SetString("device_name", kStoredDeviceName); + + std::string public_key_b64, device_name_b64, bluetooth_address_b64; + Base64UrlEncode(kStoredPublicKey, &public_key_b64); + Base64UrlEncode(kStoredDeviceName, &device_name_b64); + Base64UrlEncode(kStoredBluetoothAddress, &bluetooth_address_b64); + + unlock_key_dictionary->SetString("public_key", public_key_b64); + unlock_key_dictionary->SetString("device_name", device_name_b64); unlock_key_dictionary->SetString("bluetooth_address", - kStoredBluetoothAddress); + bluetooth_address_b64); { ListPrefUpdate update(&pref_service_, prefs::kCryptAuthDeviceSyncUnlockKeys); @@ -428,9 +442,14 @@ TEST_F(ProximityAuthCryptAuthDeviceManagerTest, SyncSameDevice) { { scoped_ptr<base::DictionaryValue> unlock_key_dictionary( new base::DictionaryValue()); - unlock_key_dictionary->SetString("public_key", kPublicKey1); - unlock_key_dictionary->SetString("device_name", kDeviceName1); - unlock_key_dictionary->SetString("bluetooth_address", kBluetoothAddress1); + std::string public_key_b64, device_name_b64, bluetooth_address_b64; + Base64UrlEncode(kPublicKey1, &public_key_b64); + Base64UrlEncode(kDeviceName1, &device_name_b64); + Base64UrlEncode(kBluetoothAddress1, &bluetooth_address_b64); + unlock_key_dictionary->SetString("public_key", public_key_b64); + unlock_key_dictionary->SetString("device_name", device_name_b64); + unlock_key_dictionary->SetString("bluetooth_address", + bluetooth_address_b64); ListPrefUpdate update(&pref_service_, prefs::kCryptAuthDeviceSyncUnlockKeys); diff --git a/components/proximity_auth/webui/proximity_auth_webui_handler.cc b/components/proximity_auth/webui/proximity_auth_webui_handler.cc index 3e73c51..f660c8f 100644 --- a/components/proximity_auth/webui/proximity_auth_webui_handler.cc +++ b/components/proximity_auth/webui/proximity_auth_webui_handler.cc @@ -94,6 +94,22 @@ scoped_ptr<base::DictionaryValue> IneligibleDeviceToDictionary( return device_dictionary; } +// Creates a SyncState JSON object that can be passed to the WebUI. +scoped_ptr<base::DictionaryValue> CreateSyncStateDictionary( + double last_success_time, + double next_refresh_time, + bool is_recovering_from_failure, + bool is_enrollment_in_progress) { + scoped_ptr<base::DictionaryValue> sync_state(new base::DictionaryValue()); + sync_state->SetDouble(kSyncStateLastSuccessTime, last_success_time); + sync_state->SetDouble(kSyncStateNextRefreshTime, next_refresh_time); + sync_state->SetBoolean(kSyncStateRecoveringFromFailure, + is_recovering_from_failure); + sync_state->SetBoolean(kSyncStateOperationInProgress, + is_enrollment_in_progress); + return sync_state; +} + } // namespace ProximityAuthWebUIHandler::ProximityAuthWebUIHandler( @@ -123,16 +139,20 @@ void ProximityAuthWebUIHandler::RegisterMessages() { base::Unretained(this))); web_ui()->RegisterMessageCallback( - "getEnrollmentState", - base::Bind(&ProximityAuthWebUIHandler::GetEnrollmentState, - base::Unretained(this))); + "getSyncStates", base::Bind(&ProximityAuthWebUIHandler::GetSyncStates, + base::Unretained(this))); web_ui()->RegisterMessageCallback( "forceEnrollment", base::Bind(&ProximityAuthWebUIHandler::ForceEnrollment, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "forceDeviceSync", base::Bind(&ProximityAuthWebUIHandler::ForceDeviceSync, + base::Unretained(this))); + LogBuffer::GetInstance()->AddObserver(this); InitEnrollmentManager(); + InitDeviceManager(); } void ProximityAuthWebUIHandler::OnLogMessageAdded( @@ -162,6 +182,23 @@ void ProximityAuthWebUIHandler::OnEnrollmentFinished(bool success) { "SyncStateInterface.onEnrollmentStateChanged", *enrollment_state); } +void ProximityAuthWebUIHandler::OnSyncStarted() { + web_ui()->CallJavascriptFunction( + "SyncStateInterface.onDeviceSyncStateChanged", + *GetDeviceSyncStateDictionary()); +} + +void ProximityAuthWebUIHandler::OnSyncFinished( + CryptAuthDeviceManager::SyncResult sync_result, + CryptAuthDeviceManager::DeviceChangeResult device_change_result) { + scoped_ptr<base::DictionaryValue> device_sync_state = + GetDeviceSyncStateDictionary(); + PA_LOG(INFO) << "Device sync completed with result=" + << static_cast<int>(sync_result) << ":\n" << *device_sync_state; + web_ui()->CallJavascriptFunction( + "SyncStateInterface.onDeviceSyncStateChanged", *device_sync_state); +} + void ProximityAuthWebUIHandler::GetLogMessages(const base::ListValue* args) { base::ListValue json_logs; for (const auto& log : *LogBuffer::GetInstance()->logs()) { @@ -198,6 +235,11 @@ void ProximityAuthWebUIHandler::ForceEnrollment(const base::ListValue* args) { } } +void ProximityAuthWebUIHandler::ForceDeviceSync(const base::ListValue* args) { + if (device_manager_) + device_manager_->ForceSyncNow(cryptauth::INVOCATION_REASON_MANUAL); +} + void ProximityAuthWebUIHandler::InitEnrollmentManager() { #if defined(OS_CHROMEOS) // TODO(tengs): We initialize a CryptAuthEnrollmentManager here for @@ -259,6 +301,16 @@ void ProximityAuthWebUIHandler::InitEnrollmentManager() { #endif } +void ProximityAuthWebUIHandler::InitDeviceManager() { + // TODO(tengs): We initialize a CryptAuthDeviceManager here for + // 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())); + device_manager_->AddObserver(this); + device_manager_->Start(); +} + void ProximityAuthWebUIHandler::OnCryptAuthClientError( const std::string& error_message) { PA_LOG(WARNING) << "CryptAuth request failed: " << error_message; @@ -285,34 +337,39 @@ void ProximityAuthWebUIHandler::OnFoundEligibleUnlockDevices( eligible_devices, ineligible_devices); } -void ProximityAuthWebUIHandler::GetEnrollmentState( - const base::ListValue* args) { +void ProximityAuthWebUIHandler::GetSyncStates(const base::ListValue* args) { scoped_ptr<base::DictionaryValue> enrollment_state = GetEnrollmentStateDictionary(); - PA_LOG(INFO) << "Got Enrollment State: \n" << *enrollment_state; - web_ui()->CallJavascriptFunction("SyncStateInterface.onGotEnrollmentState", - *enrollment_state); + scoped_ptr<base::DictionaryValue> device_sync_state = + GetDeviceSyncStateDictionary(); + PA_LOG(INFO) << "Enrollment State: \n" << *enrollment_state + << "Device Sync State: \n" << *device_sync_state; + web_ui()->CallJavascriptFunction("SyncStateInterface.onGotSyncStates", + *enrollment_state, *device_sync_state); } scoped_ptr<base::DictionaryValue> ProximityAuthWebUIHandler::GetEnrollmentStateDictionary() { - scoped_ptr<base::DictionaryValue> enrollment_state( - new base::DictionaryValue()); - if (!enrollment_manager_) - return enrollment_state; - - enrollment_state->SetDouble( - kSyncStateLastSuccessTime, - enrollment_manager_->GetLastEnrollmentTime().ToJsTime()); - enrollment_state->SetDouble( - kSyncStateNextRefreshTime, - enrollment_manager_->GetTimeToNextAttempt().InMillisecondsF()); - enrollment_state->SetBoolean(kSyncStateRecoveringFromFailure, - enrollment_manager_->IsRecoveringFromFailure()); - enrollment_state->SetBoolean(kSyncStateOperationInProgress, - enrollment_manager_->IsEnrollmentInProgress()); - return enrollment_state; + return make_scoped_ptr(new base::DictionaryValue()); + + return CreateSyncStateDictionary( + enrollment_manager_->GetLastEnrollmentTime().ToJsTime(), + enrollment_manager_->GetTimeToNextAttempt().InMillisecondsF(), + enrollment_manager_->IsRecoveringFromFailure(), + enrollment_manager_->IsEnrollmentInProgress()); +} + +scoped_ptr<base::DictionaryValue> +ProximityAuthWebUIHandler::GetDeviceSyncStateDictionary() { + if (!device_manager_) + return make_scoped_ptr(new base::DictionaryValue()); + + return CreateSyncStateDictionary( + device_manager_->GetLastSyncTime().ToJsTime(), + device_manager_->GetTimeToNextAttempt().InMillisecondsF(), + device_manager_->IsRecoveringFromFailure(), + device_manager_->IsSyncInProgress()); } } // namespace proximity_auth diff --git a/components/proximity_auth/webui/proximity_auth_webui_handler.h b/components/proximity_auth/webui/proximity_auth_webui_handler.h index b5eb7ed..860fecf 100644 --- a/components/proximity_auth/webui/proximity_auth_webui_handler.h +++ b/components/proximity_auth/webui/proximity_auth_webui_handler.h @@ -8,6 +8,7 @@ #include "base/memory/weak_ptr.h" #include "base/values.h" #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/logging/log_buffer.h" #include "components/proximity_auth/webui/proximity_auth_ui_delegate.h" @@ -22,7 +23,8 @@ namespace proximity_auth { // Handles messages from the chrome://proximity-auth page. class ProximityAuthWebUIHandler : public content::WebUIMessageHandler, public LogBuffer::Observer, - public CryptAuthEnrollmentManager::Observer { + public CryptAuthEnrollmentManager::Observer, + public CryptAuthDeviceManager::Observer { public: // |delegate| is not owned and must outlive this instance. explicit ProximityAuthWebUIHandler(ProximityAuthUIDelegate* delegate); @@ -40,15 +42,23 @@ class ProximityAuthWebUIHandler : public content::WebUIMessageHandler, void OnEnrollmentStarted() override; void OnEnrollmentFinished(bool success) override; + // CryptAuthDeviceManager::Observer: + void OnSyncStarted() override; + void OnSyncFinished( + CryptAuthDeviceManager::SyncResult sync_result, + CryptAuthDeviceManager::DeviceChangeResult device_change_result) override; + // Message handler callbacks. void GetLogMessages(const base::ListValue* args); void ClearLogBuffer(const base::ListValue* args); void FindEligibleUnlockDevices(const base::ListValue* args); - void GetEnrollmentState(const base::ListValue* args); + void GetSyncStates(const base::ListValue* args); void ForceEnrollment(const base::ListValue* args); + void ForceDeviceSync(const base::ListValue* args); - // Initializes the CryptAuthEnrollmentManager, used for development purposes. + // Initializes CryptAuth managers, used for development purposes. void InitEnrollmentManager(); + void InitDeviceManager(); // Called when a CryptAuth request fails. void OnCryptAuthClientError(const std::string& error_message); @@ -60,6 +70,9 @@ class ProximityAuthWebUIHandler : public content::WebUIMessageHandler, // Returns the current enrollment state that can be used as a JSON object. scoped_ptr<base::DictionaryValue> GetEnrollmentStateDictionary(); + // Returns the current device sync state that can be used as a JSON object. + scoped_ptr<base::DictionaryValue> GetDeviceSyncStateDictionary(); + // The delegate used to fetch dependencies. Must outlive this instance. ProximityAuthUIDelegate* delegate_; @@ -72,6 +85,7 @@ class ProximityAuthWebUIHandler : public content::WebUIMessageHandler, // TODO(tengs): These members are temporarily used for development. scoped_ptr<PrefService> pref_service; scoped_ptr<CryptAuthEnrollmentManager> enrollment_manager_; + scoped_ptr<CryptAuthDeviceManager> device_manager_; base::WeakPtrFactory<ProximityAuthWebUIHandler> weak_ptr_factory_; diff --git a/components/proximity_auth/webui/resources/local-state.html b/components/proximity_auth/webui/resources/local-state.html index a61489a..bd96b72 100644 --- a/components/proximity_auth/webui/resources/local-state.html +++ b/components/proximity_auth/webui/resources/local-state.html @@ -112,7 +112,9 @@ error-icon$="[[deviceSyncState_.recoveringFromFailure]]"> </iron-icon> </div> - <paper-button class="self-start">Force Sync</paper-button> + <paper-button class="self-start" on-click="forceDeviceSync_"> + Force Sync + </paper-button> </paper-material> </div> diff --git a/components/proximity_auth/webui/resources/local-state.js b/components/proximity_auth/webui/resources/local-state.js index 70ecb48..d606820 100644 --- a/components/proximity_auth/webui/resources/local-state.js +++ b/components/proximity_auth/webui/resources/local-state.js @@ -68,7 +68,7 @@ Polymer({ */ activate: function() { SyncStateInterface = this; - chrome.send('getEnrollmentState'); + chrome.send('getSyncStates'); }, /** @@ -79,6 +79,13 @@ Polymer({ }, /** + * Immediately forces an device sync attempt. + */ + forceDeviceSync_: function() { + chrome.send('forceDeviceSync'); + }, + + /** * Called when the enrollment state changes. * @param {SyncState} enrollmentState */ @@ -90,23 +97,21 @@ Polymer({ * Called when the device sync state changes. * @param {SyncState} deviceSyncState */ - onDeviceSyncStateChanged: function(deviceSyncState) {}, + onDeviceSyncStateChanged: function(deviceSyncState) { + this.deviceSyncState_ = deviceSyncState; + }, /** - * Called for the chrome.send('getEnrollmentState') response. + * Called for the chrome.send('getSyncStates') response. * @param {SyncState} enrollmentState + * @param {SyncState} deviceSyncState */ - onGotEnrollmentState: function(enrollmentState) { + onGotSyncStates: function(enrollmentState, deviceSyncState) { this.enrollmentState_ = enrollmentState; + this.deviceSyncState_ = deviceSyncState; }, /** - * Called for the chrome.send('getDeviceSyncState') response. - * @param {SyncState} enrollmentState - */ - onGotDeviceSyncState: function(deviceSyncState) {}, - - /** * @param {SyncState} syncState The enrollment or device sync state. * @param {string} neverSyncedString String returned if there has never been a * last successful sync. @@ -183,16 +188,9 @@ SyncStateInterface = { onDeviceSyncStateChanged: function(deviceSyncState) {}, /** - * Called in response to chrome.send('getEnrollmentState') with the current - * enrollment status of the user and device. - * @type {function(SyncState)} - */ - onGotEnrollmentState: function(enrollmentState) {}, - - /** - * Called in response to chrome.send('getDeviceState') with the current - * enrollment status of the user and device. - * @type {function(DeviceSyncState)} + * Called in response to chrome.send('getSyncStates') with the current + * enrollment and device sync states of the user and device. + * @type {function(SyncState, SyncState)} */ - onGotDeviceSyncState: function(deviceSyncState) {}, + onGotSyncStates: function(enrollmentState, deviceSyncState) {}, }; |