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