| // Copyright 2017 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. |
| |
| #include "components/signin/public/identity_manager/identity_test_environment.h" |
| #include "base/memory/raw_ptr.h" |
| |
| #include <limits> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/bind.h" |
| #include "base/callback_helpers.h" |
| #include "base/run_loop.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "build/build_config.h" |
| #include "build/chromeos_buildflags.h" |
| #include "components/image_fetcher/core/fake_image_decoder.h" |
| #include "components/signin/internal/identity_manager/account_fetcher_service.h" |
| #include "components/signin/internal/identity_manager/account_tracker_service.h" |
| #include "components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h" |
| #include "components/signin/internal/identity_manager/diagnostics_provider_impl.h" |
| #include "components/signin/internal/identity_manager/fake_profile_oauth2_token_service.h" |
| #include "components/signin/internal/identity_manager/gaia_cookie_manager_service.h" |
| #include "components/signin/internal/identity_manager/primary_account_manager.h" |
| #include "components/signin/internal/identity_manager/primary_account_mutator_impl.h" |
| #include "components/signin/internal/identity_manager/primary_account_policy_manager_impl.h" |
| #include "components/signin/public/base/consent_level.h" |
| #include "components/signin/public/base/test_signin_client.h" |
| #include "components/signin/public/identity_manager/accounts_mutator.h" |
| #include "components/signin/public/identity_manager/device_accounts_synchronizer.h" |
| #include "components/signin/public/identity_manager/identity_manager.h" |
| #include "components/signin/public/identity_manager/identity_test_utils.h" |
| #include "components/signin/public/identity_manager/primary_account_mutator.h" |
| #include "components/signin/public/identity_manager/test_identity_manager_observer.h" |
| #include "components/sync_preferences/testing_pref_service_syncable.h" |
| #include "google_apis/gaia/oauth2_access_token_consumer.h" |
| #include "services/network/test/test_url_loader_factory.h" |
| |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| #include "ash/components/account_manager/account_manager_factory.h" |
| #include "components/account_manager_core/account_manager_facade_impl.h" |
| #include "components/account_manager_core/chromeos/account_manager.h" |
| #include "components/account_manager_core/chromeos/account_manager_mojo_service.h" |
| #include "components/signin/internal/identity_manager/test_profile_oauth2_token_service_delegate_chromeos.h" |
| #endif |
| |
| #if BUILDFLAG(IS_CHROMEOS_LACROS) |
| #include "components/account_manager_core/chromeos/account_manager_facade_factory.h" |
| #endif |
| |
| #if defined(OS_IOS) |
| #include "components/signin/internal/identity_manager/device_accounts_synchronizer_impl.h" |
| #include "components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.h" |
| #endif |
| |
| #if !defined(OS_ANDROID) && !defined(OS_IOS) |
| #include "components/signin/internal/identity_manager/accounts_mutator_impl.h" |
| #endif |
| |
| using TokenResponseBuilder = OAuth2AccessTokenConsumer::TokenResponse::Builder; |
| |
| namespace signin { |
| |
| class IdentityManagerDependenciesOwner { |
| public: |
| IdentityManagerDependenciesOwner( |
| sync_preferences::TestingPrefServiceSyncable* pref_service, |
| TestSigninClient* test_signin_client); |
| |
| IdentityManagerDependenciesOwner(const IdentityManagerDependenciesOwner&) = |
| delete; |
| IdentityManagerDependenciesOwner& operator=( |
| const IdentityManagerDependenciesOwner&) = delete; |
| |
| ~IdentityManagerDependenciesOwner(); |
| |
| sync_preferences::TestingPrefServiceSyncable* pref_service(); |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| ash::AccountManagerFactory* account_manager_factory(); |
| account_manager::AccountManagerFacade* GetAccountManagerFacadeForEmptyPath(); |
| #endif |
| TestSigninClient* signin_client(); |
| |
| private: |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| std::unique_ptr<ash::AccountManagerFactory> account_manager_factory_; |
| std::unique_ptr<account_manager::AccountManagerFacadeImpl> |
| account_manager_facade_for_empty_path_; |
| #endif |
| // Depending on whether a |pref_service| instance is passed in |
| // the constructor, exactly one of these will be non-null. |
| std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> |
| owned_pref_service_; |
| raw_ptr<sync_preferences::TestingPrefServiceSyncable> raw_pref_service_ = |
| nullptr; |
| std::unique_ptr<TestSigninClient> owned_signin_client_; |
| raw_ptr<TestSigninClient> raw_signin_client_ = nullptr; |
| }; |
| |
| IdentityManagerDependenciesOwner::IdentityManagerDependenciesOwner( |
| sync_preferences::TestingPrefServiceSyncable* pref_service_param, |
| TestSigninClient* signin_client_param) |
| : |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| account_manager_factory_(std::make_unique<ash::AccountManagerFactory>()), |
| #endif |
| owned_pref_service_( |
| pref_service_param |
| ? nullptr |
| : std::make_unique< |
| sync_preferences::TestingPrefServiceSyncable>()), |
| raw_pref_service_(pref_service_param), |
| owned_signin_client_( |
| signin_client_param |
| ? nullptr |
| : std::make_unique<TestSigninClient>(pref_service())), |
| raw_signin_client_(signin_client_param) { |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| mojo::Remote<crosapi::mojom::AccountManager> remote; |
| crosapi::AccountManagerMojoService* account_manager_mojo_service = |
| account_manager_factory_->GetAccountManagerMojoService(std::string()); |
| account_manager_mojo_service->BindReceiver( |
| remote.BindNewPipeAndPassReceiver()); |
| account_manager_facade_for_empty_path_ = |
| std::make_unique<account_manager::AccountManagerFacadeImpl>( |
| std::move(remote), |
| /*remote_version=*/std::numeric_limits<uint32_t>::max(), |
| /*account_manager_for_tests=*/ |
| account_manager_factory_->GetAccountManager(std::string())); |
| #endif |
| } |
| |
| IdentityManagerDependenciesOwner::~IdentityManagerDependenciesOwner() { |
| if (owned_signin_client_) |
| owned_signin_client_->Shutdown(); |
| } |
| |
| sync_preferences::TestingPrefServiceSyncable* |
| IdentityManagerDependenciesOwner::pref_service() { |
| DCHECK(raw_pref_service_ || owned_pref_service_); |
| DCHECK(!(raw_pref_service_ && owned_pref_service_)); |
| |
| return raw_pref_service_ ? raw_pref_service_.get() |
| : owned_pref_service_.get(); |
| } |
| |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| ash::AccountManagerFactory* |
| IdentityManagerDependenciesOwner::account_manager_factory() { |
| DCHECK(account_manager_factory_); |
| return account_manager_factory_.get(); |
| } |
| |
| account_manager::AccountManagerFacade* |
| IdentityManagerDependenciesOwner::GetAccountManagerFacadeForEmptyPath() { |
| return account_manager_facade_for_empty_path_.get(); |
| } |
| #endif |
| |
| TestSigninClient* IdentityManagerDependenciesOwner::signin_client() { |
| DCHECK(raw_signin_client_ || owned_signin_client_); |
| DCHECK(!(raw_signin_client_ && owned_signin_client_)); |
| |
| return raw_signin_client_ ? raw_signin_client_.get() |
| : owned_signin_client_.get(); |
| } |
| |
| IdentityTestEnvironment::IdentityTestEnvironment( |
| network::TestURLLoaderFactory* test_url_loader_factory, |
| sync_preferences::TestingPrefServiceSyncable* pref_service, |
| AccountConsistencyMethod account_consistency, |
| TestSigninClient* test_signin_client) |
| : IdentityTestEnvironment( |
| std::make_unique<IdentityManagerDependenciesOwner>( |
| pref_service, |
| test_signin_client), |
| test_url_loader_factory, |
| account_consistency) { |
| DCHECK(!test_url_loader_factory || !test_signin_client); |
| } |
| |
| IdentityTestEnvironment::IdentityTestEnvironment( |
| IdentityManager* identity_manager, |
| SigninClient* signin_client) { |
| DCHECK(identity_manager); |
| raw_identity_manager_ = identity_manager; |
| raw_signin_client_ = signin_client; |
| Initialize(); |
| } |
| |
| void IdentityTestEnvironment::Initialize() { |
| DCHECK(base::ThreadTaskRunnerHandle::Get()) |
| << "IdentityTestEnvironment requires a properly set up task " |
| "environment. " |
| "If your test has an existing one, move it to be initialized before " |
| "IdentityTestEnvironment. Otherwise, use " |
| "base::test::TaskEnvironment."; |
| DCHECK(identity_manager() |
| ->GetTokenService() |
| ->IsFakeProfileOAuth2TokenServiceForTesting()) |
| << "IdentityTestEnvironment requires the ProfileOAuth2TokenService used " |
| "to subclass FakeProfileOAuth2TokenServiceForTesting."; |
| test_identity_manager_observer_ = |
| std::make_unique<TestIdentityManagerObserver>(identity_manager()); |
| diagnostics_observation_.Observe(identity_manager()); |
| identity_manager_observation_.Observe(identity_manager()); |
| } |
| |
| IdentityTestEnvironment::IdentityTestEnvironment( |
| std::unique_ptr<IdentityManagerDependenciesOwner> dependencies_owner, |
| network::TestURLLoaderFactory* test_url_loader_factory, |
| AccountConsistencyMethod account_consistency) { |
| dependencies_owner_ = std::move(dependencies_owner); |
| TestSigninClient* test_signin_client = dependencies_owner_->signin_client(); |
| if (test_url_loader_factory) |
| test_signin_client->OverrideTestUrlLoaderFactory(test_url_loader_factory); |
| test_url_loader_factory_ = test_signin_client->GetTestURLLoaderFactory(); |
| |
| sync_preferences::TestingPrefServiceSyncable* test_pref_service = |
| dependencies_owner_->pref_service(); |
| |
| IdentityManager::RegisterProfilePrefs(test_pref_service->registry()); |
| IdentityManager::RegisterLocalStatePrefs(test_pref_service->registry()); |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| account_manager::AccountManager::RegisterPrefs(test_pref_service->registry()); |
| |
| owned_identity_manager_ = BuildIdentityManagerForTests( |
| test_signin_client, test_pref_service, base::FilePath(), |
| dependencies_owner_->account_manager_factory(), |
| dependencies_owner_->GetAccountManagerFacadeForEmptyPath(), |
| account_consistency); |
| #else |
| owned_identity_manager_ = |
| BuildIdentityManagerForTests(test_signin_client, test_pref_service, |
| base::FilePath(), account_consistency); |
| #endif // BUILDFLAG(IS_CHROMEOS_ASH) |
| |
| Initialize(); |
| } |
| |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| // static |
| std::unique_ptr<IdentityManager> |
| IdentityTestEnvironment::BuildIdentityManagerForTests( |
| SigninClient* signin_client, |
| PrefService* pref_service, |
| base::FilePath user_data_dir, |
| ash::AccountManagerFactory* account_manager_factory, |
| account_manager::AccountManagerFacade* account_manager_facade, |
| AccountConsistencyMethod account_consistency) { |
| auto account_tracker_service = std::make_unique<AccountTrackerService>(); |
| account_tracker_service->Initialize(pref_service, user_data_dir); |
| |
| account_manager::AccountManager* account_manager = |
| account_manager_factory->GetAccountManager(user_data_dir.value()); |
| |
| if (user_data_dir.empty()) { |
| account_manager->InitializeInEphemeralMode( |
| signin_client->GetURLLoaderFactory()); |
| } else { |
| account_manager::AccountManager::DelayNetworkCallRunner |
| immediate_callback_runner = |
| base::BindRepeating([](base::OnceClosure closure) -> void { |
| std::move(closure).Run(); |
| }); |
| account_manager->Initialize(user_data_dir, |
| signin_client->GetURLLoaderFactory(), |
| immediate_callback_runner, base::DoNothing()); |
| } |
| account_manager->SetPrefService(pref_service); |
| account_manager->SetUrlLoaderFactoryForTests( |
| signin_client->GetURLLoaderFactory()); |
| |
| auto token_service = std::make_unique<FakeProfileOAuth2TokenService>( |
| pref_service, |
| std::make_unique<TestProfileOAuth2TokenServiceDelegateChromeOS>( |
| account_tracker_service.get(), |
| account_manager_factory->GetAccountManagerMojoService( |
| user_data_dir.value()), |
| /*is_regular_profile=*/true)); |
| |
| return FinishBuildIdentityManagerForTests( |
| std::move(account_tracker_service), std::move(token_service), |
| signin_client, pref_service, user_data_dir, account_manager_facade, |
| account_consistency); |
| } |
| #else |
| // static |
| std::unique_ptr<IdentityManager> |
| IdentityTestEnvironment::BuildIdentityManagerForTests( |
| SigninClient* signin_client, |
| PrefService* pref_service, |
| base::FilePath user_data_dir, |
| AccountConsistencyMethod account_consistency) { |
| auto account_tracker_service = std::make_unique<AccountTrackerService>(); |
| account_tracker_service->Initialize(pref_service, user_data_dir); |
| auto token_service = |
| std::make_unique<FakeProfileOAuth2TokenService>(pref_service); |
| return FinishBuildIdentityManagerForTests( |
| std::move(account_tracker_service), std::move(token_service), |
| signin_client, pref_service, user_data_dir, account_consistency); |
| } |
| #endif // BUILDFLAG(IS_CHROMEOS_ASH) |
| |
| IdentityTestEnvironment::PendingRequest::PendingRequest( |
| CoreAccountId account_id, |
| std::string client_id, |
| std::string client_secret, |
| OAuth2AccessTokenManager::ScopeSet scopes) |
| : account_id(account_id), |
| client_id(client_id), |
| client_secret(client_secret), |
| scopes(scopes) {} |
| |
| IdentityTestEnvironment::PendingRequest::PendingRequest(const PendingRequest&) = |
| default; |
| |
| IdentityTestEnvironment::PendingRequest::~PendingRequest() = default; |
| |
| // static |
| std::unique_ptr<IdentityManager> |
| IdentityTestEnvironment::FinishBuildIdentityManagerForTests( |
| std::unique_ptr<AccountTrackerService> account_tracker_service, |
| std::unique_ptr<ProfileOAuth2TokenService> token_service, |
| SigninClient* signin_client, |
| PrefService* pref_service, |
| base::FilePath user_data_dir, |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| account_manager::AccountManagerFacade* account_manager_facade, |
| #endif |
| AccountConsistencyMethod account_consistency) { |
| auto account_fetcher_service = std::make_unique<AccountFetcherService>(); |
| account_fetcher_service->Initialize( |
| signin_client, token_service.get(), account_tracker_service.get(), |
| std::make_unique<image_fetcher::FakeImageDecoder>()); |
| |
| std::unique_ptr<PrimaryAccountPolicyManager> policy_manager; |
| #if !BUILDFLAG(IS_CHROMEOS_ASH) |
| policy_manager = |
| std::make_unique<PrimaryAccountPolicyManagerImpl>(signin_client); |
| #endif |
| std::unique_ptr<PrimaryAccountManager> primary_account_manager = |
| std::make_unique<PrimaryAccountManager>( |
| signin_client, token_service.get(), account_tracker_service.get(), |
| std::move(policy_manager)); |
| primary_account_manager->Initialize(pref_service); |
| |
| std::unique_ptr<GaiaCookieManagerService> gaia_cookie_manager_service = |
| std::make_unique<GaiaCookieManagerService>(token_service.get(), |
| signin_client); |
| IdentityManager::InitParameters init_params; |
| init_params.primary_account_mutator = |
| std::make_unique<PrimaryAccountMutatorImpl>( |
| account_tracker_service.get(), token_service.get(), |
| primary_account_manager.get(), pref_service, account_consistency); |
| |
| #if !defined(OS_ANDROID) && !defined(OS_IOS) |
| init_params.accounts_mutator = std::make_unique<AccountsMutatorImpl>( |
| token_service.get(), account_tracker_service.get(), |
| primary_account_manager.get(), pref_service); |
| #endif |
| |
| init_params.diagnostics_provider = std::make_unique<DiagnosticsProviderImpl>( |
| token_service.get(), gaia_cookie_manager_service.get()); |
| |
| init_params.accounts_cookie_mutator = |
| std::make_unique<AccountsCookieMutatorImpl>( |
| signin_client, token_service.get(), gaia_cookie_manager_service.get(), |
| account_tracker_service.get()); |
| |
| #if defined(OS_IOS) |
| init_params.device_accounts_synchronizer = |
| std::make_unique<DeviceAccountsSynchronizerImpl>( |
| token_service->GetDelegate()); |
| #endif |
| |
| init_params.account_fetcher_service = std::move(account_fetcher_service); |
| init_params.account_tracker_service = std::move(account_tracker_service); |
| init_params.gaia_cookie_manager_service = |
| std::move(gaia_cookie_manager_service); |
| init_params.primary_account_manager = std::move(primary_account_manager); |
| init_params.token_service = std::move(token_service); |
| // TODO: Set the account_manager_facade on Lacros once Mirror is enabled by |
| // default. |
| #if BUILDFLAG(IS_CHROMEOS_ASH) |
| init_params.account_manager_facade = account_manager_facade; |
| #endif |
| #if BUILDFLAG(IS_CHROMEOS_LACROS) |
| init_params.signin_client = signin_client; |
| #endif |
| |
| return std::make_unique<IdentityManager>(std::move(init_params)); |
| } |
| |
| IdentityTestEnvironment::~IdentityTestEnvironment() { |
| if (owned_identity_manager_) |
| owned_identity_manager_->Shutdown(); |
| } |
| |
| IdentityManager* IdentityTestEnvironment::identity_manager() { |
| DCHECK(raw_identity_manager_ || owned_identity_manager_); |
| DCHECK(!(raw_identity_manager_ && owned_identity_manager_)); |
| |
| return raw_identity_manager_ ? raw_identity_manager_.get() |
| : owned_identity_manager_.get(); |
| } |
| |
| TestIdentityManagerObserver* |
| IdentityTestEnvironment::identity_manager_observer() { |
| return test_identity_manager_observer_.get(); |
| } |
| |
| void IdentityTestEnvironment::WaitForRefreshTokensLoaded() { |
| signin::WaitForRefreshTokensLoaded(identity_manager()); |
| } |
| |
| CoreAccountInfo IdentityTestEnvironment::SetPrimaryAccount( |
| const std::string& email, |
| ConsentLevel consent_level) { |
| return signin::SetPrimaryAccount(identity_manager(), email, consent_level); |
| } |
| |
| void IdentityTestEnvironment::SetRefreshTokenForPrimaryAccount() { |
| signin::SetRefreshTokenForPrimaryAccount(identity_manager()); |
| } |
| |
| void IdentityTestEnvironment::SetInvalidRefreshTokenForPrimaryAccount() { |
| signin::SetInvalidRefreshTokenForPrimaryAccount(identity_manager()); |
| } |
| |
| void IdentityTestEnvironment::RemoveRefreshTokenForPrimaryAccount() { |
| signin::RemoveRefreshTokenForPrimaryAccount(identity_manager()); |
| } |
| |
| AccountInfo IdentityTestEnvironment::MakePrimaryAccountAvailable( |
| const std::string& email, |
| ConsentLevel consent_level) { |
| return signin::MakePrimaryAccountAvailable(identity_manager(), email, |
| consent_level); |
| } |
| |
| void IdentityTestEnvironment::RevokeSyncConsent() { |
| signin::RevokeSyncConsent(identity_manager()); |
| } |
| |
| void IdentityTestEnvironment::ClearPrimaryAccount() { |
| signin::ClearPrimaryAccount(identity_manager()); |
| } |
| |
| AccountInfo IdentityTestEnvironment::MakeAccountAvailable( |
| const std::string& email) { |
| return signin::MakeAccountAvailable(identity_manager(), email); |
| } |
| |
| AccountInfo IdentityTestEnvironment::MakeAccountAvailableWithCookies( |
| const std::string& email, |
| const std::string& gaia_id) { |
| return signin::MakeAccountAvailableWithCookies( |
| identity_manager(), test_url_loader_factory(), email, gaia_id); |
| } |
| |
| void IdentityTestEnvironment::SetRefreshTokenForAccount( |
| const CoreAccountId& account_id) { |
| return signin::SetRefreshTokenForAccount(identity_manager(), account_id); |
| } |
| |
| void IdentityTestEnvironment::SetInvalidRefreshTokenForAccount( |
| const CoreAccountId& account_id) { |
| return signin::SetInvalidRefreshTokenForAccount(identity_manager(), |
| account_id); |
| } |
| |
| void IdentityTestEnvironment::RemoveRefreshTokenForAccount( |
| const CoreAccountId& account_id) { |
| return signin::RemoveRefreshTokenForAccount(identity_manager(), account_id); |
| } |
| |
| void IdentityTestEnvironment::UpdatePersistentErrorOfRefreshTokenForAccount( |
| const CoreAccountId& account_id, |
| const GoogleServiceAuthError& auth_error) { |
| return signin::UpdatePersistentErrorOfRefreshTokenForAccount( |
| identity_manager(), account_id, auth_error); |
| } |
| |
| void IdentityTestEnvironment::SetCookieAccounts( |
| const std::vector<CookieParamsForTest>& cookie_accounts) { |
| signin::SetCookieAccounts(identity_manager(), test_url_loader_factory(), |
| cookie_accounts); |
| } |
| |
| void IdentityTestEnvironment::SetAutomaticIssueOfAccessTokens(bool grant) { |
| fake_token_service()->set_auto_post_fetch_response_on_message_loop(grant); |
| } |
| |
| void IdentityTestEnvironment:: |
| WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( |
| const std::string& token, |
| const base::Time& expiration, |
| const std::string& id_token) { |
| WaitForAccessTokenRequestIfNecessary(absl::nullopt); |
| fake_token_service()->IssueTokenForAllPendingRequests( |
| TokenResponseBuilder() |
| .WithAccessToken(token) |
| .WithExpirationTime(expiration) |
| .WithIdToken(id_token) |
| .build()); |
| } |
| |
| void IdentityTestEnvironment:: |
| WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( |
| const CoreAccountId& account_id, |
| const std::string& token, |
| const base::Time& expiration, |
| const std::string& id_token) { |
| WaitForAccessTokenRequestIfNecessary(account_id); |
| fake_token_service()->IssueAllTokensForAccount( |
| account_id, TokenResponseBuilder() |
| .WithAccessToken(token) |
| .WithExpirationTime(expiration) |
| .WithIdToken(id_token) |
| .build()); |
| } |
| |
| void IdentityTestEnvironment:: |
| WaitForAccessTokenRequestIfNecessaryAndRespondWithTokenForScopes( |
| const std::string& token, |
| const base::Time& expiration, |
| const std::string& id_token, |
| const ScopeSet& scopes) { |
| WaitForAccessTokenRequestIfNecessary(absl::nullopt); |
| fake_token_service()->IssueTokenForScope(scopes, |
| TokenResponseBuilder() |
| .WithAccessToken(token) |
| .WithExpirationTime(expiration) |
| .WithIdToken(id_token) |
| .build()); |
| } |
| |
| void IdentityTestEnvironment:: |
| WaitForAccessTokenRequestIfNecessaryAndRespondWithError( |
| const GoogleServiceAuthError& error) { |
| WaitForAccessTokenRequestIfNecessary(absl::nullopt); |
| fake_token_service()->IssueErrorForAllPendingRequests(error); |
| } |
| |
| void IdentityTestEnvironment:: |
| WaitForAccessTokenRequestIfNecessaryAndRespondWithError( |
| const CoreAccountId& account_id, |
| const GoogleServiceAuthError& error) { |
| WaitForAccessTokenRequestIfNecessary(account_id); |
| fake_token_service()->IssueErrorForAllPendingRequestsForAccount(account_id, |
| error); |
| } |
| |
| void IdentityTestEnvironment::SetCallbackForNextAccessTokenRequest( |
| base::OnceClosure callback) { |
| on_access_token_requested_callback_ = std::move(callback); |
| } |
| |
| IdentityTestEnvironment::AccessTokenRequestState::AccessTokenRequestState() = |
| default; |
| IdentityTestEnvironment::AccessTokenRequestState::~AccessTokenRequestState() = |
| default; |
| IdentityTestEnvironment::AccessTokenRequestState::AccessTokenRequestState( |
| AccessTokenRequestState&& other) = default; |
| IdentityTestEnvironment::AccessTokenRequestState& |
| IdentityTestEnvironment::AccessTokenRequestState::operator=( |
| AccessTokenRequestState&& other) = default; |
| |
| void IdentityTestEnvironment::OnAccessTokenRequested( |
| const CoreAccountId& account_id, |
| const std::string& consumer_id, |
| const ScopeSet& scopes) { |
| // Post a task to handle this access token request in order to support the |
| // case where the access token request is handled synchronously in the |
| // production code, in which case this callback could be coming in ahead |
| // of an invocation of WaitForAccessTokenRequestIfNecessary() that will be |
| // made in this same iteration of the run loop. |
| base::SequencedTaskRunnerHandle::Get()->PostTask( |
| FROM_HERE, |
| base::BindOnce(&IdentityTestEnvironment::HandleOnAccessTokenRequested, |
| weak_ptr_factory_.GetWeakPtr(), account_id)); |
| } |
| |
| void IdentityTestEnvironment::OnIdentityManagerShutdown( |
| signin::IdentityManager* identity_manager) { |
| // Remove the Observers that IdentityTestEnvironment added during its |
| // initialization. |
| test_identity_manager_observer_.reset(); |
| diagnostics_observation_.Reset(); |
| identity_manager_observation_.Reset(); |
| } |
| |
| void IdentityTestEnvironment::HandleOnAccessTokenRequested( |
| CoreAccountId account_id) { |
| if (on_access_token_requested_callback_) { |
| std::move(on_access_token_requested_callback_).Run(); |
| return; |
| } |
| |
| for (auto it = requesters_.begin(); it != requesters_.end(); ++it) { |
| if (!it->account_id || (it->account_id.value() == account_id)) { |
| if (it->state == AccessTokenRequestState::kAvailable) |
| return; |
| if (it->on_available) |
| std::move(it->on_available).Run(); |
| requesters_.erase(it); |
| return; |
| } |
| } |
| |
| // A requests came in for a request for which we are not waiting. Record |
| // that it's available. |
| requesters_.emplace_back(); |
| requesters_.back().state = AccessTokenRequestState::kAvailable; |
| requesters_.back().account_id = account_id; |
| } |
| |
| void IdentityTestEnvironment::WaitForAccessTokenRequestIfNecessary( |
| absl::optional<CoreAccountId> account_id) { |
| // Handle HandleOnAccessTokenRequested getting called before |
| // WaitForAccessTokenRequestIfNecessary. |
| if (account_id) { |
| for (auto it = requesters_.begin(); it != requesters_.end(); ++it) { |
| if (it->account_id && it->account_id.value() == account_id.value()) { |
| // Can't wait twice for same thing. |
| DCHECK_EQ(AccessTokenRequestState::kAvailable, it->state); |
| requesters_.erase(it); |
| return; |
| } |
| } |
| } else { |
| for (auto it = requesters_.begin(); it != requesters_.end(); ++it) { |
| if (it->state == AccessTokenRequestState::kAvailable) { |
| requesters_.erase(it); |
| return; |
| } |
| } |
| } |
| |
| base::RunLoop run_loop; |
| requesters_.emplace_back(); |
| requesters_.back().state = AccessTokenRequestState::kPending; |
| requesters_.back().account_id = std::move(account_id); |
| requesters_.back().on_available = run_loop.QuitClosure(); |
| run_loop.Run(); |
| } |
| |
| FakeProfileOAuth2TokenService* IdentityTestEnvironment::fake_token_service() { |
| // We can't absolutely guarantee that IdentityTestEnvironment was not given an |
| // IdentityManager that uses a non-fake FakeProfileOAuth2TokenService. If that |
| // ever happens, this will blow up. There doesn't seem to be a better option. |
| return static_cast<FakeProfileOAuth2TokenService*>( |
| identity_manager()->GetTokenService()); |
| } |
| |
| network::TestURLLoaderFactory* |
| IdentityTestEnvironment::test_url_loader_factory() { |
| CHECK(test_url_loader_factory_) |
| << "IdentityTestEnvironment cannot perform cookie-related operations if " |
| "TestURLLoaderFactory isn't set. This may happen if you built your " |
| "IdentityTestEnvironment from an existing profile. Please provide a " |
| "TestURLLoaderFactory by calling SetTestURLLoaderFactory()"; |
| return test_url_loader_factory_; |
| } |
| |
| void IdentityTestEnvironment::UpdateAccountInfoForAccount( |
| AccountInfo account_info) { |
| signin::UpdateAccountInfoForAccount(identity_manager(), account_info); |
| } |
| |
| void IdentityTestEnvironment::ResetToAccountsNotYetLoadedFromDiskState() { |
| fake_token_service()->set_all_credentials_loaded_for_testing(false); |
| } |
| |
| void IdentityTestEnvironment::ReloadAccountsFromDisk() { |
| fake_token_service()->LoadCredentials(CoreAccountId()); |
| } |
| |
| bool IdentityTestEnvironment::IsAccessTokenRequestPending() { |
| return fake_token_service()->GetPendingRequests().size(); |
| } |
| |
| std::vector<IdentityTestEnvironment::PendingRequest> |
| IdentityTestEnvironment::GetPendingAccessTokenRequests() { |
| std::vector<PendingRequest> result; |
| |
| for (const auto& request : fake_token_service()->GetPendingRequests()) { |
| result.emplace_back(request.account_id, request.client_id, |
| request.client_secret, request.scopes); |
| } |
| |
| return result; |
| } |
| |
| void IdentityTestEnvironment::SetFreshnessOfAccountsInGaiaCookie( |
| bool accounts_are_fresh) { |
| signin::SetFreshnessOfAccountsInGaiaCookie(identity_manager(), |
| accounts_are_fresh); |
| } |
| |
| void IdentityTestEnvironment::EnableRemovalOfExtendedAccountInfo() { |
| identity_manager()->GetAccountFetcherService()->EnableAccountRemovalForTest(); |
| } |
| |
| void IdentityTestEnvironment::SimulateSuccessfulFetchOfAccountInfo( |
| const CoreAccountId& account_id, |
| const std::string& email, |
| const std::string& gaia, |
| const std::string& hosted_domain, |
| const std::string& full_name, |
| const std::string& given_name, |
| const std::string& locale, |
| const std::string& picture_url) { |
| signin::SimulateSuccessfulFetchOfAccountInfo( |
| identity_manager(), account_id, email, gaia, hosted_domain, full_name, |
| given_name, locale, picture_url); |
| } |
| |
| void IdentityTestEnvironment::SimulateMergeSessionFailure( |
| const GoogleServiceAuthError& auth_error) { |
| // GaiaCookieManagerService changes the visibility of inherited method |
| // OnMergeSessionFailure from public to private. Cast to a base class |
| // pointer to call the method. |
| static_cast<GaiaAuthConsumer*>( |
| identity_manager()->GetGaiaCookieManagerService()) |
| ->OnMergeSessionFailure(auth_error); |
| } |
| |
| void IdentityTestEnvironment::SetTestURLLoaderFactory( |
| network::TestURLLoaderFactory* test_url_loader_factory) { |
| if (dependencies_owner_) { |
| dependencies_owner_->signin_client()->OverrideTestUrlLoaderFactory( |
| test_url_loader_factory); |
| } else { |
| DCHECK(raw_signin_client_); |
| DCHECK_EQ(test_url_loader_factory->GetSafeWeakWrapper(), |
| raw_signin_client_->GetURLLoaderFactory()) |
| << "SigninClient uses a factory different from the one passed in " |
| "SetTestURLLoaderFactory(). See " |
| "BuildChromeSigninClientWithURLLoader() method for setting up the " |
| "SigninClient properly."; |
| } |
| test_url_loader_factory_ = test_url_loader_factory; |
| } |
| |
| } // namespace signin |