Commit 079b419e authored by Sylvain Defresne's avatar Sylvain Defresne Committed by Commit Bot

Introduce PrimaryAccountMutator.

PrimaryAccountMutator is a new API that wraps the method related to the
mutation of the signed-in state of the primary account. It will become
the recommended API to set and clear the primary account when migrating
to the Identity Service API.

The PrimaryAccountMutatorImpl methods are not implemented yet. They
will be implemented in follow up CLs (and corresponding tests added).
This is done to limit the size of the CLs.

Design document is available at:
https://docs.google.com/document/d/1YVx-SW0VbrAnek69PVxQ1ie71VewcuKvf8JvIzFfuRQ/view

Bug: 889902
Cq-Include-Trybots: luci.chromium.try:ios-simulator-cronet;luci.chromium.try:ios-simulator-full-configs
Change-Id: I2acd1ebdccadfebb855e55f4e9b78c148557ed85
Reviewed-on: https://chromium-review.googlesource.com/c/1286852Reviewed-by: default avatarMihai Sardarescu <msarda@chromium.org>
Reviewed-by: default avatarColin Blundell <blundell@chromium.org>
Commit-Queue: Sylvain Defresne <sdefresne@chromium.org>
Cr-Commit-Position: refs/heads/master@{#602467}
parent 86ae7b06
......@@ -14,6 +14,29 @@
#include "components/keyed_service/core/keyed_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "services/identity/public/cpp/identity_manager.h"
#include "services/identity/public/cpp/primary_account_mutator.h"
#if !defined(OS_CHROMEOS)
#include "services/identity/public/cpp/primary_account_mutator_impl.h"
#endif
namespace {
// Helper function returning a newly constructed PrimaryAccountMutator for
// |profile|. May return null if mutation of the signed-in state is not
// supported on the current platform.
std::unique_ptr<identity::PrimaryAccountMutator> BuildPrimaryAccountMutator(
Profile* profile) {
#if !defined(OS_CHROMEOS)
return std::make_unique<identity::PrimaryAccountMutatorImpl>(
AccountTrackerServiceFactory::GetForProfile(profile),
SigninManagerFactory::GetForProfile(profile));
#else
return nullptr;
#endif
}
} // namespace
// Subclass that wraps IdentityManager in a KeyedService (as IdentityManager is
// a client-side library intended for use by any process, it would be a layering
......@@ -29,7 +52,8 @@ class IdentityManagerWrapper : public KeyedService,
SigninManagerFactory::GetForProfile(profile),
ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
AccountTrackerServiceFactory::GetForProfile(profile),
GaiaCookieManagerServiceFactory::GetForProfile(profile)) {}
GaiaCookieManagerServiceFactory::GetForProfile(profile),
BuildPrimaryAccountMutator(profile)) {}
};
IdentityManagerFactory::IdentityManagerFactory()
......
......@@ -15,6 +15,7 @@
#include "ios/chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "ios/chrome/browser/signin/signin_manager_factory.h"
#include "services/identity/public/cpp/identity_manager.h"
#include "services/identity/public/cpp/primary_account_mutator_impl.h"
// Subclass that wraps IdentityManager in a KeyedService (as IdentityManager is
// a client-side library intended for use by any process, it would be a layering
......@@ -33,7 +34,12 @@ class IdentityManagerWrapper : public KeyedService,
ios::AccountTrackerServiceFactory::GetForBrowserState(
browser_state),
ios::GaiaCookieManagerServiceFactory::GetForBrowserState(
browser_state)) {}
browser_state),
std::make_unique<identity::PrimaryAccountMutatorImpl>(
ios::AccountTrackerServiceFactory::GetForBrowserState(
browser_state),
ios::SigninManagerFactory::GetForBrowserState(browser_state))) {
}
};
IdentityManagerFactory::IdentityManagerFactory()
......
......@@ -15,6 +15,7 @@
#include "ios/web_view/internal/signin/web_view_signin_manager_factory.h"
#include "ios/web_view/internal/web_view_browser_state.h"
#include "services/identity/public/cpp/identity_manager.h"
#include "services/identity/public/cpp/primary_account_mutator_impl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
......@@ -39,7 +40,12 @@ class IdentityManagerWrapper : public KeyedService,
WebViewAccountTrackerServiceFactory::GetForBrowserState(
browser_state),
WebViewGaiaCookieManagerServiceFactory::GetForBrowserState(
browser_state)) {}
browser_state),
std::make_unique<identity::PrimaryAccountMutatorImpl>(
WebViewAccountTrackerServiceFactory::GetForBrowserState(
browser_state),
WebViewSigninManagerFactory::GetForBrowserState(
browser_state))) {}
};
WebViewIdentityManagerFactory::WebViewIdentityManagerFactory()
......
......@@ -12,8 +12,16 @@ source_set("cpp") {
"identity_manager.h",
"primary_account_access_token_fetcher.cc",
"primary_account_access_token_fetcher.h",
"primary_account_mutator.h",
]
if (!is_chromeos) {
sources += [
"primary_account_mutator_impl.cc",
"primary_account_mutator_impl.h",
]
}
configs += [ "//build/config/compiler:wexit_time_destructors" ]
public_deps = [
......
......@@ -5,6 +5,7 @@
#include "services/identity/public/cpp/identity_manager.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "services/identity/public/cpp/primary_account_mutator.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace identity {
......@@ -47,11 +48,13 @@ IdentityManager::IdentityManager(
SigninManagerBase* signin_manager,
ProfileOAuth2TokenService* token_service,
AccountTrackerService* account_tracker_service,
GaiaCookieManagerService* gaia_cookie_manager_service)
GaiaCookieManagerService* gaia_cookie_manager_service,
std::unique_ptr<PrimaryAccountMutator> primary_account_mutator)
: signin_manager_(signin_manager),
token_service_(token_service),
account_tracker_service_(account_tracker_service),
gaia_cookie_manager_service_(gaia_cookie_manager_service) {
gaia_cookie_manager_service_(gaia_cookie_manager_service),
primary_account_mutator_(std::move(primary_account_mutator)) {
signin_manager_->AddObserver(this);
token_service_->AddDiagnosticsObserver(this);
token_service_->AddObserver(this);
......@@ -185,6 +188,10 @@ void IdentityManager::RemoveAccessTokenFromCache(
token_service_->InvalidateAccessToken(account_id, scopes, access_token);
}
PrimaryAccountMutator* IdentityManager::GetPrimaryAccountMutator() {
return primary_account_mutator_.get();
}
void IdentityManager::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
}
......
......@@ -44,6 +44,8 @@ class MultiProfileDownloadNotificationTest;
namespace identity {
class PrimaryAccountMutator;
// Gives access to information about the user's Google identities. See
// ./README.md for detailed documentation.
class IdentityManager : public SigninManagerBase::Observer,
......@@ -127,10 +129,12 @@ class IdentityManager : public SigninManagerBase::Observer,
const OAuth2TokenService::ScopeSet& scopes) {}
};
IdentityManager(SigninManagerBase* signin_manager,
ProfileOAuth2TokenService* token_service,
AccountTrackerService* account_tracker_service,
GaiaCookieManagerService* gaia_cookie_manager_service);
IdentityManager(
SigninManagerBase* signin_manager,
ProfileOAuth2TokenService* token_service,
AccountTrackerService* account_tracker_service,
GaiaCookieManagerService* gaia_cookie_manager_service,
std::unique_ptr<PrimaryAccountMutator> primary_account_mutator);
~IdentityManager() override;
// Provides access to the extended information of the user's primary account.
......@@ -246,6 +250,11 @@ class IdentityManager : public SigninManagerBase::Observer,
const OAuth2TokenService::ScopeSet& scopes,
const std::string& access_token);
// Returns pointer to the object used to change the signed-in state of the
// primary account, if supported on the current platform. Otherwise, returns
// null.
PrimaryAccountMutator* GetPrimaryAccountMutator();
// Methods to register or remove observers.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
......@@ -320,6 +329,10 @@ class IdentityManager : public SigninManagerBase::Observer,
AccountTrackerService* account_tracker_service_;
GaiaCookieManagerService* gaia_cookie_manager_service_;
// PrimaryAccountMutator instance. May be null if mutation of the primary
// account state is not supported on the current platform.
std::unique_ptr<PrimaryAccountMutator> primary_account_mutator_;
// Lists of observers.
// Makes sure lists are empty on destruction.
base::ObserverList<Observer, true>::Unchecked observer_list_;
......
......@@ -20,6 +20,7 @@
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_token_service_delegate.h"
#include "services/identity/public/cpp/identity_test_utils.h"
#include "services/identity/public/cpp/primary_account_mutator.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -464,9 +465,9 @@ class IdentityManagerTest : public testing::Test {
identity_manager_diagnostics_observer_.reset();
identity_manager_.reset();
identity_manager_.reset(
new IdentityManager(signin_manager_.get(), &token_service_,
&account_tracker_, &gaia_cookie_manager_service_));
identity_manager_.reset(new IdentityManager(
signin_manager_.get(), &token_service_, &account_tracker_,
&gaia_cookie_manager_service_, nullptr));
identity_manager_observer_.reset(
new TestIdentityManagerObserver(identity_manager_.get()));
identity_manager_diagnostics_observer_.reset(
......
......@@ -4,12 +4,19 @@
#include "services/identity/public/cpp/identity_test_environment.h"
#include "build/build_config.h"
#include "base/run_loop.h"
#include "components/signin/core/browser/profile_management_switches.h"
#include "components/signin/core/browser/test_signin_client.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "google_apis/gaia/oauth2_access_token_consumer.h"
#include "services/identity/public/cpp/identity_test_utils.h"
#include "services/identity/public/cpp/primary_account_mutator.h"
#if !defined(OS_CHROMEOS)
#include "services/identity/public/cpp/primary_account_mutator_impl.h"
#endif
namespace identity {
......@@ -162,9 +169,18 @@ IdentityTestEnvironment::IdentityTestEnvironment(
if (identity_manager) {
raw_identity_manager_ = identity_manager;
} else {
#if !defined(OS_CHROMEOS)
std::unique_ptr<PrimaryAccountMutator> account_mutator =
std::make_unique<PrimaryAccountMutatorImpl>(
account_tracker_service_,
static_cast<SigninManager*>(signin_manager_));
#else
std::unique_ptr<PrimaryAccountMutator> account_mutator;
#endif
owned_identity_manager_ = std::make_unique<IdentityManager>(
signin_manager_, token_service_, account_tracker_service_,
gaia_cookie_manager_service_);
gaia_cookie_manager_service_, std::move(account_mutator));
}
this->identity_manager()->AddDiagnosticsObserver(this);
......
// Copyright 2018 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 SERVICES_IDENTITY_PUBLIC_CPP_PRIMARY_ACCOUNT_MUTATOR_H_
#define SERVICES_IDENTITY_PUBLIC_CPP_PRIMARY_ACCOUNT_MUTATOR_H_
#include <string>
#include "base/callback_forward.h"
#include "components/signin/core/browser/signin_metrics.h"
struct AccountInfo;
namespace identity {
// PrimaryAccountMutator is the interface to set and clear the primary account
// (see IdentityManager for more information).
//
// It is a pure interface that has concrete implementation on platform that
// support changing the signed-in state during the lifetime of the application.
// On other platforms, there is no implementation, and no instance will be
// available at runtime (thus accessors may return null).
class PrimaryAccountMutator {
public:
// Represents the options for handling the accounts known to the
// IdentityManager upon calling ClearPrimaryAccount().
enum class ClearAccountsAction {
kDefault, // Default action based on internal policy.
kKeepAll, // Keep all accounts.
kRemoveAll, // Remove all accounts.
};
PrimaryAccountMutator() = default;
virtual ~PrimaryAccountMutator() = default;
// PrimaryAccountMutator is non-copyable, non-moveable.
PrimaryAccountMutator(PrimaryAccountMutator&& other) = delete;
PrimaryAccountMutator const& operator=(PrimaryAccountMutator&& other) =
delete;
PrimaryAccountMutator(const PrimaryAccountMutator& other) = delete;
PrimaryAccountMutator const& operator=(const PrimaryAccountMutator& other) =
delete;
// Marks the account with |account_id| as the primary account, and returns
// whether the operation succeeded or not. To succeed, this requires that:
// - setting the primary account is allowed,
// - the account username is allowed by policy,
// - the account is known by the IdentityManager.
virtual bool SetPrimaryAccount(const std::string& account_id) = 0;
// Clears the primary account. Depending on |action|, the other accounts
// known to the IdentityManager may be deleted.
virtual void ClearPrimaryAccount(
ClearAccountsAction action,
signin_metrics::ProfileSignout source_metric,
signin_metrics::SignoutDelete delete_metric) = 0;
// Getter and setter that allow enabling or disabling the ability to set the
// primary account.
virtual bool IsSettingPrimaryAccountAllowed() const = 0;
virtual void SetSettingPrimaryAccountAllowed(bool allowed) = 0;
// Getter and setter that allow enabling or disabling the ability to clear
// the primary account.
virtual bool IsClearingPrimaryAccountAllowed() const = 0;
virtual void SetClearingPrimaryAccountAllowed(bool allowed) = 0;
// Sets the pattern controlling which user names are allowed when setting
// the primary account.
virtual void SetAllowedPrimaryAccountPattern(const std::string& pattern) = 0;
// All the following APIs are for use by legacy code only. They are deprecated
// and should not be used when writing new code. They will be removed when the
// old sign-in workflow has been turned down.
// Attempts to sign-in user with a given refresh token and account. If it is
// defined, |callback| should invoke either ClearPrimaryAccount() or
// LegacyCompletePendingPrimaryAccountSignin() to either cancel or continue
// the in progress sign-in (legacy, pre-DICE workflow).
virtual void LegacyStartSigninWithRefreshTokenForPrimaryAccount(
const std::string& refresh_token,
const std::string& gaia_id,
const std::string& username,
const std::string& password,
base::RepeatingCallback<void(const std::string&)> callback) = 0;
// Complete the in-process sign-in (legacy, pre-DICE workflow).
virtual void LegacyCompletePendingPrimaryAccountSignin() = 0;
// If applicable, merges the signed-in account into the cookie jar (legacy,
// pre-DICE workflow).
virtual void LegacyMergeSigninCredentialIntoCookieJar() = 0;
// Returns true if there is a sign-in in progress (legacy, pre-DICE workflow).
virtual bool LegacyIsPrimaryAccountAuthInProgress() const = 0;
// If an authentication is in progress, returns the AccountInfo for the
// account being authenticated. Returns an empty AccountInfo if no auth is
// in progress (legacy, pre-DICE workflow).
virtual AccountInfo LegacyPrimaryAccountForAuthInProgress() const = 0;
// Copy auth credentials from the other PrimaryAccountMutator to this one.
// Used when creating a new profile during the sign-in process to transfer
// the in-progress credential information to the new profile (legacy, pre-
// DICE workflow).
virtual void LegacyCopyCredentialsFrom(
const PrimaryAccountMutator& source) = 0;
};
} // namespace identity
#endif // SERVICES_IDENTITY_PUBLIC_CPP_PRIMARY_ACCOUNT_MUTATOR_H_
// Copyright 2018 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 "services/identity/public/cpp/primary_account_mutator_impl.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/signin_manager.h"
namespace identity {
PrimaryAccountMutatorImpl::PrimaryAccountMutatorImpl(
AccountTrackerService* account_tracker,
SigninManager* signin_manager)
: account_tracker_(account_tracker), signin_manager_(signin_manager) {
DCHECK(account_tracker_);
DCHECK(signin_manager_);
}
PrimaryAccountMutatorImpl::~PrimaryAccountMutatorImpl() {}
bool PrimaryAccountMutatorImpl::SetPrimaryAccount(
const std::string& account_id) {
NOTIMPLEMENTED();
return false;
}
void PrimaryAccountMutatorImpl::ClearPrimaryAccount(
ClearAccountsAction action,
signin_metrics::ProfileSignout source_metric,
signin_metrics::SignoutDelete delete_metric) {
NOTIMPLEMENTED();
}
bool PrimaryAccountMutatorImpl::IsSettingPrimaryAccountAllowed() const {
NOTIMPLEMENTED();
return false;
}
void PrimaryAccountMutatorImpl::SetSettingPrimaryAccountAllowed(bool allowed) {
NOTIMPLEMENTED();
}
bool PrimaryAccountMutatorImpl::IsClearingPrimaryAccountAllowed() const {
NOTIMPLEMENTED();
return false;
}
void PrimaryAccountMutatorImpl::SetClearingPrimaryAccountAllowed(bool allowed) {
NOTIMPLEMENTED();
}
void PrimaryAccountMutatorImpl::SetAllowedPrimaryAccountPattern(
const std::string& pattern) {
NOTIMPLEMENTED();
}
void PrimaryAccountMutatorImpl::
LegacyStartSigninWithRefreshTokenForPrimaryAccount(
const std::string& refresh_token,
const std::string& gaia_id,
const std::string& username,
const std::string& password,
base::RepeatingCallback<void(const std::string&)> callback) {
NOTIMPLEMENTED();
}
void PrimaryAccountMutatorImpl::LegacyCompletePendingPrimaryAccountSignin() {
NOTIMPLEMENTED();
}
void PrimaryAccountMutatorImpl::LegacyMergeSigninCredentialIntoCookieJar() {
NOTIMPLEMENTED();
}
bool PrimaryAccountMutatorImpl::LegacyIsPrimaryAccountAuthInProgress() const {
NOTIMPLEMENTED();
return false;
}
AccountInfo PrimaryAccountMutatorImpl::LegacyPrimaryAccountForAuthInProgress()
const {
NOTIMPLEMENTED();
return AccountInfo{};
}
void PrimaryAccountMutatorImpl::LegacyCopyCredentialsFrom(
const PrimaryAccountMutator& source) {
NOTIMPLEMENTED();
}
} // namespace identity
// Copyright 2018 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 SERVICES_IDENTITY_PUBLIC_CPP_PRIMARY_ACCOUNT_MUTATOR_IMPL_H_
#define SERVICES_IDENTITY_PUBLIC_CPP_PRIMARY_ACCOUNT_MUTATOR_IMPL_H_
#include "services/identity/public/cpp/primary_account_mutator.h"
class AccountTrackerService;
class SigninManager;
namespace identity {
// Concrete implementation of PrimaryAccountMutator that is based on the
// SigninManager API. It is supported on all platform except Chrome OS.
class PrimaryAccountMutatorImpl : public PrimaryAccountMutator {
public:
PrimaryAccountMutatorImpl(AccountTrackerService* account_tracker,
SigninManager* signin_manager);
~PrimaryAccountMutatorImpl() override;
// PrimaryAccountMutator implementation.
bool SetPrimaryAccount(const std::string& account_id) override;
void ClearPrimaryAccount(
ClearAccountsAction action,
signin_metrics::ProfileSignout source_metric,
signin_metrics::SignoutDelete delete_metric) override;
bool IsSettingPrimaryAccountAllowed() const override;
void SetSettingPrimaryAccountAllowed(bool allowed) override;
bool IsClearingPrimaryAccountAllowed() const override;
void SetClearingPrimaryAccountAllowed(bool allowed) override;
void SetAllowedPrimaryAccountPattern(const std::string& pattern) override;
void LegacyStartSigninWithRefreshTokenForPrimaryAccount(
const std::string& refresh_token,
const std::string& gaia_id,
const std::string& username,
const std::string& password,
base::RepeatingCallback<void(const std::string&)> callback) override;
void LegacyCompletePendingPrimaryAccountSignin() override;
void LegacyMergeSigninCredentialIntoCookieJar() override;
bool LegacyIsPrimaryAccountAuthInProgress() const override;
AccountInfo LegacyPrimaryAccountForAuthInProgress() const override;
void LegacyCopyCredentialsFrom(const PrimaryAccountMutator& source) override;
private:
// Pointers to the services used by the PrimaryAccountMutatorImpl. They
// *must* outlive this instance.
AccountTrackerService* account_tracker_ = nullptr;
SigninManager* signin_manager_ = nullptr;
};
} // namespace identity
#endif // SERVICES_IDENTITY_PUBLIC_CPP_PRIMARY_ACCOUNT_MUTATOR_IMPL_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment