1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
// 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.
#ifndef CHROME_BROWSER_SIGNIN_FAKE_PROFILE_OAUTH2_TOKEN_SERVICE_H_
#define CHROME_BROWSER_SIGNIN_FAKE_PROFILE_OAUTH2_TOKEN_SERVICE_H_
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
#if defined(OS_ANDROID)
#include "chrome/browser/signin/android_profile_oauth2_token_service.h"
#else
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#endif
// Helper class to simplify writing unittests that depend on an instance of
// ProfileOAuth2TokenService.
//
// Tests would typically do something like the following:
//
// FakeProfileOAuth2TokenService service;
// ...
// service.IssueRefreshToken("token"); // Issue refresh token/notify observers
// ...
// // Confirm that there is at least one active request.
// EXPECT_GT(0U, service.GetPendingRequests().size());
// ...
// // Make any pending token fetches for a given scope succeed.
// ScopeSet scopes;
// scopes.insert(GaiaConstants::kYourServiceScope);
// IssueTokenForScope(scopes, "access_token", base::Time()::Max());
// ...
// // ...or make them fail...
// IssueErrorForScope(scopes, GoogleServiceAuthError(INVALID_GAIA_CREDENTIALS));
//
class FakeProfileOAuth2TokenService
#if defined(OS_ANDROID)
: public AndroidProfileOAuth2TokenService {
#else
: public ProfileOAuth2TokenService {
#endif
public:
struct PendingRequest {
PendingRequest();
~PendingRequest();
std::string account_id;
std::string client_id;
std::string client_secret;
ScopeSet scopes;
base::WeakPtr<RequestImpl> request;
};
FakeProfileOAuth2TokenService();
~FakeProfileOAuth2TokenService() override;
// Overriden to make sure it works on Android.
bool RefreshTokenIsAvailable(const std::string& account_id) const override;
// Overriden to make sure it works on iOS.
void LoadCredentials(const std::string& primary_account_id) override;
std::vector<std::string> GetAccounts() override;
// Overriden to make sure it works on Android. Simply calls
// IssueRefreshToken().
void UpdateCredentials(const std::string& account_id,
const std::string& refresh_token) override;
// Sets the current refresh token. If |token| is non-empty, this will invoke
// OnRefreshTokenAvailable() on all Observers, otherwise this will invoke
// OnRefreshTokenRevoked().
void IssueRefreshToken(const std::string& token);
// TODO(fgorski,rogerta): Merge with UpdateCredentials when this class fully
// supports multiple accounts.
void IssueRefreshTokenForUser(const std::string& account_id,
const std::string& token);
// Fire OnRefreshTokensLoaded on all observers.
void IssueAllRefreshTokensLoaded();
// Gets a list of active requests (can be used by tests to validate that the
// correct request has been issued).
std::vector<PendingRequest> GetPendingRequests();
// Helper routines to issue tokens for pending requests.
void IssueAllTokensForAccount(const std::string& account_id,
const std::string& access_token,
const base::Time& expiration);
void IssueErrorForAllPendingRequestsForAccount(
const std::string& account_id,
const GoogleServiceAuthError& error);
void IssueTokenForScope(const ScopeSet& scopes,
const std::string& access_token,
const base::Time& expiration);
void IssueErrorForScope(const ScopeSet& scopes,
const GoogleServiceAuthError& error);
void IssueTokenForAllPendingRequests(const std::string& access_token,
const base::Time& expiration);
void IssueErrorForAllPendingRequests(const GoogleServiceAuthError& error);
void set_auto_post_fetch_response_on_message_loop(bool auto_post_response) {
auto_post_fetch_response_on_message_loop_ = auto_post_response;
}
protected:
// OAuth2TokenService overrides.
void FetchOAuth2Token(RequestImpl* request,
const std::string& account_id,
net::URLRequestContextGetter* getter,
const std::string& client_id,
const std::string& client_secret,
const ScopeSet& scopes) override;
OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
const std::string& account_id,
net::URLRequestContextGetter* getter,
OAuth2AccessTokenConsumer* consumer) override;
void InvalidateOAuth2Token(const std::string& account_id,
const std::string& client_id,
const ScopeSet& scopes,
const std::string& access_token) override;
net::URLRequestContextGetter* GetRequestContext() override;
private:
// Helper function to complete pending requests - if |all_scopes| is true,
// then all pending requests are completed, otherwise, only those requests
// matching |scopes| are completed. If |account_id| is empty, then pending
// requests for all accounts are completed, otherwise only requests for the
// given account.
void CompleteRequests(const std::string& account_id,
bool all_scopes,
const ScopeSet& scopes,
const GoogleServiceAuthError& error,
const std::string& access_token,
const base::Time& expiration);
std::string GetRefreshToken(const std::string& account_id) const;
std::vector<PendingRequest> pending_requests_;
// Maps account ids to their refresh token strings.
std::map<std::string, std::string> refresh_tokens_;
// If true, then this fake service will post responses to
// |FetchOAuth2Token| on the current run loop. There is no need to call
// |IssueTokenForScope| in this case.
bool auto_post_fetch_response_on_message_loop_;
base::WeakPtrFactory<FakeProfileOAuth2TokenService> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(FakeProfileOAuth2TokenService);
};
#endif // CHROME_BROWSER_SIGNIN_FAKE_PROFILE_OAUTH2_TOKEN_SERVICE_H_
|