blob: 248ecd48c20c1a83e318e41ccd08d7623e9916bb [file] [log] [blame]
// Copyright 2013 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 "chrome/browser/signin/mutable_profile_oauth2_token_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/webdata/token_web_data.h"
#include "components/webdata/common/web_data_service_base.h"
#include "google_apis/gaia/gaia_constants.h"
#if defined(ENABLE_MANAGED_USERS)
#include "chrome/browser/managed_mode/managed_user_constants.h"
#endif
namespace {
const char kAccountIdPrefix[] = "AccountId-";
const size_t kAccountIdPrefixLength = 10;
bool IsLegacyRefreshTokenId(const std::string& service_id) {
return service_id == GaiaConstants::kGaiaOAuth2LoginRefreshToken;
}
bool IsLegacyServiceId(const std::string& account_id) {
return account_id.compare(0u, kAccountIdPrefixLength, kAccountIdPrefix) != 0;
}
std::string RemoveAccountIdPrefix(const std::string& prefixed_account_id) {
return prefixed_account_id.substr(kAccountIdPrefixLength);
}
} // namespace
MutableProfileOAuth2TokenService::MutableProfileOAuth2TokenService()
: web_data_service_request_(0) {
}
MutableProfileOAuth2TokenService::~MutableProfileOAuth2TokenService() {
}
void MutableProfileOAuth2TokenService::Shutdown() {
if (web_data_service_request_ != 0) {
scoped_refptr<TokenWebData> token_web_data =
TokenWebData::FromBrowserContext(profile());
DCHECK(token_web_data.get());
token_web_data->CancelRequest(web_data_service_request_);
web_data_service_request_ = 0;
}
ProfileOAuth2TokenService::Shutdown();
}
void MutableProfileOAuth2TokenService::LoadCredentials() {
DCHECK_EQ(0, web_data_service_request_);
CancelAllRequests();
refresh_tokens().clear();
scoped_refptr<TokenWebData> token_web_data =
TokenWebData::FromBrowserContext(profile());
if (token_web_data.get())
web_data_service_request_ = token_web_data->GetAllTokens(this);
}
void MutableProfileOAuth2TokenService::OnWebDataServiceRequestDone(
WebDataServiceBase::Handle handle,
const WDTypedResult* result) {
DCHECK_EQ(web_data_service_request_, handle);
web_data_service_request_ = 0;
if (result) {
DCHECK(result->GetType() == TOKEN_RESULT);
const WDResult<std::map<std::string, std::string> > * token_result =
static_cast<const WDResult<std::map<std::string, std::string> > * > (
result);
LoadAllCredentialsIntoMemory(token_result->GetValue());
}
std::string account_id = GetPrimaryAccountId();
// If |account_id| is not empty, make sure that we have an entry in the
// map for it. The entry could be missing if there is a corruption in
// the token DB while this profile is connected to an account.
if (!account_id.empty() && refresh_tokens().count(account_id) == 0) {
refresh_tokens()[account_id].reset(
new AccountInfo(this, account_id, std::string()));
}
// If we don't have a refresh token for the primary account, signal a signin
// error.
if (!account_id.empty() && !RefreshTokenIsAvailable(account_id)) {
UpdateAuthError(
account_id,
GoogleServiceAuthError(
GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
}
}
void MutableProfileOAuth2TokenService::LoadAllCredentialsIntoMemory(
const std::map<std::string, std::string>& db_tokens) {
std::string old_login_token;
for (std::map<std::string, std::string>::const_iterator iter =
db_tokens.begin();
iter != db_tokens.end();
++iter) {
std::string prefixed_account_id = iter->first;
std::string refresh_token = iter->second;
if (IsLegacyRefreshTokenId(prefixed_account_id) && !refresh_token.empty())
old_login_token = refresh_token;
if (IsLegacyServiceId(prefixed_account_id)) {
scoped_refptr<TokenWebData> token_web_data =
TokenWebData::FromBrowserContext(profile());
if (token_web_data.get())
token_web_data->RemoveTokenForService(prefixed_account_id);
} else {
DCHECK(!refresh_token.empty());
std::string account_id = RemoveAccountIdPrefix(prefixed_account_id);
refresh_tokens()[account_id].reset(
new AccountInfo(this, account_id, refresh_token));
FireRefreshTokenAvailable(account_id);
// TODO(fgorski): Notify diagnostic observers.
}
}
if (!old_login_token.empty()) {
std::string account_id = GetAccountIdForMigratingRefreshToken();
if (refresh_tokens().count(account_id) == 0)
UpdateCredentials(account_id, old_login_token);
}
FireRefreshTokensLoaded();
}
std::string
MutableProfileOAuth2TokenService::GetAccountIdForMigratingRefreshToken() {
#if defined(ENABLE_MANAGED_USERS)
// TODO(bauerb): Make sure that only services that can deal with supervised
// users see the supervised user token.
if (profile()->IsManaged())
return managed_users::kManagedUserPseudoEmail;
#endif
return GetPrimaryAccountId();
}