Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/signin/easy_unlock_service_signin_chromeos.h" | 5 #include "chrome/browser/signin/easy_unlock_service_signin_chromeos.h" |
| 6 | 6 |
| 7 #include "base/base64url.h" | 7 #include "base/base64url.h" |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 | 38 |
| 39 // Calculates the backoff interval that should be used next. | 39 // Calculates the backoff interval that should be used next. |
| 40 // |backoff| The last backoff interval used. | 40 // |backoff| The last backoff interval used. |
| 41 uint32 GetNextBackoffInterval(uint32 backoff) { | 41 uint32 GetNextBackoffInterval(uint32 backoff) { |
| 42 if (backoff == 0u) | 42 if (backoff == 0u) |
| 43 return kInitialCryptohomeBackoffIntervalMs; | 43 return kInitialCryptohomeBackoffIntervalMs; |
| 44 return backoff * 2; | 44 return backoff * 2; |
| 45 } | 45 } |
| 46 | 46 |
| 47 void LoadDataForUser( | 47 void LoadDataForUser( |
| 48 const std::string& user_id, | 48 const AccountId& account_id, |
| 49 uint32 backoff_ms, | 49 uint32 backoff_ms, |
| 50 const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback); | 50 const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback); |
| 51 | 51 |
| 52 // Callback passed to |LoadDataForUser()|. | 52 // Callback passed to |LoadDataForUser()|. |
| 53 // If |LoadDataForUser| function succeeded, it invokes |callback| with the | 53 // If |LoadDataForUser| function succeeded, it invokes |callback| with the |
| 54 // results. | 54 // results. |
| 55 // If |LoadDataForUser| failed and further retries are allowed, schedules new | 55 // If |LoadDataForUser| failed and further retries are allowed, schedules new |
| 56 // |LoadDataForUser| call with some backoff. If no further retires are allowed, | 56 // |LoadDataForUser| call with some backoff. If no further retires are allowed, |
| 57 // it invokes |callback| with the |LoadDataForUser| results. | 57 // it invokes |callback| with the |LoadDataForUser| results. |
| 58 void RetryDataLoadOnError( | 58 void RetryDataLoadOnError( |
| 59 const std::string& user_id, | 59 const AccountId& account_id, |
| 60 uint32 backoff_ms, | 60 uint32 backoff_ms, |
| 61 const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback, | 61 const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback, |
| 62 bool success, | 62 bool success, |
| 63 const chromeos::EasyUnlockDeviceKeyDataList& data_list) { | 63 const chromeos::EasyUnlockDeviceKeyDataList& data_list) { |
| 64 if (success) { | 64 if (success) { |
| 65 callback.Run(success, data_list); | 65 callback.Run(success, data_list); |
| 66 return; | 66 return; |
| 67 } | 67 } |
| 68 | 68 |
| 69 uint32 next_backoff_ms = GetNextBackoffInterval(backoff_ms); | 69 uint32 next_backoff_ms = GetNextBackoffInterval(backoff_ms); |
| 70 if (next_backoff_ms > kMaxCryptohomeBackoffIntervalMs) { | 70 if (next_backoff_ms > kMaxCryptohomeBackoffIntervalMs) { |
| 71 callback.Run(false, data_list); | 71 callback.Run(false, data_list); |
| 72 return; | 72 return; |
| 73 } | 73 } |
| 74 | 74 |
| 75 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 75 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 76 FROM_HERE, | 76 FROM_HERE, |
| 77 base::Bind(&LoadDataForUser, user_id, next_backoff_ms, callback), | 77 base::Bind(&LoadDataForUser, account_id, next_backoff_ms, callback), |
| 78 base::TimeDelta::FromMilliseconds(next_backoff_ms)); | 78 base::TimeDelta::FromMilliseconds(next_backoff_ms)); |
| 79 } | 79 } |
| 80 | 80 |
| 81 // Loads device data list associated with the user's Easy unlock keys. | 81 // Loads device data list associated with the user's Easy unlock keys. |
| 82 void LoadDataForUser( | 82 void LoadDataForUser( |
| 83 const std::string& user_id, | 83 const AccountId& account_id, |
| 84 uint32 backoff_ms, | 84 uint32 backoff_ms, |
| 85 const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback) { | 85 const chromeos::EasyUnlockKeyManager::GetDeviceDataListCallback& callback) { |
| 86 chromeos::EasyUnlockKeyManager* key_manager = | 86 chromeos::EasyUnlockKeyManager* key_manager = |
| 87 chromeos::UserSessionManager::GetInstance()->GetEasyUnlockKeyManager(); | 87 chromeos::UserSessionManager::GetInstance()->GetEasyUnlockKeyManager(); |
| 88 DCHECK(key_manager); | 88 DCHECK(key_manager); |
| 89 | 89 |
| 90 key_manager->GetDeviceDataList( | 90 key_manager->GetDeviceDataList( |
| 91 chromeos::UserContext(AccountId::FromUserEmail(user_id)), | 91 chromeos::UserContext(account_id), |
| 92 base::Bind(&RetryDataLoadOnError, user_id, backoff_ms, callback)); | 92 base::Bind(&RetryDataLoadOnError, account_id, backoff_ms, callback)); |
| 93 } | 93 } |
| 94 | 94 |
| 95 } // namespace | 95 } // namespace |
| 96 | 96 |
| 97 EasyUnlockServiceSignin::UserData::UserData() | 97 EasyUnlockServiceSignin::UserData::UserData() |
| 98 : state(EasyUnlockServiceSignin::USER_DATA_STATE_INITIAL) { | 98 : state(EasyUnlockServiceSignin::USER_DATA_STATE_INITIAL) { |
| 99 } | 99 } |
| 100 | 100 |
| 101 EasyUnlockServiceSignin::UserData::~UserData() {} | 101 EasyUnlockServiceSignin::UserData::~UserData() {} |
| 102 | 102 |
| 103 EasyUnlockServiceSignin::EasyUnlockServiceSignin(Profile* profile) | 103 EasyUnlockServiceSignin::EasyUnlockServiceSignin(Profile* profile) |
| 104 : EasyUnlockService(profile), | 104 : EasyUnlockService(profile), |
| 105 allow_cryptohome_backoff_(true), | 105 account_id_(EmptyAccountId()), |
| 106 service_active_(false), | |
| 107 user_pod_last_focused_timestamp_(base::TimeTicks::Now()), | 106 user_pod_last_focused_timestamp_(base::TimeTicks::Now()), |
| 108 weak_ptr_factory_(this) { | 107 weak_ptr_factory_(this) {} |
| 109 } | |
| 110 | 108 |
| 111 EasyUnlockServiceSignin::~EasyUnlockServiceSignin() { | 109 EasyUnlockServiceSignin::~EasyUnlockServiceSignin() { |
| 112 } | 110 } |
| 113 | 111 |
| 114 void EasyUnlockServiceSignin::SetCurrentUser(const std::string& user_id) { | 112 void EasyUnlockServiceSignin::SetCurrentUser(const AccountId& account_id) { |
| 115 OnFocusedUserChanged(user_id); | 113 OnFocusedUserChanged(account_id); |
| 116 } | 114 } |
| 117 | 115 |
| 118 void EasyUnlockServiceSignin::WrapChallengeForUserAndDevice( | 116 void EasyUnlockServiceSignin::WrapChallengeForUserAndDevice( |
| 119 const std::string& user_id, | 117 const AccountId& account_id, |
| 120 const std::string& device_public_key, | 118 const std::string& device_public_key, |
| 121 const std::string& channel_binding_data, | 119 const std::string& channel_binding_data, |
| 122 base::Callback<void(const std::string& wraped_challenge)> callback) { | 120 base::Callback<void(const std::string& wraped_challenge)> callback) { |
| 123 std::map<std::string, UserData*>::const_iterator it = | 121 auto it = user_data_.find(account_id); |
| 124 user_data_.find(user_id); | |
| 125 if (it == user_data_.end() || it->second->state != USER_DATA_STATE_LOADED) { | 122 if (it == user_data_.end() || it->second->state != USER_DATA_STATE_LOADED) { |
| 126 PA_LOG(ERROR) << "TPM data not loaded for " << user_id; | 123 PA_LOG(ERROR) << "TPM data not loaded for " << account_id.Serialize(); |
| 127 callback.Run(std::string()); | 124 callback.Run(std::string()); |
| 128 return; | 125 return; |
| 129 } | 126 } |
| 130 | 127 |
| 131 std::string device_public_key_base64; | 128 std::string device_public_key_base64; |
| 132 base::Base64UrlEncode(device_public_key, | 129 base::Base64UrlEncode(device_public_key, |
| 133 base::Base64UrlEncodePolicy::INCLUDE_PADDING, | 130 base::Base64UrlEncodePolicy::INCLUDE_PADDING, |
| 134 &device_public_key_base64); | 131 &device_public_key_base64); |
| 135 for (const auto& device_data : it->second->devices) { | 132 for (const auto& device_data : it->second->devices) { |
| 136 if (device_data.public_key == device_public_key_base64) { | 133 if (device_data.public_key == device_public_key_base64) { |
| 137 PA_LOG(INFO) << "Wrapping challenge for " << user_id << "..."; | 134 PA_LOG(INFO) << "Wrapping challenge for " << account_id.Serialize() |
| 135 << "..."; | |
| 138 challenge_wrapper_.reset(new chromeos::EasyUnlockChallengeWrapper( | 136 challenge_wrapper_.reset(new chromeos::EasyUnlockChallengeWrapper( |
| 139 device_data.challenge, channel_binding_data, user_id, | 137 device_data.challenge, channel_binding_data, account_id, |
| 140 EasyUnlockTpmKeyManagerFactory::GetInstance()->Get(profile()))); | 138 EasyUnlockTpmKeyManagerFactory::GetInstance()->Get(profile()))); |
| 141 challenge_wrapper_->WrapChallenge(callback); | 139 challenge_wrapper_->WrapChallenge(callback); |
| 142 return; | 140 return; |
| 143 } | 141 } |
| 144 } | 142 } |
| 145 | 143 |
| 146 PA_LOG(ERROR) << "Unable to find device record for " << user_id; | 144 PA_LOG(ERROR) << "Unable to find device record for " |
| 145 << account_id.Serialize(); | |
| 147 callback.Run(std::string()); | 146 callback.Run(std::string()); |
| 148 } | 147 } |
| 149 | 148 |
| 150 EasyUnlockService::Type EasyUnlockServiceSignin::GetType() const { | 149 EasyUnlockService::Type EasyUnlockServiceSignin::GetType() const { |
| 151 return EasyUnlockService::TYPE_SIGNIN; | 150 return EasyUnlockService::TYPE_SIGNIN; |
| 152 } | 151 } |
| 153 | 152 |
| 154 std::string EasyUnlockServiceSignin::GetUserEmail() const { | 153 AccountId EasyUnlockServiceSignin::GetAccountId() const { |
| 155 return user_id_; | 154 return account_id_; |
| 156 } | 155 } |
| 157 | 156 |
| 158 void EasyUnlockServiceSignin::LaunchSetup() { | 157 void EasyUnlockServiceSignin::LaunchSetup() { |
| 159 NOTREACHED(); | 158 NOTREACHED(); |
| 160 } | 159 } |
| 161 | 160 |
| 162 const base::DictionaryValue* EasyUnlockServiceSignin::GetPermitAccess() const { | 161 const base::DictionaryValue* EasyUnlockServiceSignin::GetPermitAccess() const { |
| 163 return NULL; | 162 return nullptr; |
| 164 } | 163 } |
| 165 | 164 |
| 166 void EasyUnlockServiceSignin::SetPermitAccess( | 165 void EasyUnlockServiceSignin::SetPermitAccess( |
| 167 const base::DictionaryValue& permit) { | 166 const base::DictionaryValue& permit) { |
| 168 NOTREACHED(); | 167 NOTREACHED(); |
| 169 } | 168 } |
| 170 | 169 |
| 171 void EasyUnlockServiceSignin::ClearPermitAccess() { | 170 void EasyUnlockServiceSignin::ClearPermitAccess() { |
| 172 NOTREACHED(); | 171 NOTREACHED(); |
| 173 } | 172 } |
| 174 | 173 |
| 175 const base::ListValue* EasyUnlockServiceSignin::GetRemoteDevices() const { | 174 const base::ListValue* EasyUnlockServiceSignin::GetRemoteDevices() const { |
| 176 const UserData* data = FindLoadedDataForCurrentUser(); | 175 const UserData* data = FindLoadedDataForCurrentUser(); |
| 177 if (!data) | 176 if (!data) |
| 178 return NULL; | 177 return nullptr; |
| 179 return &data->remote_devices_value; | 178 return &data->remote_devices_value; |
| 180 } | 179 } |
| 181 | 180 |
| 182 void EasyUnlockServiceSignin::SetRemoteDevices( | 181 void EasyUnlockServiceSignin::SetRemoteDevices( |
| 183 const base::ListValue& devices) { | 182 const base::ListValue& devices) { |
| 184 NOTREACHED(); | 183 NOTREACHED(); |
| 185 } | 184 } |
| 186 | 185 |
| 187 void EasyUnlockServiceSignin::SetRemoteBleDevices( | 186 void EasyUnlockServiceSignin::SetRemoteBleDevices( |
| 188 const base::ListValue& devices) { | 187 const base::ListValue& devices) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 214 std::string EasyUnlockServiceSignin::GetWrappedSecret() const { | 213 std::string EasyUnlockServiceSignin::GetWrappedSecret() const { |
| 215 const UserData* data = FindLoadedDataForCurrentUser(); | 214 const UserData* data = FindLoadedDataForCurrentUser(); |
| 216 // TODO(xiyuan): Use correct remote device instead of hard coded first one. | 215 // TODO(xiyuan): Use correct remote device instead of hard coded first one. |
| 217 uint32 device_index = 0; | 216 uint32 device_index = 0; |
| 218 if (!data || data->devices.size() <= device_index) | 217 if (!data || data->devices.size() <= device_index) |
| 219 return std::string(); | 218 return std::string(); |
| 220 return data->devices[device_index].wrapped_secret; | 219 return data->devices[device_index].wrapped_secret; |
| 221 } | 220 } |
| 222 | 221 |
| 223 void EasyUnlockServiceSignin::RecordEasySignInOutcome( | 222 void EasyUnlockServiceSignin::RecordEasySignInOutcome( |
| 224 const std::string& user_id, | 223 const AccountId& account_id, |
| 225 bool success) const { | 224 bool success) const { |
| 226 DCHECK_EQ(GetUserEmail(), user_id); | 225 DCHECK(GetAccountId() == account_id) |
| 226 << "GetAccountId()=" << GetAccountId().Serialize() | |
| 227 << " != account_id=" << account_id.Serialize(); | |
| 227 | 228 |
| 228 RecordEasyUnlockSigninEvent( | 229 RecordEasyUnlockSigninEvent( |
| 229 success ? EASY_UNLOCK_SUCCESS : EASY_UNLOCK_FAILURE); | 230 success ? EASY_UNLOCK_SUCCESS : EASY_UNLOCK_FAILURE); |
| 230 if (success) { | 231 if (success) { |
| 231 RecordEasyUnlockSigninDuration( | 232 RecordEasyUnlockSigninDuration( |
| 232 base::TimeTicks::Now() - user_pod_last_focused_timestamp_); | 233 base::TimeTicks::Now() - user_pod_last_focused_timestamp_); |
| 233 } | 234 } |
| 234 DVLOG(1) << "Easy sign-in " << (success ? "success" : "failure"); | 235 DVLOG(1) << "Easy sign-in " << (success ? "success" : "failure"); |
| 235 } | 236 } |
| 236 | 237 |
| 237 void EasyUnlockServiceSignin::RecordPasswordLoginEvent( | 238 void EasyUnlockServiceSignin::RecordPasswordLoginEvent( |
| 238 const std::string& user_id) const { | 239 const AccountId& account_id) const { |
| 239 // This happens during tests, where a user could log in without the user pod | 240 // This happens during tests, where a user could log in without the user pod |
| 240 // being focused. | 241 // being focused. |
| 241 if (GetUserEmail() != user_id) | 242 if (GetAccountId() != account_id) |
| 242 return; | 243 return; |
| 243 | 244 |
| 244 if (!IsEnabled()) | 245 if (!IsEnabled()) |
| 245 return; | 246 return; |
| 246 | 247 |
| 247 EasyUnlockAuthEvent event = GetPasswordAuthEvent(); | 248 EasyUnlockAuthEvent event = GetPasswordAuthEvent(); |
| 248 RecordEasyUnlockSigninEvent(event); | 249 RecordEasyUnlockSigninEvent(event); |
| 249 DVLOG(1) << "Easy Sign-in password login event, event=" << event; | 250 DVLOG(1) << "Easy Sign-in password login event, event=" << event; |
| 250 } | 251 } |
| 251 | 252 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 263 void EasyUnlockServiceSignin::InitializeInternal() { | 264 void EasyUnlockServiceSignin::InitializeInternal() { |
| 264 if (chromeos::LoginState::Get()->IsUserLoggedIn()) | 265 if (chromeos::LoginState::Get()->IsUserLoggedIn()) |
| 265 return; | 266 return; |
| 266 | 267 |
| 267 service_active_ = true; | 268 service_active_ = true; |
| 268 | 269 |
| 269 chromeos::LoginState::Get()->AddObserver(this); | 270 chromeos::LoginState::Get()->AddObserver(this); |
| 270 proximity_auth::ScreenlockBridge* screenlock_bridge = | 271 proximity_auth::ScreenlockBridge* screenlock_bridge = |
| 271 proximity_auth::ScreenlockBridge::Get(); | 272 proximity_auth::ScreenlockBridge::Get(); |
| 272 screenlock_bridge->AddObserver(this); | 273 screenlock_bridge->AddObserver(this); |
| 273 if (!screenlock_bridge->focused_user_id().empty()) | 274 if (screenlock_bridge->focused_account_id().is_valid()) |
| 274 OnFocusedUserChanged(screenlock_bridge->focused_user_id()); | 275 OnFocusedUserChanged(screenlock_bridge->focused_account_id()); |
| 275 } | 276 } |
| 276 | 277 |
| 277 void EasyUnlockServiceSignin::ShutdownInternal() { | 278 void EasyUnlockServiceSignin::ShutdownInternal() { |
| 278 if (!service_active_) | 279 if (!service_active_) |
| 279 return; | 280 return; |
| 280 service_active_ = false; | 281 service_active_ = false; |
| 281 | 282 |
| 282 weak_ptr_factory_.InvalidateWeakPtrs(); | 283 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 283 proximity_auth::ScreenlockBridge::Get()->RemoveObserver(this); | 284 proximity_auth::ScreenlockBridge::Get()->RemoveObserver(this); |
| 284 chromeos::LoginState::Get()->RemoveObserver(this); | 285 chromeos::LoginState::Get()->RemoveObserver(this); |
| 285 STLDeleteContainerPairSecondPointers(user_data_.begin(), user_data_.end()); | 286 STLDeleteContainerPairSecondPointers(user_data_.begin(), user_data_.end()); |
| 286 user_data_.clear(); | 287 user_data_.clear(); |
| 287 } | 288 } |
| 288 | 289 |
| 289 bool EasyUnlockServiceSignin::IsAllowedInternal() const { | 290 bool EasyUnlockServiceSignin::IsAllowedInternal() const { |
| 290 return service_active_ && | 291 return service_active_ && account_id_.is_valid() && |
| 291 !user_id_.empty() && | |
| 292 !chromeos::LoginState::Get()->IsUserLoggedIn(); | 292 !chromeos::LoginState::Get()->IsUserLoggedIn(); |
| 293 } | 293 } |
| 294 | 294 |
| 295 void EasyUnlockServiceSignin::OnWillFinalizeUnlock(bool success) { | 295 void EasyUnlockServiceSignin::OnWillFinalizeUnlock(bool success) { |
| 296 // This code path should only be exercised for the lock screen, not for the | 296 // This code path should only be exercised for the lock screen, not for the |
| 297 // sign-in screen. | 297 // sign-in screen. |
| 298 NOTREACHED(); | 298 NOTREACHED(); |
| 299 } | 299 } |
| 300 | 300 |
| 301 void EasyUnlockServiceSignin::OnSuspendDoneInternal() { | 301 void EasyUnlockServiceSignin::OnSuspendDoneInternal() { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 321 // in tests, the screen type might be different. | 321 // in tests, the screen type might be different. |
| 322 if (screen_type != | 322 if (screen_type != |
| 323 proximity_auth::ScreenlockBridge::LockHandler::SIGNIN_SCREEN) | 323 proximity_auth::ScreenlockBridge::LockHandler::SIGNIN_SCREEN) |
| 324 return; | 324 return; |
| 325 | 325 |
| 326 DisableAppWithoutResettingScreenlockState(); | 326 DisableAppWithoutResettingScreenlockState(); |
| 327 | 327 |
| 328 Shutdown(); | 328 Shutdown(); |
| 329 } | 329 } |
| 330 | 330 |
| 331 void EasyUnlockServiceSignin::OnFocusedUserChanged(const std::string& user_id) { | 331 void EasyUnlockServiceSignin::OnFocusedUserChanged( |
| 332 if (user_id_ == user_id) | 332 const AccountId& account_id) { |
| 333 if (account_id_ == account_id) | |
| 333 return; | 334 return; |
| 334 | 335 |
| 335 // Setting or clearing the user_id may changed |IsAllowed| value, so in these | 336 // Setting or clearing the account_id may changed |IsAllowed| value, so in |
| 337 // these | |
| 336 // cases update the app state. Otherwise, it's enough to notify the app the | 338 // cases update the app state. Otherwise, it's enough to notify the app the |
| 337 // user data has been updated. | 339 // user data has been updated. |
| 338 bool should_update_app_state = user_id_.empty() != user_id.empty(); | 340 const bool should_update_app_state = |
| 339 user_id_ = user_id; | 341 account_id_.is_valid() != account_id.is_valid(); |
| 342 account_id_ = account_id; | |
| 340 user_pod_last_focused_timestamp_ = base::TimeTicks::Now(); | 343 user_pod_last_focused_timestamp_ = base::TimeTicks::Now(); |
| 341 | 344 |
| 342 ResetScreenlockState(); | 345 ResetScreenlockState(); |
| 343 ShowInitialUserState(); | 346 ShowInitialUserState(); |
| 344 | 347 |
| 345 if (should_update_app_state) { | 348 if (should_update_app_state) { |
| 346 UpdateAppState(); | 349 UpdateAppState(); |
| 347 } else { | 350 } else { |
| 348 NotifyUserUpdated(); | 351 NotifyUserUpdated(); |
| 349 } | 352 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 364 if (!chromeos::LoginState::Get()->IsUserLoggedIn()) | 367 if (!chromeos::LoginState::Get()->IsUserLoggedIn()) |
| 365 return; | 368 return; |
| 366 DisableAppWithoutResettingScreenlockState(); | 369 DisableAppWithoutResettingScreenlockState(); |
| 367 } | 370 } |
| 368 | 371 |
| 369 void EasyUnlockServiceSignin::LoadCurrentUserDataIfNeeded() { | 372 void EasyUnlockServiceSignin::LoadCurrentUserDataIfNeeded() { |
| 370 // TODO(xiyuan): Revisit this when adding tests. | 373 // TODO(xiyuan): Revisit this when adding tests. |
| 371 if (!base::SysInfo::IsRunningOnChromeOS()) | 374 if (!base::SysInfo::IsRunningOnChromeOS()) |
| 372 return; | 375 return; |
| 373 | 376 |
| 374 if (user_id_.empty() || !service_active_) | 377 if (account_id_.is_valid() || !service_active_) |
| 375 return; | 378 return; |
| 376 | 379 |
| 377 std::map<std::string, UserData*>::iterator it = user_data_.find(user_id_); | 380 const auto it = user_data_.find(account_id_); |
| 378 if (it == user_data_.end()) | 381 if (it == user_data_.end()) |
| 379 user_data_.insert(std::make_pair(user_id_, new UserData())); | 382 user_data_.insert(std::make_pair(account_id_, new UserData())); |
| 380 | 383 |
| 381 UserData* data = user_data_[user_id_]; | 384 UserData* data = user_data_[account_id_]; |
| 382 | 385 |
| 383 if (data->state != USER_DATA_STATE_INITIAL) | 386 if (data->state != USER_DATA_STATE_INITIAL) |
| 384 return; | 387 return; |
| 385 data->state = USER_DATA_STATE_LOADING; | 388 data->state = USER_DATA_STATE_LOADING; |
| 386 | 389 |
| 387 LoadDataForUser( | 390 LoadDataForUser( |
| 388 user_id_, | 391 account_id_, |
| 389 allow_cryptohome_backoff_ ? 0u : kMaxCryptohomeBackoffIntervalMs, | 392 allow_cryptohome_backoff_ ? 0u : kMaxCryptohomeBackoffIntervalMs, |
| 390 base::Bind(&EasyUnlockServiceSignin::OnUserDataLoaded, | 393 base::Bind(&EasyUnlockServiceSignin::OnUserDataLoaded, |
| 391 weak_ptr_factory_.GetWeakPtr(), | 394 weak_ptr_factory_.GetWeakPtr(), account_id_)); |
| 392 user_id_)); | |
| 393 } | 395 } |
| 394 | 396 |
| 395 void EasyUnlockServiceSignin::OnUserDataLoaded( | 397 void EasyUnlockServiceSignin::OnUserDataLoaded( |
| 396 const std::string& user_id, | 398 const AccountId& account_id, |
| 397 bool success, | 399 bool success, |
| 398 const chromeos::EasyUnlockDeviceKeyDataList& devices) { | 400 const chromeos::EasyUnlockDeviceKeyDataList& devices) { |
| 399 allow_cryptohome_backoff_ = false; | 401 allow_cryptohome_backoff_ = false; |
| 400 | 402 |
| 401 UserData* data = user_data_[user_id]; | 403 UserData* data = user_data_[account_id]; |
| 402 data->state = USER_DATA_STATE_LOADED; | 404 data->state = USER_DATA_STATE_LOADED; |
| 403 if (success) { | 405 if (success) { |
| 404 data->devices = devices; | 406 data->devices = devices; |
| 405 chromeos::EasyUnlockKeyManager::DeviceDataListToRemoteDeviceList( | 407 chromeos::EasyUnlockKeyManager::DeviceDataListToRemoteDeviceList( |
| 406 user_id, devices, &data->remote_devices_value); | 408 account_id, devices, &data->remote_devices_value); |
| 407 | 409 |
| 408 // User could have a NO_HARDLOCK state but has no remote devices if | 410 // User could have a NO_HARDLOCK state but has no remote devices if |
| 409 // previous user session shuts down before | 411 // previous user session shuts down before |
| 410 // CheckCryptohomeKeysAndMaybeHardlock finishes. Set NO_PAIRING state | 412 // CheckCryptohomeKeysAndMaybeHardlock finishes. Set NO_PAIRING state |
| 411 // and update UI to remove the confusing spinner in this case. | 413 // and update UI to remove the confusing spinner in this case. |
| 412 EasyUnlockScreenlockStateHandler::HardlockState hardlock_state; | 414 EasyUnlockScreenlockStateHandler::HardlockState hardlock_state; |
| 413 if (devices.empty() && | 415 if (devices.empty() && |
| 414 GetPersistedHardlockState(&hardlock_state) && | 416 GetPersistedHardlockState(&hardlock_state) && |
| 415 hardlock_state == EasyUnlockScreenlockStateHandler::NO_HARDLOCK) { | 417 hardlock_state == EasyUnlockScreenlockStateHandler::NO_HARDLOCK) { |
| 416 SetHardlockStateForUser(user_id, | 418 SetHardlockStateForUser(account_id, |
| 417 EasyUnlockScreenlockStateHandler::NO_PAIRING); | 419 EasyUnlockScreenlockStateHandler::NO_PAIRING); |
| 418 } | 420 } |
| 419 } | 421 } |
| 420 | 422 |
| 421 // If the fetched data belongs to the currently focused user, notify the app | 423 // If the fetched data belongs to the currently focused user, notify the app |
| 422 // that it has to refresh it's user data. | 424 // that it has to refresh it's user data. |
| 423 if (user_id == user_id_) | 425 if (account_id == account_id_) |
| 424 NotifyUserUpdated(); | 426 NotifyUserUpdated(); |
| 425 | 427 |
| 426 if (user_id != user_id || devices.empty()) | 428 if (account_id != account_id || devices.empty()) |
|
Alexander Alekseev
2015/12/08 19:51:27
Roger, doesn't this line looks like a bug? Should
Alexander Alekseev
2015/12/09 02:49:15
Tim, what do you think?
Tim Song
2015/12/09 03:16:42
Yes this is definitely a bug. |user_id| should def
Tim Song
2015/12/09 03:52:48
Actually, I think the proper fix is just to remove
Alexander Alekseev
2015/12/09 04:49:23
Done.
| |
| 427 return; | 429 return; |
| 428 | 430 |
| 429 // TODO(tengs): Currently, ProximityAuthSystem only supports one device. Once | 431 // TODO(tengs): Currently, ProximityAuthSystem only supports one device. Once |
| 430 // multiple devices are supported, we need to load all devices. | 432 // multiple devices are supported, we need to load all devices. |
| 431 std::string decoded_public_key, decoded_psk, decoded_challenge; | 433 std::string decoded_public_key, decoded_psk, decoded_challenge; |
| 432 if (!base::Base64UrlDecode(devices[0].public_key, | 434 if (!base::Base64UrlDecode(devices[0].public_key, |
| 433 base::Base64UrlDecodePolicy::REQUIRE_PADDING, | 435 base::Base64UrlDecodePolicy::REQUIRE_PADDING, |
| 434 &decoded_public_key) || | 436 &decoded_public_key) || |
| 435 !base::Base64UrlDecode(devices[0].psk, | 437 !base::Base64UrlDecode(devices[0].psk, |
| 436 base::Base64UrlDecodePolicy::REQUIRE_PADDING, | 438 base::Base64UrlDecodePolicy::REQUIRE_PADDING, |
| 437 &decoded_psk) || | 439 &decoded_psk) || |
| 438 !base::Base64UrlDecode(devices[0].challenge, | 440 !base::Base64UrlDecode(devices[0].challenge, |
| 439 base::Base64UrlDecodePolicy::REQUIRE_PADDING, | 441 base::Base64UrlDecodePolicy::REQUIRE_PADDING, |
| 440 &decoded_challenge)) { | 442 &decoded_challenge)) { |
| 441 PA_LOG(ERROR) << "Unable to base64url decode the input data."; | 443 PA_LOG(ERROR) << "Unable to base64url decode the input data."; |
| 442 return; | 444 return; |
| 443 } | 445 } |
| 444 | 446 |
| 445 proximity_auth::RemoteDevice::BluetoothType bluetooth_type = | 447 proximity_auth::RemoteDevice::BluetoothType bluetooth_type = |
| 446 devices[0].bluetooth_type == | 448 devices[0].bluetooth_type == |
| 447 chromeos::EasyUnlockDeviceKeyData::BLUETOOTH_LE | 449 chromeos::EasyUnlockDeviceKeyData::BLUETOOTH_LE |
| 448 ? proximity_auth::RemoteDevice::BLUETOOTH_LE | 450 ? proximity_auth::RemoteDevice::BLUETOOTH_LE |
| 449 : proximity_auth::RemoteDevice::BLUETOOTH_CLASSIC; | 451 : proximity_auth::RemoteDevice::BLUETOOTH_CLASSIC; |
| 450 | 452 |
| 451 proximity_auth::RemoteDevice remote_device( | 453 proximity_auth::RemoteDevice remote_device( |
| 452 user_id, std::string(), decoded_public_key, bluetooth_type, | 454 account_id.GetUserEmail(), std::string(), decoded_public_key, |
| 453 devices[0].bluetooth_address, decoded_psk, decoded_challenge); | 455 bluetooth_type, devices[0].bluetooth_address, decoded_psk, |
| 456 decoded_challenge); | |
| 454 PA_LOG(INFO) << "Loaded Remote Device:\n" | 457 PA_LOG(INFO) << "Loaded Remote Device:\n" |
| 455 << " user id: " << remote_device.user_id << "\n" | 458 << " user id: " << remote_device.user_id << "\n" |
| 456 << " name: " << remote_device.name << "\n" | 459 << " name: " << remote_device.name << "\n" |
| 457 << " public key" << devices[0].public_key << "\n" | 460 << " public key" << devices[0].public_key << "\n" |
| 458 << " bt_addr:" << remote_device.bluetooth_address; | 461 << " bt_addr:" << remote_device.bluetooth_address; |
| 459 OnRemoteDeviceChanged(&remote_device); | 462 OnRemoteDeviceChanged(&remote_device); |
| 460 } | 463 } |
| 461 | 464 |
| 462 const EasyUnlockServiceSignin::UserData* | 465 const EasyUnlockServiceSignin::UserData* |
| 463 EasyUnlockServiceSignin::FindLoadedDataForCurrentUser() const { | 466 EasyUnlockServiceSignin::FindLoadedDataForCurrentUser() const { |
| 464 if (user_id_.empty()) | 467 if (account_id_.is_valid()) |
| 465 return NULL; | 468 return nullptr; |
| 466 | 469 |
| 467 std::map<std::string, UserData*>::const_iterator it = | 470 const auto it = user_data_.find(account_id_); |
| 468 user_data_.find(user_id_); | |
| 469 if (it == user_data_.end()) | 471 if (it == user_data_.end()) |
| 470 return NULL; | 472 return nullptr; |
| 471 if (it->second->state != USER_DATA_STATE_LOADED) | 473 if (it->second->state != USER_DATA_STATE_LOADED) |
| 472 return NULL; | 474 return nullptr; |
| 473 return it->second; | 475 return it->second; |
| 474 } | 476 } |
| OLD | NEW |