123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/mutable_profile_oauth2_token_service.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/signin_client.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/signin/core/browser/signin_metrics.h"
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/webdata/token_web_data.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/webdata/common/web_data_service_base.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_fetcher.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/gaia/gaia_constants.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "google_apis/gaia/oauth2_access_token_fetcher_impl.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kAccountIdPrefix[] = "AccountId-";
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const size_t kAccountIdPrefixLength = 10;
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string ApplyAccountIdPrefix(const std::string& account_id) {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return kAccountIdPrefix + account_id;
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool IsLegacyRefreshTokenId(const std::string& service_id) {
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return service_id == GaiaConstants::kGaiaOAuth2LoginRefreshToken;
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool IsLegacyServiceId(const std::string& account_id) {
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return account_id.compare(0u, kAccountIdPrefixLength, kAccountIdPrefix) != 0;
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::string RemoveAccountIdPrefix(const std::string& prefixed_account_id) {
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return prefixed_account_id.substr(kAccountIdPrefixLength);
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This class sends a request to GAIA to revoke the given refresh token from
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the server.  This is a best effort attempt only.  This class deletes itself
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// when done sucessfully or otherwise.
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class MutableProfileOAuth2TokenService::RevokeServerRefreshToken
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : public GaiaAuthConsumer {
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RevokeServerRefreshToken(MutableProfileOAuth2TokenService* token_service,
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           const std::string& account_id);
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~RevokeServerRefreshToken();
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // GaiaAuthConsumer overrides:
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnOAuth2RevokeTokenCompleted() OVERRIDE;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MutableProfileOAuth2TokenService* token_service_;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GaiaAuthFetcher fetcher_;
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RevokeServerRefreshToken);
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MutableProfileOAuth2TokenService::
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RevokeServerRefreshToken::RevokeServerRefreshToken(
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MutableProfileOAuth2TokenService* token_service,
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& refresh_token)
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : token_service_(token_service),
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fetcher_(this, GaiaConstants::kChromeSource,
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               token_service_->GetRequestContext()) {
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  fetcher_.StartRevokeOAuth2Token(refresh_token);
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MutableProfileOAuth2TokenService::
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RevokeServerRefreshToken::~RevokeServerRefreshToken() {}
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MutableProfileOAuth2TokenService::
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RevokeServerRefreshToken::OnOAuth2RevokeTokenCompleted() {
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |this| pointer will be deleted when removed from the vector, so don't
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // access any members after call to erase().
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  token_service_->server_revokes_.erase(
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::find(token_service_->server_revokes_.begin(),
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                token_service_->server_revokes_.end(),
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                this));
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MutableProfileOAuth2TokenService::AccountInfo::AccountInfo(
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProfileOAuth2TokenService* token_service,
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& account_id,
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& refresh_token)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  : token_service_(token_service),
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    account_id_(account_id),
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    refresh_token_(refresh_token),
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    last_auth_error_(GoogleServiceAuthError::NONE) {
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(token_service_);
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!account_id_.empty());
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  token_service_->signin_error_controller()->AddProvider(this);
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MutableProfileOAuth2TokenService::AccountInfo::~AccountInfo() {
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  token_service_->signin_error_controller()->RemoveProvider(this);
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MutableProfileOAuth2TokenService::AccountInfo::SetLastAuthError(
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GoogleServiceAuthError& error) {
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error.state() != last_auth_error_.state()) {
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    last_auth_error_ = error;
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    token_service_->signin_error_controller()->AuthStatusChanged();
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MutableProfileOAuth2TokenService::AccountInfo::GetAccountId() const {
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return account_id_;
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)MutableProfileOAuth2TokenService::AccountInfo::GetUsername() const {
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(rogerta): when |account_id| becomes the obfuscated gaia id, this
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // will need to be changed.
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return account_id_;
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GoogleServiceAuthError
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MutableProfileOAuth2TokenService::AccountInfo::GetAuthStatus() const {
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return last_auth_error_;
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)MutableProfileOAuth2TokenService::MutableProfileOAuth2TokenService()
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : web_data_service_request_(0)  {
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)MutableProfileOAuth2TokenService::~MutableProfileOAuth2TokenService() {
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(server_revokes_.empty());
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MutableProfileOAuth2TokenService::Shutdown() {
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  server_revokes_.clear();
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CancelWebTokenFetch();
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CancelAllRequests();
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  refresh_tokens_.clear();
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ProfileOAuth2TokenService::Shutdown();
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool MutableProfileOAuth2TokenService::RefreshTokenIsAvailable(
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& account_id) const {
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return !GetRefreshToken(account_id).empty();
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string MutableProfileOAuth2TokenService::GetRefreshToken(
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& account_id) const {
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AccountInfoMap::const_iterator iter = refresh_tokens_.find(account_id);
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (iter != refresh_tokens_.end())
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return iter->second->refresh_token();
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return std::string();
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)OAuth2AccessTokenFetcher*
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MutableProfileOAuth2TokenService::CreateAccessTokenFetcher(
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& account_id,
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    net::URLRequestContextGetter* getter,
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    OAuth2AccessTokenConsumer* consumer) {
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string refresh_token = GetRefreshToken(account_id);
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!refresh_token.empty());
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return new OAuth2AccessTokenFetcherImpl(consumer, getter, refresh_token);
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)net::URLRequestContextGetter*
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MutableProfileOAuth2TokenService::GetRequestContext() {
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return client()->GetURLRequestContext();
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MutableProfileOAuth2TokenService::LoadCredentials(
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& primary_account_id) {
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!primary_account_id.empty());
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(loading_primary_account_id_.empty());
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_EQ(0, web_data_service_request_);
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CancelAllRequests();
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  refresh_tokens().clear();
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  loading_primary_account_id_ = primary_account_id;
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<TokenWebData> token_web_data = client()->GetDatabase();
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (token_web_data.get())
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    web_data_service_request_ = token_web_data->GetAllTokens(this);
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MutableProfileOAuth2TokenService::OnWebDataServiceRequestDone(
185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    WebDataServiceBase::Handle handle,
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const WDTypedResult* result) {
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_EQ(web_data_service_request_, handle);
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  web_data_service_request_ = 0;
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (result) {
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(result->GetType() == TOKEN_RESULT);
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const WDResult<std::map<std::string, std::string> > * token_result =
193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        static_cast<const WDResult<std::map<std::string, std::string> > * > (
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            result);
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LoadAllCredentialsIntoMemory(token_result->GetValue());
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Make sure that we have an entry for |loading_primary_account_id_| in the
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // map.  The entry could be missing if there is a corruption in the token DB
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // while this profile is connected to an account.
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!loading_primary_account_id_.empty());
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (refresh_tokens().count(loading_primary_account_id_) == 0) {
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    refresh_tokens()[loading_primary_account_id_].reset(
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new AccountInfo(this, loading_primary_account_id_, std::string()));
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If we don't have a refresh token for a known account, signal an error.
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (AccountInfoMap::const_iterator i = refresh_tokens_.begin();
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       i != refresh_tokens_.end(); ++i) {
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!RefreshTokenIsAvailable(i->first)) {
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      UpdateAuthError(
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          i->first,
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          GoogleServiceAuthError(
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  loading_primary_account_id_.clear();
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MutableProfileOAuth2TokenService::LoadAllCredentialsIntoMemory(
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::map<std::string, std::string>& db_tokens) {
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string old_login_token;
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  {
227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScopedBacthChange batch(this);
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    for (std::map<std::string, std::string>::const_iterator iter =
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             db_tokens.begin();
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         iter != db_tokens.end();
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         ++iter) {
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      std::string prefixed_account_id = iter->first;
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      std::string refresh_token = iter->second;
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (IsLegacyRefreshTokenId(prefixed_account_id) && !refresh_token.empty())
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        old_login_token = refresh_token;
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (IsLegacyServiceId(prefixed_account_id)) {
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        scoped_refptr<TokenWebData> token_web_data = client()->GetDatabase();
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        if (token_web_data.get())
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          token_web_data->RemoveTokenForService(prefixed_account_id);
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      } else {
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        DCHECK(!refresh_token.empty());
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        std::string account_id = RemoveAccountIdPrefix(prefixed_account_id);
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        refresh_tokens()[account_id].reset(
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            new AccountInfo(this, account_id, refresh_token));
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        FireRefreshTokenAvailable(account_id);
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        // TODO(fgorski): Notify diagnostic observers.
250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!old_login_token.empty()) {
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DCHECK(!loading_primary_account_id_.empty());
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (refresh_tokens().count(loading_primary_account_id_) == 0)
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        UpdateCredentials(loading_primary_account_id_, old_login_token);
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FireRefreshTokensLoaded();
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MutableProfileOAuth2TokenService::UpdateAuthError(
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& account_id,
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GoogleServiceAuthError& error) {
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Do not report connection errors as these are not actually auth errors.
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We also want to avoid masking a "real" auth error just because we
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // subsequently get a transient network error.
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error.state() == GoogleServiceAuthError::CONNECTION_FAILED ||
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE)
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (refresh_tokens_.count(account_id) == 0) {
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // This could happen if the preferences have been corrupted (see
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // http://crbug.com/321370). In a Debug build that would be a bug, but in a
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Release build we want to deal with it gracefully.
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED();
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  refresh_tokens_[account_id]->SetLastAuthError(error);
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::vector<std::string> MutableProfileOAuth2TokenService::GetAccounts() {
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<std::string> account_ids;
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (AccountInfoMap::const_iterator iter = refresh_tokens_.begin();
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           iter != refresh_tokens_.end(); ++iter) {
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    account_ids.push_back(iter->first);
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return account_ids;
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MutableProfileOAuth2TokenService::UpdateCredentials(
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& account_id,
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& refresh_token) {
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!account_id.empty());
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!refresh_token.empty());
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  signin_metrics::LogSigninAddAccount();
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool refresh_token_present = refresh_tokens_.count(account_id) > 0;
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!refresh_token_present ||
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      refresh_tokens_[account_id]->refresh_token() != refresh_token) {
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScopedBacthChange batch(this);
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // If token present, and different from the new one, cancel its requests,
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // and clear the entries in cache related to that account.
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (refresh_token_present) {
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::string revoke_reason = refresh_token_present ? "token differs" :
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                          "token is missing";
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      LOG(WARNING) << "Revoking refresh token on server. "
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   << "Reason: token update, " << revoke_reason;
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RevokeCredentialsOnServer(refresh_tokens_[account_id]->refresh_token());
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CancelRequestsForAccount(account_id);
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ClearCacheForAccount(account_id);
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      refresh_tokens_[account_id]->set_refresh_token(refresh_token);
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      refresh_tokens_[account_id].reset(
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          new AccountInfo(this, account_id, refresh_token));
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Save the token in memory and in persistent store.
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PersistCredentials(account_id, refresh_token);
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UpdateAuthError(account_id, GoogleServiceAuthError::AuthErrorNone());
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FireRefreshTokenAvailable(account_id);
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MutableProfileOAuth2TokenService::RevokeCredentials(
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& account_id) {
332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (refresh_tokens_.count(account_id) > 0) {
335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScopedBacthChange batch(this);
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RevokeCredentialsOnServer(refresh_tokens_[account_id]->refresh_token());
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CancelRequestsForAccount(account_id);
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ClearCacheForAccount(account_id);
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    refresh_tokens_.erase(account_id);
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ClearPersistedCredentials(account_id);
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FireRefreshTokenRevoked(account_id);
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MutableProfileOAuth2TokenService::PersistCredentials(
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& account_id,
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& refresh_token) {
348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<TokenWebData> token_web_data = client()->GetDatabase();
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (token_web_data.get()) {
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    token_web_data->SetTokenForService(ApplyAccountIdPrefix(account_id),
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       refresh_token);
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MutableProfileOAuth2TokenService::ClearPersistedCredentials(
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& account_id) {
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<TokenWebData> token_web_data = client()->GetDatabase();
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (token_web_data.get())
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    token_web_data->RemoveTokenForService(ApplyAccountIdPrefix(account_id));
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MutableProfileOAuth2TokenService::RevokeAllCredentials() {
363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!client()->CanRevokeCredentials())
364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScopedBacthChange batch(this);
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CancelWebTokenFetch();
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CancelAllRequests();
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ClearCache();
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AccountInfoMap tokens = refresh_tokens_;
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (AccountInfoMap::iterator i = tokens.begin(); i != tokens.end(); ++i)
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RevokeCredentials(i->first);
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(0u, refresh_tokens_.size());
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MutableProfileOAuth2TokenService::RevokeCredentialsOnServer(
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& refresh_token) {
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Keep track or all server revoke requests.  This way they can be deleted
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // before the token service is shutdown and won't outlive the profile.
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  server_revokes_.push_back(
384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new RevokeServerRefreshToken(this, refresh_token));
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MutableProfileOAuth2TokenService::CancelWebTokenFetch() {
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (web_data_service_request_ != 0) {
389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_refptr<TokenWebData> token_web_data = client()->GetDatabase();
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(token_web_data.get());
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    token_web_data->CancelRequest(web_data_service_request_);
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    web_data_service_request_  = 0;
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
395