1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.h"
6 
7 #include "components/signin/internal/identity_manager/profile_oauth2_token_service.h"
8 #include "google_apis/gaia/gaia_constants.h"
9 #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h"
10 
11 namespace {
12 // Values used from |MutableProfileOAuth2TokenServiceDelegate|.
13 const net::BackoffEntry::Policy kBackoffPolicy = {
14     0 /* int num_errors_to_ignore */,
15 
16     1000 /* int initial_delay_ms */,
17 
18     2.0 /* double multiply_factor */,
19 
20     0.2 /* double jitter_factor */,
21 
22     15 * 60 * 1000 /* int64_t maximum_backoff_ms */,
23 
24     -1 /* int64_t entry_lifetime_ms */,
25 
26     false /* bool always_use_initial_delay */,
27 };
28 }  // namespace
29 
AccountInfo(const std::string & refresh_token)30 FakeProfileOAuth2TokenServiceDelegate::AccountInfo::AccountInfo(
31     const std::string& refresh_token)
32     : refresh_token(refresh_token), error(GoogleServiceAuthError::NONE) {}
33 
FakeProfileOAuth2TokenServiceDelegate()34 FakeProfileOAuth2TokenServiceDelegate::FakeProfileOAuth2TokenServiceDelegate()
35     : shared_factory_(
36           base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
37               &test_url_loader_factory_)),
38       backoff_entry_(&kBackoffPolicy) {}
39 
40 FakeProfileOAuth2TokenServiceDelegate::
41     ~FakeProfileOAuth2TokenServiceDelegate() = default;
42 
43 std::unique_ptr<OAuth2AccessTokenFetcher>
CreateAccessTokenFetcher(const CoreAccountId & account_id,scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,OAuth2AccessTokenConsumer * consumer)44 FakeProfileOAuth2TokenServiceDelegate::CreateAccessTokenFetcher(
45     const CoreAccountId& account_id,
46     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
47     OAuth2AccessTokenConsumer* consumer) {
48   auto it = refresh_tokens_.find(account_id);
49   DCHECK(it != refresh_tokens_.end());
50   return std::make_unique<OAuth2AccessTokenFetcherImpl>(
51       consumer, url_loader_factory, it->second->refresh_token);
52 }
53 
RefreshTokenIsAvailable(const CoreAccountId & account_id) const54 bool FakeProfileOAuth2TokenServiceDelegate::RefreshTokenIsAvailable(
55     const CoreAccountId& account_id) const {
56   return !GetRefreshToken(account_id).empty();
57 }
58 
GetAuthError(const CoreAccountId & account_id) const59 GoogleServiceAuthError FakeProfileOAuth2TokenServiceDelegate::GetAuthError(
60     const CoreAccountId& account_id) const {
61   auto it = refresh_tokens_.find(account_id);
62   return (it == refresh_tokens_.end()) ? GoogleServiceAuthError::AuthErrorNone()
63                                        : it->second->error;
64 }
65 
GetRefreshToken(const CoreAccountId & account_id) const66 std::string FakeProfileOAuth2TokenServiceDelegate::GetRefreshToken(
67     const CoreAccountId& account_id) const {
68   auto it = refresh_tokens_.find(account_id);
69   if (it != refresh_tokens_.end())
70     return it->second->refresh_token;
71   return std::string();
72 }
73 
BackoffEntry() const74 const net::BackoffEntry* FakeProfileOAuth2TokenServiceDelegate::BackoffEntry()
75     const {
76   return &backoff_entry_;
77 }
78 
GetAccounts() const79 std::vector<CoreAccountId> FakeProfileOAuth2TokenServiceDelegate::GetAccounts()
80     const {
81   std::vector<CoreAccountId> account_ids;
82   for (const auto& token : refresh_tokens_)
83     account_ids.push_back(token.first);
84   return account_ids;
85 }
86 
RevokeAllCredentials()87 void FakeProfileOAuth2TokenServiceDelegate::RevokeAllCredentials() {
88   std::vector<CoreAccountId> account_ids = GetAccounts();
89   for (const auto& account : account_ids)
90     RevokeCredentials(account);
91 }
92 
LoadCredentials(const CoreAccountId & primary_account_id)93 void FakeProfileOAuth2TokenServiceDelegate::LoadCredentials(
94     const CoreAccountId& primary_account_id) {
95   set_load_credentials_state(
96       signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS);
97   FireRefreshTokensLoaded();
98 }
99 
UpdateCredentials(const CoreAccountId & account_id,const std::string & refresh_token)100 void FakeProfileOAuth2TokenServiceDelegate::UpdateCredentials(
101     const CoreAccountId& account_id,
102     const std::string& refresh_token) {
103   IssueRefreshTokenForUser(account_id, refresh_token);
104 }
105 
IssueRefreshTokenForUser(const CoreAccountId & account_id,const std::string & token)106 void FakeProfileOAuth2TokenServiceDelegate::IssueRefreshTokenForUser(
107     const CoreAccountId& account_id,
108     const std::string& token) {
109   ScopedBatchChange batch(this);
110   if (token.empty()) {
111     refresh_tokens_.erase(account_id);
112     FireRefreshTokenRevoked(account_id);
113   } else {
114     refresh_tokens_[account_id].reset(new AccountInfo(token));
115     // If the token is a special "invalid" value, then that means the token was
116     // rejected by the client and is thus not valid. So set the appropriate
117     // error in that case. This logic is essentially duplicated from
118     // MutableProfileOAuth2TokenServiceDelegate.
119     if (token == GaiaConstants::kInvalidRefreshToken) {
120       refresh_tokens_[account_id]->error =
121           GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
122               GoogleServiceAuthError::InvalidGaiaCredentialsReason::
123                   CREDENTIALS_REJECTED_BY_CLIENT);
124     }
125     FireRefreshTokenAvailable(account_id);
126   }
127 }
128 
RevokeCredentials(const CoreAccountId & account_id)129 void FakeProfileOAuth2TokenServiceDelegate::RevokeCredentials(
130     const CoreAccountId& account_id) {
131   IssueRefreshTokenForUser(account_id, std::string());
132 }
133 
ExtractCredentials(ProfileOAuth2TokenService * to_service,const CoreAccountId & account_id)134 void FakeProfileOAuth2TokenServiceDelegate::ExtractCredentials(
135     ProfileOAuth2TokenService* to_service,
136     const CoreAccountId& account_id) {
137   auto it = refresh_tokens_.find(account_id);
138   DCHECK(it != refresh_tokens_.end());
139   to_service->GetDelegate()->UpdateCredentials(account_id,
140                                                it->second->refresh_token);
141   RevokeCredentials(account_id);
142 }
143 
144 scoped_refptr<network::SharedURLLoaderFactory>
GetURLLoaderFactory() const145 FakeProfileOAuth2TokenServiceDelegate::GetURLLoaderFactory() const {
146   return shared_factory_;
147 }
148 
FixRequestErrorIfPossible()149 bool FakeProfileOAuth2TokenServiceDelegate::FixRequestErrorIfPossible() {
150   return fix_request_if_possible_;
151 }
152 
UpdateAuthError(const CoreAccountId & account_id,const GoogleServiceAuthError & error)153 void FakeProfileOAuth2TokenServiceDelegate::UpdateAuthError(
154     const CoreAccountId& account_id,
155     const GoogleServiceAuthError& error) {
156   backoff_entry_.InformOfRequest(!error.IsTransientError());
157   // Drop transient errors to match ProfileOAuth2TokenService's stated contract
158   // for GetAuthError() and to allow clients to test proper behavior in the case
159   // of transient errors.
160   if (error.IsTransientError())
161     return;
162 
163   if (GetAuthError(account_id) == error)
164     return;
165 
166   auto it = refresh_tokens_.find(account_id);
167   DCHECK(it != refresh_tokens_.end());
168   it->second->error = error;
169   FireAuthErrorChanged(account_id, error);
170 }
171 
172 #if defined(OS_ANDROID)
173 base::android::ScopedJavaLocalRef<jobject>
GetJavaObject()174 FakeProfileOAuth2TokenServiceDelegate::GetJavaObject() {
175   return base::android::ScopedJavaLocalRef<jobject>();
176 }
177 #endif
178