Commit d0eb2001 authored by Andre Vincent's avatar Andre Vincent Committed by Chromium LUCI CQ

[ntp][module] Fetches token for available account

As of now, the Drive Service fetches an access token.

Fixed: 1166345
Change-Id: I9446d5811ea1726c8865c7f3604da1554cce4fe5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2628048
Commit-Queue: Andre Vincent <andrevincent@google.com>
Reviewed-by: default avatarEsmael Elmoslimany <aee@chromium.org>
Reviewed-by: default avatarTibor Goldschwendt <tiborg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846295}
parent 10021fad
...@@ -3884,6 +3884,10 @@ static_library("browser") { ...@@ -3884,6 +3884,10 @@ static_library("browser") {
"search/chrome_colors/chrome_colors_service.h", "search/chrome_colors/chrome_colors_service.h",
"search/drive/drive_handler.cc", "search/drive/drive_handler.cc",
"search/drive/drive_handler.h", "search/drive/drive_handler.h",
"search/drive/drive_service.cc",
"search/drive/drive_service.h",
"search/drive/drive_service_factory.cc",
"search/drive/drive_service_factory.h",
"search/instant_service.cc", "search/instant_service.cc",
"search/instant_service.h", "search/instant_service.h",
"search/instant_service_factory.cc", "search/instant_service_factory.cc",
......
// Copyright 2021 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 "chrome/browser/search/drive/drive_service.h"
#include <memory>
#include <utility>
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h"
#include "components/signin/public/identity_manager/scope_set.h"
namespace {
// The scope required for an access token in order to query ItemSuggest.
constexpr char kDriveScope[] = "https://www.googleapis.com/auth/drive.readonly";
} // namespace
DriveService::~DriveService() = default;
DriveService::DriveService(signin::IdentityManager* identity_manager)
: identity_manager_(identity_manager) {}
void DriveService::GetDriveSuggestions(SuggestionsCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// TODO(crbug/1168763) May need to handle multiple requests after
// token_fetcher has been set.
token_fetcher_ = std::make_unique<signin::PrimaryAccountAccessTokenFetcher>(
"ntp_drive_module", identity_manager_, signin::ScopeSet({kDriveScope}),
base::BindOnce(&DriveService::OnTokenReceived, weak_factory_.GetWeakPtr(),
std::move(callback)),
signin::PrimaryAccountAccessTokenFetcher::Mode::kImmediate,
signin::ConsentLevel::kSync);
}
void DriveService::OnTokenReceived(SuggestionsCallback callback,
GoogleServiceAuthError error,
signin::AccessTokenInfo token_info) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
token_fetcher_.reset();
if (error.state() != GoogleServiceAuthError::NONE) {
std::move(callback).Run("");
return;
}
std::move(callback).Run("valid token");
}
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SEARCH_DRIVE_DRIVE_SERVICE_H_
#define CHROME_BROWSER_SEARCH_DRIVE_DRIVE_SERVICE_H_
#include <memory>
#include <string>
#include "base/sequence_checker.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/signin/public/identity_manager/access_token_info.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
namespace signin {
class IdentityManager;
class PrimaryAccountAccessTokenFetcher;
} // namespace signin
// Handles requests for user Google Drive data.
class DriveService : public KeyedService {
public:
DriveService(const DriveService&) = delete;
explicit DriveService(signin::IdentityManager* identity_manager);
~DriveService() override;
using SuggestionsCallback = base::OnceCallback<void(std::string)>;
// Retrieves Google Drive document suggestions from ItemSuggest API.
void GetDriveSuggestions(SuggestionsCallback callback);
private:
// TODO(crbug/1164012): Use token to create request
// with callback.
void OnTokenReceived(SuggestionsCallback callback,
GoogleServiceAuthError error,
signin::AccessTokenInfo token_info);
// Used for fetching OAuth2 access tokens. Only non-null when a token
// is made available, or a token is being fetched.
std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher> token_fetcher_;
signin::IdentityManager* identity_manager_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<DriveService> weak_factory_{this};
};
#endif // CHROME_BROWSER_SEARCH_DRIVE_DRIVE_SERVICE_H_
// Copyright 2021 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 "chrome/browser/search/drive/drive_service_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/drive/drive_service.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
DriveService* DriveServiceFactory::GetForProfile(Profile* profile) {
return static_cast<DriveService*>(
GetInstance()->GetServiceForBrowserContext(profile, true));
}
DriveServiceFactory* DriveServiceFactory::GetInstance() {
return base::Singleton<DriveServiceFactory>::get();
}
DriveServiceFactory::DriveServiceFactory()
: BrowserContextKeyedServiceFactory(
"DriveService",
BrowserContextDependencyManager::GetInstance()) {
DependsOn(CookieSettingsFactory::GetInstance());
}
DriveServiceFactory::~DriveServiceFactory() = default;
KeyedService* DriveServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
auto url_loader_factory =
content::BrowserContext::GetDefaultStoragePartition(context)
->GetURLLoaderFactoryForBrowserProcess();
return new DriveService(IdentityManagerFactory::GetForProfile(
Profile::FromBrowserContext(context)));
}
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SEARCH_DRIVE_DRIVE_SERVICE_FACTORY_H_
#define CHROME_BROWSER_SEARCH_DRIVE_DRIVE_SERVICE_FACTORY_H_
#include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
class DriveService;
class Profile;
class DriveServiceFactory : BrowserContextKeyedServiceFactory {
public:
static DriveService* GetForProfile(Profile* profile);
static DriveServiceFactory* GetInstance();
DriveServiceFactory(const DriveServiceFactory&) = delete;
private:
friend struct base::DefaultSingletonTraits<DriveServiceFactory>;
DriveServiceFactory();
~DriveServiceFactory() override;
// Uses BrowserContextKeyedServiceFactory to build a DriveService.
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* profile) const override;
};
#endif // CHROME_BROWSER_SEARCH_DRIVE_DRIVE_SERVICE_FACTORY_H_
// Copyright 2021 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 "chrome/browser/search/drive/drive_service.h"
#include "base/test/mock_callback.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "content/public/test/browser_task_environment.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
class DriveServiceTest : public testing::Test {
public:
DriveServiceTest()
: task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {}
void SetUp() override {
testing::Test::SetUp();
service_ =
std::make_unique<DriveService>(identity_test_env.identity_manager());
identity_test_env.MakePrimaryAccountAvailable("example@google.com");
}
void TearDown() override {
service_.reset();
test_url_loader_factory_.ClearResponses();
}
protected:
content::BrowserTaskEnvironment task_environment_;
network::TestURLLoaderFactory test_url_loader_factory_;
std::unique_ptr<DriveService> service_;
signin::IdentityTestEnvironment identity_test_env;
};
TEST_F(DriveServiceTest, GeneratesTokenOnFetchSuccess) {
bool token_is_valid;
base::MockCallback<DriveService::SuggestionsCallback> callback;
EXPECT_CALL(callback, Run(testing::_))
.Times(1)
.WillOnce(testing::Invoke([&token_is_valid](std::string suggestions) {
token_is_valid = !suggestions.empty();
}));
service_->GetDriveSuggestions(callback.Get());
identity_test_env.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
"token", base::Time());
EXPECT_TRUE(token_is_valid);
}
TEST_F(DriveServiceTest, PassesEmptyStringOnError) {
bool token_is_valid = true;
base::MockCallback<DriveService::SuggestionsCallback> callback;
EXPECT_CALL(callback, Run(testing::_))
.Times(1)
.WillOnce(testing::Invoke([&token_is_valid](std::string suggestion) {
token_is_valid = !suggestion.empty();
}));
service_->GetDriveSuggestions(callback.Get());
identity_test_env.WaitForAccessTokenRequestIfNecessaryAndRespondWithError(
GoogleServiceAuthError(GoogleServiceAuthError::State::CONNECTION_FAILED));
EXPECT_FALSE(token_is_valid);
}
...@@ -4748,6 +4748,7 @@ test("unit_tests") { ...@@ -4748,6 +4748,7 @@ test("unit_tests") {
# NTP is in native code on Android. # NTP is in native code on Android.
"../browser/cart/cart_service_unittest.cc", "../browser/cart/cart_service_unittest.cc",
"../browser/search/drive/drive_service_unittest.cc",
"../browser/search/ntp_features_unittest.cc", "../browser/search/ntp_features_unittest.cc",
"../browser/search/task_module/task_module_service_unittest.cc", "../browser/search/task_module/task_module_service_unittest.cc",
] ]
......
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