13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file.
43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#ifndef CHROME_BROWSER_SIGNIN_FAKE_PROFILE_OAUTH2_TOKEN_SERVICE_H_
63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define CHROME_BROWSER_SIGNIN_FAKE_PROFILE_OAUTH2_TOKEN_SERVICE_H_
73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <string>
93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <vector>
103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/compiler_specific.h"
123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/weak_ptr.h"
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_ANDROID)
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/signin/android_profile_oauth2_token_service.h"
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#else
17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h"
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Helper class to simplify writing unittests that depend on an instance of
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ProfileOAuth2TokenService.
223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests would typically do something like the following:
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// FakeProfileOAuth2TokenService service;
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ...
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// service.IssueRefreshToken("token");  // Issue refresh token/notify observers
283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ...
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// // Confirm that there is at least one active request.
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// EXPECT_GT(0U, service.GetPendingRequests().size());
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ...
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// // Make any pending token fetches for a given scope succeed.
333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ScopeSet scopes;
343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// scopes.insert(GaiaConstants::kYourServiceScope);
353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// IssueTokenForScope(scopes, "access_token", base::Time()::Max());
363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ...
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// // ...or make them fail...
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// IssueErrorForScope(scopes, GoogleServiceAuthError(INVALID_GAIA_CREDENTIALS));
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class FakeProfileOAuth2TokenService
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_ANDROID)
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  : public AndroidProfileOAuth2TokenService {
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#else
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  : public ProfileOAuth2TokenService {
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  struct PendingRequest {
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    PendingRequest();
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ~PendingRequest();
503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    std::string account_id;
523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string client_id;
533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string client_secret;
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ScopeSet scopes;
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::WeakPtr<RequestImpl> request;
563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeProfileOAuth2TokenService();
593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeProfileOAuth2TokenService();
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Overriden to make sure it works on Android.
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual bool RefreshTokenIsAvailable(
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const std::string& account_id) const OVERRIDE;
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Overriden to make sure it works on iOS.
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void LoadCredentials(const std::string& primary_account_id) OVERRIDE;
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual std::vector<std::string> GetAccounts() OVERRIDE;
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Overriden to make sure it works on Android.  Simply calls
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // IssueRefreshToken().
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void UpdateCredentials(const std::string& account_id,
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 const std::string& refresh_token) OVERRIDE;
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Sets the current refresh token. If |token| is non-empty, this will invoke
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // OnRefreshTokenAvailable() on all Observers, otherwise this will invoke
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // OnRefreshTokenRevoked().
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void IssueRefreshToken(const std::string& token);
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // TODO(fgorski,rogerta): Merge with UpdateCredentials when this class fully
818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // supports multiple accounts.
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void IssueRefreshTokenForUser(const std::string& account_id,
838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                const std::string& token);
848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Fire OnRefreshTokensLoaded on all observers.
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void IssueAllRefreshTokensLoaded();
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Gets a list of active requests (can be used by tests to validate that the
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // correct request has been issued).
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::vector<PendingRequest> GetPendingRequests();
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Helper routines to issue tokens for pending requests.
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void IssueAllTokensForAccount(const std::string& account_id,
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                const std::string& access_token,
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                const base::Time& expiration);
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void IssueErrorForAllPendingRequestsForAccount(
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const std::string& account_id,
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const GoogleServiceAuthError& error);
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void IssueTokenForScope(const ScopeSet& scopes,
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          const std::string& access_token,
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          const base::Time& expiration);
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void IssueErrorForScope(const ScopeSet& scopes,
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          const GoogleServiceAuthError& error);
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void IssueTokenForAllPendingRequests(const std::string& access_token,
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                       const base::Time& expiration);
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void IssueErrorForAllPendingRequests(const GoogleServiceAuthError& error);
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void set_auto_post_fetch_response_on_message_loop(bool auto_post_response) {
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    auto_post_fetch_response_on_message_loop_ = auto_post_response;
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) protected:
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // OAuth2TokenService overrides.
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void FetchOAuth2Token(RequestImpl* request,
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                const std::string& account_id,
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                net::URLRequestContextGetter* getter,
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                const std::string& client_id,
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                const std::string& client_secret,
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                const ScopeSet& scopes) OVERRIDE;
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const std::string& account_id,
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::URLRequestContextGetter* getter,
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      OAuth2AccessTokenConsumer* consumer) OVERRIDE;
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void InvalidateOAuth2Token(const std::string& account_id,
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     const std::string& client_id,
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     const ScopeSet& scopes,
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     const std::string& access_token) OVERRIDE;
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE;
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Helper function to complete pending requests - if |all_scopes| is true,
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // then all pending requests are completed, otherwise, only those requests
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // matching |scopes| are completed.  If |account_id| is empty, then pending
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // requests for all accounts are completed, otherwise only requests for the
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // given account.
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CompleteRequests(const std::string& account_id,
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        bool all_scopes,
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        const ScopeSet& scopes,
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        const GoogleServiceAuthError& error,
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        const std::string& access_token,
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        const base::Time& expiration);
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string GetRefreshToken(const std::string& account_id) const;
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::vector<PendingRequest> pending_requests_;
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Maps account ids to their refresh token strings.
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<std::string, std::string> refresh_tokens_;
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If true, then this fake service will post responses to
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |FetchOAuth2Token| on the current run loop. There is no need to call
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |IssueTokenForScope| in this case.
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool auto_post_fetch_response_on_message_loop_;
1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::WeakPtrFactory<FakeProfileOAuth2TokenService> weak_ptr_factory_;
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeProfileOAuth2TokenService);
1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif  // CHROME_BROWSER_SIGNIN_FAKE_PROFILE_OAUTH2_TOKEN_SERVICE_H_
169