Commit 7e830210 authored by Jochen Eisinger's avatar Jochen Eisinger Committed by Commit Bot

Delete CryptAuthAccessTokenFetcher

Replaces the two distinct implementations of CryptAuthAccessTokenFetcher with
having CryptAuthClientImpl directly construct a PAATF. Those two
implementations are each identical in functionality to using a PAATF in
kImmediate mode: the first simply wraps PAATF used in kImmediate mode, while
the second just makes an immediate request on ProfileOAuth2TokenService.

Also eliminates a //chromeos implementation of CryptAuthClientFactory, as that
implementation is now identical with the //components/cryptauth implementation,
which is used instead in the //chromeos context.

BUG=809433
R=blundell@chromium.org,khorimoto@chromium.org

Change-Id: I93ee9e736395bc71a1e741fc45d027ff32787536
Reviewed-on: https://chromium-review.googlesource.com/1107715
Commit-Queue: Jochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarColin Blundell <blundell@chromium.org>
Reviewed-by: default avatarTim Song <tengs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#572505}
parent e95b6ce4
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "chrome/browser/chromeos/cryptauth/gcm_device_info_provider_impl.h" #include "chrome/browser/chromeos/cryptauth/gcm_device_info_provider_impl.h"
#include "chrome/browser/gcm/gcm_profile_service_factory.h" #include "chrome/browser/gcm/gcm_profile_service_factory.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
...@@ -46,8 +47,7 @@ namespace { ...@@ -46,8 +47,7 @@ namespace {
std::unique_ptr<cryptauth::CryptAuthClientFactory> std::unique_ptr<cryptauth::CryptAuthClientFactory>
CreateCryptAuthClientFactoryImpl(Profile* profile) { CreateCryptAuthClientFactoryImpl(Profile* profile) {
return std::make_unique<cryptauth::CryptAuthClientFactoryImpl>( return std::make_unique<cryptauth::CryptAuthClientFactoryImpl>(
ProfileOAuth2TokenServiceFactory::GetForProfile(profile), IdentityManagerFactory::GetForProfile(profile),
SigninManagerFactory::GetForProfile(profile)->GetAuthenticatedAccountId(),
profile->GetRequestContext(), profile->GetRequestContext(),
cryptauth::device_classifier_util::GetDeviceClassifier()); cryptauth::device_classifier_util::GetDeviceClassifier());
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "chrome/browser/chromeos/cryptauth/chrome_cryptauth_service.h" #include "chrome/browser/chromeos/cryptauth/chrome_cryptauth_service.h"
#include "chrome/browser/gcm/gcm_profile_service_factory.h" #include "chrome/browser/gcm/gcm_profile_service_factory.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_manager_factory.h"
#include "chromeos/chromeos_features.h" #include "chromeos/chromeos_features.h"
...@@ -32,6 +33,7 @@ ChromeCryptAuthServiceFactory::ChromeCryptAuthServiceFactory() ...@@ -32,6 +33,7 @@ ChromeCryptAuthServiceFactory::ChromeCryptAuthServiceFactory()
: BrowserContextKeyedServiceFactory( : BrowserContextKeyedServiceFactory(
"CryptAuthService", "CryptAuthService",
BrowserContextDependencyManager::GetInstance()) { BrowserContextDependencyManager::GetInstance()) {
DependsOn(IdentityManagerFactory::GetInstance());
DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
DependsOn(SigninManagerFactory::GetInstance()); DependsOn(SigninManagerFactory::GetInstance());
DependsOn(gcm::GCMProfileServiceFactory::GetInstance()); DependsOn(gcm::GCMProfileServiceFactory::GetInstance());
......
...@@ -10,12 +10,8 @@ assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos") ...@@ -10,12 +10,8 @@ assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
static_library("device_sync") { static_library("device_sync") {
sources = [ sources = [
"cryptauth_client_factory_impl.cc",
"cryptauth_client_factory_impl.h",
"cryptauth_enroller_factory_impl.cc", "cryptauth_enroller_factory_impl.cc",
"cryptauth_enroller_factory_impl.h", "cryptauth_enroller_factory_impl.h",
"cryptauth_token_fetcher_impl.cc",
"cryptauth_token_fetcher_impl.h",
"device_sync_base.cc", "device_sync_base.cc",
"device_sync_base.h", "device_sync_base.h",
"device_sync_impl.cc", "device_sync_impl.cc",
...@@ -75,7 +71,6 @@ source_set("unit_tests") { ...@@ -75,7 +71,6 @@ source_set("unit_tests") {
testonly = true testonly = true
sources = [ sources = [
"cryptauth_token_fetcher_impl_unittest.cc",
"device_sync_service_unittest.cc", "device_sync_service_unittest.cc",
] ]
......
// 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 "chromeos/services/device_sync/cryptauth_client_factory_impl.h"
#include "chromeos/services/device_sync/cryptauth_token_fetcher_impl.h"
#include "components/cryptauth/cryptauth_client_impl.h"
namespace chromeos {
namespace device_sync {
CryptAuthClientFactoryImpl::CryptAuthClientFactoryImpl(
identity::IdentityManager* identity_manager,
scoped_refptr<net::URLRequestContextGetter> url_request_context,
const cryptauth::DeviceClassifier& device_classifier)
: identity_manager_(identity_manager),
url_request_context_(std::move(url_request_context)),
device_classifier_(device_classifier) {}
CryptAuthClientFactoryImpl::~CryptAuthClientFactoryImpl() = default;
std::unique_ptr<cryptauth::CryptAuthClient>
CryptAuthClientFactoryImpl::CreateInstance() {
return std::make_unique<cryptauth::CryptAuthClientImpl>(
std::make_unique<cryptauth::CryptAuthApiCallFlow>(),
std::make_unique<CryptAuthAccessTokenFetcherImpl>(identity_manager_),
url_request_context_, device_classifier_);
}
} // namespace device_sync
} // namespace chromeos
// 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 CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_CLIENT_FACTORY_IMPL_H_
#define CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_CLIENT_FACTORY_IMPL_H_
#include "base/memory/ref_counted.h"
#include "components/cryptauth/cryptauth_client.h"
#include "components/cryptauth/proto/cryptauth_api.pb.h"
namespace identity {
class IdentityManager;
} // namespace identity
namespace net {
class URLRequestContextGetter;
} // namespace net
namespace chromeos {
namespace device_sync {
// CryptAuthClientFactory implementation which utilizes IdentityManager.
class CryptAuthClientFactoryImpl : public cryptauth::CryptAuthClientFactory {
public:
CryptAuthClientFactoryImpl(
identity::IdentityManager* identity_manager,
scoped_refptr<net::URLRequestContextGetter> url_request_context,
const cryptauth::DeviceClassifier& device_classifier);
~CryptAuthClientFactoryImpl() override;
// cryptauth::CryptAuthClientFactory:
std::unique_ptr<cryptauth::CryptAuthClient> CreateInstance() override;
private:
identity::IdentityManager* identity_manager_;
const scoped_refptr<net::URLRequestContextGetter> url_request_context_;
const cryptauth::DeviceClassifier device_classifier_;
};
} // namespace device_sync
} // namespace chromeos
#endif // CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_CLIENT_FACTORY_IMPL_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 "chromeos/services/device_sync/cryptauth_token_fetcher_impl.h"
#include <set>
#include "services/identity/public/cpp/identity_manager.h"
namespace chromeos {
namespace device_sync {
namespace {
const char kIdentityManagerConsumerName[] = "multi_device_service";
const char kCryptAuthApiScope[] = "https://www.googleapis.com/auth/cryptauth";
} // namespace
CryptAuthAccessTokenFetcherImpl::CryptAuthAccessTokenFetcherImpl(
identity::IdentityManager* identity_manager)
: identity_manager_(identity_manager), weak_ptr_factory_(this) {}
CryptAuthAccessTokenFetcherImpl::~CryptAuthAccessTokenFetcherImpl() {
// If any callbacks are still pending when the object is deleted, run them
// now, passing an empty string to indicate failure. This ensures that no
// callbacks are left hanging forever.
InvokeThenClearPendingCallbacks(std::string());
}
void CryptAuthAccessTokenFetcherImpl::FetchAccessToken(
const AccessTokenCallback& callback) {
pending_callbacks_.emplace_back(callback);
// If the token is already being fetched, continue waiting for it.
if (access_token_fetcher_)
return;
const OAuth2TokenService::ScopeSet kScopes{kCryptAuthApiScope};
access_token_fetcher_ =
identity_manager_->CreateAccessTokenFetcherForPrimaryAccount(
kIdentityManagerConsumerName, kScopes,
base::BindOnce(&CryptAuthAccessTokenFetcherImpl::OnAccessTokenFetched,
weak_ptr_factory_.GetWeakPtr()),
identity::PrimaryAccountAccessTokenFetcher::Mode::kImmediate);
}
void CryptAuthAccessTokenFetcherImpl::InvokeThenClearPendingCallbacks(
const std::string& access_token) {
for (auto& callback : pending_callbacks_)
callback.Run(access_token);
pending_callbacks_.clear();
}
void CryptAuthAccessTokenFetcherImpl::OnAccessTokenFetched(
GoogleServiceAuthError error,
std::string access_token) {
access_token_fetcher_.reset();
InvokeThenClearPendingCallbacks(
error == GoogleServiceAuthError::AuthErrorNone() ? access_token
: std::string());
}
} // namespace device_sync
} // namespace chromeos
// 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 CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_TOKEN_FETCHER_IMPL_H_
#define CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_TOKEN_FETCHER_IMPL_H_
#include <memory>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "components/cryptauth/cryptauth_access_token_fetcher.h"
#include "google_apis/gaia/google_service_auth_error.h"
namespace identity {
class IdentityManager;
class PrimaryAccountAccessTokenFetcher;
} // namespace identity
namespace chromeos {
namespace device_sync {
// CryptAuthAccessTokenFetcher implementation which utilizes IdentityManager.
class CryptAuthAccessTokenFetcherImpl
: public cryptauth::CryptAuthAccessTokenFetcher {
public:
explicit CryptAuthAccessTokenFetcherImpl(
identity::IdentityManager* identity_manager);
~CryptAuthAccessTokenFetcherImpl() override;
// cryptauth::CryptAuthAccessTokenFetcher:
void FetchAccessToken(const AccessTokenCallback& callback) override;
private:
void InvokeThenClearPendingCallbacks(const std::string& access_token);
void OnAccessTokenFetched(GoogleServiceAuthError error,
std::string access_token);
identity::IdentityManager* identity_manager_;
std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher>
access_token_fetcher_;
std::vector<AccessTokenCallback> pending_callbacks_;
base::WeakPtrFactory<CryptAuthAccessTokenFetcherImpl> weak_ptr_factory_;
};
} // namespace device_sync
} // namespace chromeos
#endif // CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_TOKEN_FETCHER_IMPL_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 "chromeos/services/device_sync/cryptauth_token_fetcher_impl.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "services/identity/public/cpp/identity_test_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace device_sync {
namespace {
const char kAccessToken[] = "access_token";
const char kTestEmail[] = "example@gmail.com";
} // namespace
class DeviceSyncCryptAuthAccessTokenFetcherImplTest : public testing::Test {
protected:
DeviceSyncCryptAuthAccessTokenFetcherImplTest() {}
void SetUp() override {
identity_test_environment_ =
std::make_unique<identity::IdentityTestEnvironment>();
identity_test_environment_->MakePrimaryAccountAvailable(kTestEmail);
token_fetcher_ = std::make_unique<CryptAuthAccessTokenFetcherImpl>(
identity_test_environment_->identity_manager());
}
void TearDown() override {
// Deleting the object should not result in any additional tokens provided.
token_fetcher_.reset();
EXPECT_EQ(nullptr, GetTokenAndReset());
EXPECT_TRUE(on_access_token_received_callback_.is_null());
}
void set_on_access_token_received_callback(
base::OnceClosure on_access_token_received_callback) {
EXPECT_TRUE(on_access_token_received_callback_.is_null());
on_access_token_received_callback_ =
std::move(on_access_token_received_callback);
}
void StartFetchingAccessToken() {
token_fetcher_->FetchAccessToken(base::Bind(
&DeviceSyncCryptAuthAccessTokenFetcherImplTest::OnAccessTokenFetched,
base::Unretained(this)));
}
void OnAccessTokenFetched(const std::string& access_token) {
last_access_token_ = std::make_unique<std::string>(access_token);
if (!on_access_token_received_callback_.is_null())
std::move(on_access_token_received_callback_).Run();
}
std::unique_ptr<std::string> GetTokenAndReset() {
return std::move(last_access_token_);
}
const base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<std::string> last_access_token_;
base::OnceClosure on_access_token_received_callback_;
std::unique_ptr<identity::IdentityTestEnvironment> identity_test_environment_;
std::unique_ptr<CryptAuthAccessTokenFetcherImpl> token_fetcher_;
private:
DISALLOW_COPY_AND_ASSIGN(DeviceSyncCryptAuthAccessTokenFetcherImplTest);
};
TEST_F(DeviceSyncCryptAuthAccessTokenFetcherImplTest, TestSuccess) {
base::RunLoop run_loop;
set_on_access_token_received_callback(run_loop.QuitClosure());
// Start fetching the token. Nothing should be returned yet since the message
// loop has not been run.
StartFetchingAccessToken();
EXPECT_EQ(nullptr, GetTokenAndReset());
identity_test_environment_
->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
kAccessToken, base::Time::Max() /* expiration */);
// Run the request and confirm that the access token was returned.
run_loop.Run();
EXPECT_EQ(kAccessToken, *GetTokenAndReset());
}
TEST_F(DeviceSyncCryptAuthAccessTokenFetcherImplTest, TestFailure) {
base::RunLoop run_loop;
set_on_access_token_received_callback(run_loop.QuitClosure());
// Start fetching the token. Nothing should be returned yet since the message
// loop has not been run.
StartFetchingAccessToken();
EXPECT_EQ(nullptr, GetTokenAndReset());
identity_test_environment_
->WaitForAccessTokenRequestIfNecessaryAndRespondWithError(
GoogleServiceAuthError(
GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS));
// Run the request and confirm that an empty string was returned, signifying a
// failure to fetch the token.
run_loop.Run();
EXPECT_EQ(std::string(), *GetTokenAndReset());
}
TEST_F(DeviceSyncCryptAuthAccessTokenFetcherImplTest,
TestDeletedBeforeOperationFinished) {
StartFetchingAccessToken();
EXPECT_EQ(nullptr, GetTokenAndReset());
// Deleting the object should result in the callback being invoked with an
// empty string (indicating failure).
token_fetcher_.reset();
EXPECT_EQ(std::string(), *GetTokenAndReset());
}
} // namespace device_sync
} // namespace chromeos
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
#include "base/optional.h" #include "base/optional.h"
#include "base/time/default_clock.h" #include "base/time/default_clock.h"
#include "chromeos/components/proximity_auth/logging/logging.h" #include "chromeos/components/proximity_auth/logging/logging.h"
#include "chromeos/services/device_sync/cryptauth_client_factory_impl.h"
#include "chromeos/services/device_sync/cryptauth_enroller_factory_impl.h" #include "chromeos/services/device_sync/cryptauth_enroller_factory_impl.h"
#include "components/cryptauth/cryptauth_client_impl.h"
#include "components/cryptauth/cryptauth_device_manager_impl.h" #include "components/cryptauth/cryptauth_device_manager_impl.h"
#include "components/cryptauth/cryptauth_enrollment_manager_impl.h" #include "components/cryptauth/cryptauth_enrollment_manager_impl.h"
#include "components/cryptauth/cryptauth_gcm_manager_impl.h" #include "components/cryptauth/cryptauth_gcm_manager_impl.h"
...@@ -324,9 +324,10 @@ void DeviceSyncImpl::InitializeCryptAuthManagementObjects() { ...@@ -324,9 +324,10 @@ void DeviceSyncImpl::InitializeCryptAuthManagementObjects() {
gcm_driver_, pref_service_.get()); gcm_driver_, pref_service_.get());
cryptauth_gcm_manager_->StartListening(); cryptauth_gcm_manager_->StartListening();
cryptauth_client_factory_ = std::make_unique<CryptAuthClientFactoryImpl>( cryptauth_client_factory_ =
identity_manager_, url_request_context_, std::make_unique<cryptauth::CryptAuthClientFactoryImpl>(
cryptauth::device_classifier_util::GetDeviceClassifier()); identity_manager_, url_request_context_,
cryptauth::device_classifier_util::GetDeviceClassifier());
// Initialize |crypauth_device_manager_| and start observing. Start() is not // Initialize |crypauth_device_manager_| and start observing. Start() is not
// called yet since the device has not completed enrollment. // called yet since the device has not completed enrollment.
......
...@@ -16,9 +16,6 @@ static_library("cryptauth") { ...@@ -16,9 +16,6 @@ static_library("cryptauth") {
"background_eid_generator.h", "background_eid_generator.h",
"connection.cc", "connection.cc",
"connection.h", "connection.h",
"cryptauth_access_token_fetcher.h",
"cryptauth_access_token_fetcher_impl.cc",
"cryptauth_access_token_fetcher_impl.h",
"cryptauth_api_call_flow.cc", "cryptauth_api_call_flow.cc",
"cryptauth_api_call_flow.h", "cryptauth_api_call_flow.h",
"cryptauth_client.h", "cryptauth_client.h",
...@@ -112,6 +109,7 @@ static_library("cryptauth") { ...@@ -112,6 +109,7 @@ static_library("cryptauth") {
"//crypto", "//crypto",
"//google_apis", "//google_apis",
"//net", "//net",
"//services/identity/public/cpp",
] ]
public_deps = [ public_deps = [
...@@ -185,7 +183,6 @@ source_set("unit_tests") { ...@@ -185,7 +183,6 @@ source_set("unit_tests") {
sources = [ sources = [
"background_eid_generator_unittest.cc", "background_eid_generator_unittest.cc",
"connection_unittest.cc", "connection_unittest.cc",
"cryptauth_access_token_fetcher_impl_unittest.cc",
"cryptauth_api_call_flow_unittest.cc", "cryptauth_api_call_flow_unittest.cc",
"cryptauth_client_impl_unittest.cc", "cryptauth_client_impl_unittest.cc",
"cryptauth_device_manager_impl_unittest.cc", "cryptauth_device_manager_impl_unittest.cc",
...@@ -220,6 +217,7 @@ source_set("unit_tests") { ...@@ -220,6 +217,7 @@ source_set("unit_tests") {
"//components/prefs:test_support", "//components/prefs:test_support",
"//google_apis:test_support", "//google_apis:test_support",
"//net:test_support", "//net:test_support",
"//services/identity/public/cpp:test_support",
"//testing/gtest", "//testing/gtest",
] ]
} }
...@@ -12,5 +12,6 @@ include_rules = [ ...@@ -12,5 +12,6 @@ include_rules = [
"+device/bluetooth", "+device/bluetooth",
"+google_apis", "+google_apis",
"+net", "+net",
"+services/identity/public/cpp",
"+third_party/cros_system_api/dbus/service_constants.h", "+third_party/cros_system_api/dbus/service_constants.h",
] ]
// Copyright 2014 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 COMPONENTS_CRYPTAUTH_CRYPTAUTH_ACCESS_TOKEN_FETCHER_H_
#define COMPONENTS_CRYPTAUTH_CRYPTAUTH_ACCESS_TOKEN_FETCHER_H_
#include <string>
#include "base/callback_forward.h"
namespace cryptauth {
// Simple interface for fetching the OAuth2 access token that authorizes
// CryptAuth API calls. Do not reuse this after calling FetchAccessToken();
// instead, create a new instance.
class CryptAuthAccessTokenFetcher {
public:
virtual ~CryptAuthAccessTokenFetcher() {}
// Fetches the access token asynchronously, invoking the callback upon
// completion. If the fetch fails, the callback will be invoked with an empty
// string.
typedef base::Callback<void(const std::string&)> AccessTokenCallback;
virtual void FetchAccessToken(const AccessTokenCallback& callback) = 0;
};
} // namespace cryptauth
#endif // COMPONENTS_CRYPTAUTH_CRYPTAUTH_ACCESS_TOKEN_FETCHER_H_
// Copyright 2014 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/cryptauth/cryptauth_access_token_fetcher_impl.h"
namespace cryptauth {
namespace {
// Returns the set of OAuth2 scopes that CryptAuth uses.
OAuth2TokenService::ScopeSet GetScopes() {
OAuth2TokenService::ScopeSet scopes;
scopes.insert("https://www.googleapis.com/auth/cryptauth");
return scopes;
}
} // namespace
CryptAuthAccessTokenFetcherImpl::CryptAuthAccessTokenFetcherImpl(
OAuth2TokenService* token_service,
const std::string& account_id)
: OAuth2TokenService::Consumer("cryptauth_access_token_fetcher"),
token_service_(token_service),
account_id_(account_id),
fetch_started_(false) {
}
CryptAuthAccessTokenFetcherImpl::~CryptAuthAccessTokenFetcherImpl() {
}
void CryptAuthAccessTokenFetcherImpl::FetchAccessToken(
const AccessTokenCallback& callback) {
if (fetch_started_) {
LOG(WARNING) << "Create an instance for each token fetched. Do not reuse.";
callback.Run(std::string());
return;
}
fetch_started_ = true;
callback_ = callback;
// This request will return a cached result if it is available, saving a
// network round trip every time we fetch the access token.
token_request_ = token_service_->StartRequest(account_id_, GetScopes(), this);
}
void CryptAuthAccessTokenFetcherImpl::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) {
callback_.Run(access_token);
}
void CryptAuthAccessTokenFetcherImpl::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
callback_.Run(std::string());
}
} // namespace cryptauth
// Copyright 2014 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 COMPONENTS_CRYPTAUTH_CRYPTAUTH_ACCESS_TOKEN_FETCHER_IMPL_H_
#define COMPONENTS_CRYPTAUTH_CRYPTAUTH_ACCESS_TOKEN_FETCHER_IMPL_H_
#include <memory>
#include "base/callback.h"
#include "base/macros.h"
#include "components/cryptauth/cryptauth_access_token_fetcher.h"
#include "google_apis/gaia/oauth2_token_service.h"
namespace cryptauth {
// Implementation of CryptAuthAccessTokenFetcher fetching an access token for a
// given account using the provided OAuth2TokenService.
class CryptAuthAccessTokenFetcherImpl : public CryptAuthAccessTokenFetcher,
public OAuth2TokenService::Consumer {
public:
// |token_service| is not owned, and must outlive this object.
CryptAuthAccessTokenFetcherImpl(OAuth2TokenService* token_service,
const std::string& account_id);
~CryptAuthAccessTokenFetcherImpl() override;
// CryptAuthAccessTokenFetcher:
void FetchAccessToken(const AccessTokenCallback& callback) override;
private:
// OAuth2TokenService::Consumer:
void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) override;
void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) override;
// System service that caches and fetches tokens for a given account.
// Not owned.
OAuth2TokenService* token_service_;
// The account id for whom to mint the token.
std::string account_id_;
// True if FetchAccessToken() has been called.
bool fetch_started_;
// Stores the request from |token_service_| to mint the token.
std::unique_ptr<OAuth2TokenService::Request> token_request_;
// Callback to invoke when the token fetch succeeds or fails.
AccessTokenCallback callback_;
DISALLOW_COPY_AND_ASSIGN(CryptAuthAccessTokenFetcherImpl);
};
} // namespace cryptauth
#endif // COMPONENTS_CRYPTAUTH_CRYPTAUTH_ACCESS_TOKEN_FETCHER_IMPL_H_
// Copyright 2014 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/cryptauth/cryptauth_access_token_fetcher_impl.h"
#include <string>
#include "base/bind.h"
#include "base/macros.h"
#include "google_apis/gaia/fake_oauth2_token_service.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cryptauth {
namespace {
const char kAccountId[] = "account_id";
const char kAccessToken[] = "access_token";
const char kInvalidResult[] = "invalid_result";
// Callback that saves the fetched access token to the first argument.
void SaveAccessToken(std::string* out_token, const std::string& in_token) {
*out_token = in_token;
}
} // namespace
class CryptAuthAccessTokenFetcherTest : public testing::Test {
protected:
CryptAuthAccessTokenFetcherTest()
: fetcher_(&token_service_, kAccountId) {
token_service_.AddAccount(kAccountId);
}
FakeOAuth2TokenService token_service_;
CryptAuthAccessTokenFetcherImpl fetcher_;
DISALLOW_COPY_AND_ASSIGN(CryptAuthAccessTokenFetcherTest);
};
TEST_F(CryptAuthAccessTokenFetcherTest, FetchSuccess) {
std::string result;
fetcher_.FetchAccessToken(base::Bind(SaveAccessToken, &result));
token_service_.IssueAllTokensForAccount(kAccountId, kAccessToken,
base::Time::Max());
EXPECT_EQ(kAccessToken, result);
}
TEST_F(CryptAuthAccessTokenFetcherTest, FetchFailure) {
std::string result(kInvalidResult);
fetcher_.FetchAccessToken(base::Bind(SaveAccessToken, &result));
token_service_.IssueErrorForAllPendingRequestsForAccount(
kAccountId,
GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR));
EXPECT_EQ(std::string(), result);
}
TEST_F(CryptAuthAccessTokenFetcherTest, FetcherReuse) {
std::string result1;
fetcher_.FetchAccessToken(base::Bind(SaveAccessToken, &result1));
{
std::string result2(kInvalidResult);
fetcher_.FetchAccessToken(base::Bind(SaveAccessToken, &result2));
EXPECT_EQ(std::string(), result2);
}
token_service_.IssueAllTokensForAccount(kAccountId, kAccessToken,
base::Time::Max());
EXPECT_EQ(kAccessToken, result1);
}
} // namespace cryptauth
...@@ -10,8 +10,9 @@ ...@@ -10,8 +10,9 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "components/cryptauth/cryptauth_access_token_fetcher_impl.h"
#include "components/cryptauth/switches.h" #include "components/cryptauth/switches.h"
#include "services/identity/public/cpp/identity_manager.h"
#include "services/identity/public/cpp/primary_account_access_token_fetcher.h"
namespace cryptauth { namespace cryptauth {
...@@ -53,11 +54,11 @@ GURL CreateRequestUrl(const std::string& request_path) { ...@@ -53,11 +54,11 @@ GURL CreateRequestUrl(const std::string& request_path) {
CryptAuthClientImpl::CryptAuthClientImpl( CryptAuthClientImpl::CryptAuthClientImpl(
std::unique_ptr<CryptAuthApiCallFlow> api_call_flow, std::unique_ptr<CryptAuthApiCallFlow> api_call_flow,
std::unique_ptr<CryptAuthAccessTokenFetcher> access_token_fetcher, identity::IdentityManager* identity_manager,
scoped_refptr<net::URLRequestContextGetter> url_request_context, scoped_refptr<net::URLRequestContextGetter> url_request_context,
const DeviceClassifier& device_classifier) const DeviceClassifier& device_classifier)
: api_call_flow_(std::move(api_call_flow)), : api_call_flow_(std::move(api_call_flow)),
access_token_fetcher_(std::move(access_token_fetcher)), identity_manager_(identity_manager),
url_request_context_(url_request_context), url_request_context_(url_request_context),
device_classifier_(device_classifier), device_classifier_(device_classifier),
has_call_started_(false), has_call_started_(false),
...@@ -277,17 +278,29 @@ void CryptAuthClientImpl::MakeApiCall( ...@@ -277,17 +278,29 @@ void CryptAuthClientImpl::MakeApiCall(
request_path_ = request_path; request_path_ = request_path;
error_callback_ = error_callback; error_callback_ = error_callback;
access_token_fetcher_->FetchAccessToken(base::Bind(
&CryptAuthClientImpl::OnAccessTokenFetched<ResponseProto>, OAuth2TokenService::ScopeSet scopes;
weak_ptr_factory_.GetWeakPtr(), serialized_request, response_callback)); scopes.insert("https://www.googleapis.com/auth/cryptauth");
access_token_fetcher_ =
identity_manager_->CreateAccessTokenFetcherForPrimaryAccount(
"cryptauth_client", scopes,
base::BindOnce(
&CryptAuthClientImpl::OnAccessTokenFetched<ResponseProto>,
weak_ptr_factory_.GetWeakPtr(), serialized_request,
response_callback),
identity::PrimaryAccountAccessTokenFetcher::Mode::kImmediate);
} }
template <class ResponseProto> template <class ResponseProto>
void CryptAuthClientImpl::OnAccessTokenFetched( void CryptAuthClientImpl::OnAccessTokenFetched(
const std::string& serialized_request, const std::string& serialized_request,
const base::Callback<void(const ResponseProto&)>& response_callback, const base::Callback<void(const ResponseProto&)>& response_callback,
const std::string& access_token) { GoogleServiceAuthError error,
if (access_token.empty()) { std::string access_token) {
access_token_fetcher_.reset();
if (error.state() != GoogleServiceAuthError::NONE) {
OnApiCallFailed("Failed to get a valid access token."); OnApiCallFailed("Failed to get a valid access token.");
return; return;
} }
...@@ -320,24 +333,19 @@ void CryptAuthClientImpl::OnApiCallFailed(const std::string& error_message) { ...@@ -320,24 +333,19 @@ void CryptAuthClientImpl::OnApiCallFailed(const std::string& error_message) {
// CryptAuthClientFactoryImpl // CryptAuthClientFactoryImpl
CryptAuthClientFactoryImpl::CryptAuthClientFactoryImpl( CryptAuthClientFactoryImpl::CryptAuthClientFactoryImpl(
OAuth2TokenService* token_service, identity::IdentityManager* identity_manager,
const std::string& account_id,
scoped_refptr<net::URLRequestContextGetter> url_request_context, scoped_refptr<net::URLRequestContextGetter> url_request_context,
const DeviceClassifier& device_classifier) const DeviceClassifier& device_classifier)
: token_service_(token_service), : identity_manager_(identity_manager),
account_id_(account_id),
url_request_context_(url_request_context), url_request_context_(url_request_context),
device_classifier_(device_classifier) { device_classifier_(device_classifier) {}
}
CryptAuthClientFactoryImpl::~CryptAuthClientFactoryImpl() { CryptAuthClientFactoryImpl::~CryptAuthClientFactoryImpl() {
} }
std::unique_ptr<CryptAuthClient> CryptAuthClientFactoryImpl::CreateInstance() { std::unique_ptr<CryptAuthClient> CryptAuthClientFactoryImpl::CreateInstance() {
return std::make_unique<CryptAuthClientImpl>( return std::make_unique<CryptAuthClientImpl>(
base::WrapUnique(new CryptAuthApiCallFlow()), base::WrapUnique(new CryptAuthApiCallFlow()), identity_manager_,
base::WrapUnique(
new CryptAuthAccessTokenFetcherImpl(token_service_, account_id_)),
url_request_context_, device_classifier_); url_request_context_, device_classifier_);
} }
......
...@@ -7,14 +7,17 @@ ...@@ -7,14 +7,17 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "components/cryptauth/cryptauth_access_token_fetcher.h"
#include "components/cryptauth/cryptauth_api_call_flow.h" #include "components/cryptauth/cryptauth_api_call_flow.h"
#include "components/cryptauth/cryptauth_client.h" #include "components/cryptauth/cryptauth_client.h"
#include "components/cryptauth/proto/cryptauth_api.pb.h" #include "components/cryptauth/proto/cryptauth_api.pb.h"
#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
class OAuth2TokenService; namespace identity {
class IdentityManager;
class PrimaryAccountAccessTokenFetcher;
} // namespace identity
class GoogleServiceAuthError;
namespace cryptauth { namespace cryptauth {
...@@ -26,13 +29,11 @@ class CryptAuthClientImpl : public CryptAuthClient { ...@@ -26,13 +29,11 @@ class CryptAuthClientImpl : public CryptAuthClient {
typedef base::Callback<void(const std::string&)> ErrorCallback; typedef base::Callback<void(const std::string&)> ErrorCallback;
// Creates the client using |url_request_context| to make the HTTP request // Creates the client using |url_request_context| to make the HTTP request
// through |api_call_flow|. CryptAuthClientImpl takes ownership of // through |api_call_flow|. The |device_classifier| argument contains basic
// |access_token_fetcher|, which provides the access token authorizing // device information of the caller (e.g. version and device type).
// CryptAuth requests. The |device_classifier| argument contains basic device
// information of the caller (e.g. version and device type).
CryptAuthClientImpl( CryptAuthClientImpl(
std::unique_ptr<CryptAuthApiCallFlow> api_call_flow, std::unique_ptr<CryptAuthApiCallFlow> api_call_flow,
std::unique_ptr<CryptAuthAccessTokenFetcher> access_token_fetcher, identity::IdentityManager* identity_manager,
scoped_refptr<net::URLRequestContextGetter> url_request_context, scoped_refptr<net::URLRequestContextGetter> url_request_context,
const DeviceClassifier& device_classifier); const DeviceClassifier& device_classifier);
~CryptAuthClientImpl() override; ~CryptAuthClientImpl() override;
...@@ -85,7 +86,8 @@ class CryptAuthClientImpl : public CryptAuthClient { ...@@ -85,7 +86,8 @@ class CryptAuthClientImpl : public CryptAuthClient {
void OnAccessTokenFetched( void OnAccessTokenFetched(
const std::string& serialized_request, const std::string& serialized_request,
const base::Callback<void(const ResponseProto&)>& response_callback, const base::Callback<void(const ResponseProto&)>& response_callback,
const std::string& access_token); GoogleServiceAuthError error,
std::string access_token);
// Called with CryptAuthApiCallFlow completes successfully to deserialize and // Called with CryptAuthApiCallFlow completes successfully to deserialize and
// return the result. // return the result.
...@@ -100,8 +102,11 @@ class CryptAuthClientImpl : public CryptAuthClient { ...@@ -100,8 +102,11 @@ class CryptAuthClientImpl : public CryptAuthClient {
// Constructs and executes the actual HTTP request. // Constructs and executes the actual HTTP request.
std::unique_ptr<CryptAuthApiCallFlow> api_call_flow_; std::unique_ptr<CryptAuthApiCallFlow> api_call_flow_;
identity::IdentityManager* identity_manager_;
// Fetches the access token authorizing the API calls. // Fetches the access token authorizing the API calls.
std::unique_ptr<CryptAuthAccessTokenFetcher> access_token_fetcher_; std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher>
access_token_fetcher_;
// The context for network requests. // The context for network requests.
scoped_refptr<net::URLRequestContextGetter> url_request_context_; scoped_refptr<net::URLRequestContextGetter> url_request_context_;
...@@ -131,14 +136,12 @@ class CryptAuthClientImpl : public CryptAuthClient { ...@@ -131,14 +136,12 @@ class CryptAuthClientImpl : public CryptAuthClient {
// Implementation of CryptAuthClientFactory. // Implementation of CryptAuthClientFactory.
class CryptAuthClientFactoryImpl : public CryptAuthClientFactory { class CryptAuthClientFactoryImpl : public CryptAuthClientFactory {
public: public:
// |token_service|: Gets the user's access token. // |identity_manager|: Gets the user's access token.
// Not owned, so |token_service| needs to outlive this object. // Not owned, so |identity_manager| needs to outlive this object.
// |account_id|: The account id of the user.
// |url_request_context|: The request context to make the HTTP requests. // |url_request_context|: The request context to make the HTTP requests.
// |device_classifier|: Contains basic device information of the client. // |device_classifier|: Contains basic device information of the client.
CryptAuthClientFactoryImpl( CryptAuthClientFactoryImpl(
OAuth2TokenService* token_service, identity::IdentityManager* identity_manager,
const std::string& account_id,
scoped_refptr<net::URLRequestContextGetter> url_request_context, scoped_refptr<net::URLRequestContextGetter> url_request_context,
const DeviceClassifier& device_classifier); const DeviceClassifier& device_classifier);
~CryptAuthClientFactoryImpl() override; ~CryptAuthClientFactoryImpl() override;
...@@ -147,8 +150,7 @@ class CryptAuthClientFactoryImpl : public CryptAuthClientFactory { ...@@ -147,8 +150,7 @@ class CryptAuthClientFactoryImpl : public CryptAuthClientFactory {
std::unique_ptr<CryptAuthClient> CreateInstance() override; std::unique_ptr<CryptAuthClient> CreateInstance() override;
private: private:
OAuth2TokenService* token_service_; identity::IdentityManager* identity_manager_;
const std::string account_id_;
const scoped_refptr<net::URLRequestContextGetter> url_request_context_; const scoped_refptr<net::URLRequestContextGetter> url_request_context_;
const DeviceClassifier device_classifier_; const DeviceClassifier device_classifier_;
......
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