Commit 662ae897 authored by Stephane Zermatten's avatar Stephane Zermatten Committed by Commit Bot

[Autofill Assistant] Add optional authentication.

With this change, if the user is logged into Chrome,
and unless authentication is disabled with
  --autofill-assistant-auth=false
the service will send out oauth credentials with the request.

This is one step towards making only authenticated calls.

Bug: 806868
Change-Id: I504a06af842869739ba44230d57f2a58259a480c
Reviewed-on: https://chromium-review.googlesource.com/c/1275890
Commit-Queue: Stephane Zermatten <szermatt@chromium.org>
Reviewed-by: default avatarMathias Carlen <mcarlen@chromium.org>
Reviewed-by: default avatarColin Blundell <blundell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#602354}
parent 47546c89
...@@ -14,7 +14,9 @@ ...@@ -14,7 +14,9 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "chrome/browser/android/chrome_feature_list.h" #include "chrome/browser/android/chrome_feature_list.h"
#include "chrome/browser/autofill/personal_data_manager_factory.h" #include "chrome/browser/autofill/personal_data_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/common/channel_info.h" #include "chrome/common/channel_info.h"
#include "components/autofill_assistant/browser/controller.h" #include "components/autofill_assistant/browser/controller.h"
#include "components/variations/variations_associated_data.h" #include "components/variations/variations_associated_data.h"
...@@ -279,6 +281,24 @@ std::string UiControllerAndroid::GetApiKey() { ...@@ -279,6 +281,24 @@ std::string UiControllerAndroid::GetApiKey() {
return api_key; return api_key;
} }
identity::IdentityManager*
UiControllerAndroid::GetIdentityManagerForPrimaryAccount() {
Profile* profile = ProfileManager::GetActiveUserProfile();
if (!profile) {
DLOG(ERROR) << "No active user profile. Cannot authenticate.";
return nullptr;
}
// TODO(crbug.com/806868): Log in as a specific account, instead of always the
// primary.
identity::IdentityManager* identity_manager =
profile ? IdentityManagerFactory::GetForProfile(profile) : nullptr;
if (!identity_manager || !identity_manager->HasPrimaryAccount()) {
DLOG(ERROR) << "No primary account. Cannot authenticate.";
return nullptr;
}
return identity_manager;
}
autofill::PersonalDataManager* UiControllerAndroid::GetPersonalDataManager() { autofill::PersonalDataManager* UiControllerAndroid::GetPersonalDataManager() {
return autofill::PersonalDataManagerFactory::GetForProfile( return autofill::PersonalDataManagerFactory::GetForProfile(
ProfileManager::GetLastUsedProfile()); ProfileManager::GetLastUsedProfile());
......
...@@ -47,6 +47,7 @@ class UiControllerAndroid : public UiController, public Client { ...@@ -47,6 +47,7 @@ class UiControllerAndroid : public UiController, public Client {
// Overrides Client: // Overrides Client:
std::string GetApiKey() override; std::string GetApiKey() override;
identity::IdentityManager* GetIdentityManagerForPrimaryAccount() override;
autofill::PersonalDataManager* GetPersonalDataManager() override; autofill::PersonalDataManager* GetPersonalDataManager() override;
std::string GetServerUrl() override; std::string GetServerUrl() override;
UiController* GetUiController() override; UiController* GetUiController() override;
......
...@@ -88,6 +88,7 @@ jumbo_static_library("browser") { ...@@ -88,6 +88,7 @@ jumbo_static_library("browser") {
"//content/public/browser", "//content/public/browser",
"//google_apis", "//google_apis",
"//net", "//net",
"//services/identity/public/cpp:cpp",
"//third_party/re2", "//third_party/re2",
] ]
} }
......
...@@ -8,6 +8,7 @@ include_rules = [ ...@@ -8,6 +8,7 @@ include_rules = [
"+google_apis", "+google_apis",
"+net", "+net",
"+services/network/public/cpp", "+services/network/public/cpp",
"+services/identity/public/cpp",
"+third_party/blink/public/mojom/payments/payment_request.mojom.h", "+third_party/blink/public/mojom/payments/payment_request.mojom.h",
"+third_party/re2", "+third_party/re2",
"+ui/base/l10n/l10n_util.h", "+ui/base/l10n/l10n_util.h",
......
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
#include <string> #include <string>
namespace identity {
class IdentityManager;
} // namespace identity
namespace autofill { namespace autofill {
class PersonalDataManager; class PersonalDataManager;
} // namespace autofill } // namespace autofill
...@@ -23,6 +27,10 @@ class Client { ...@@ -23,6 +27,10 @@ class Client {
// Returns the API key to be used for requests to the backend. // Returns the API key to be used for requests to the backend.
virtual std::string GetApiKey() = 0; virtual std::string GetApiKey() = 0;
// Gets the identity manager to use to make authenticated calls or nullptr if
// no identity is available.
virtual identity::IdentityManager* GetIdentityManagerForPrimaryAccount() = 0;
// Returns the current active personal data manager. // Returns the current active personal data manager.
virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0; virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0;
......
...@@ -36,14 +36,14 @@ void Controller::CreateAndStartForWebContents( ...@@ -36,14 +36,14 @@ void Controller::CreateAndStartForWebContents(
std::unique_ptr<Client> client, std::unique_ptr<Client> client,
std::unique_ptr<std::map<std::string, std::string>> parameters) { std::unique_ptr<std::map<std::string, std::string>> parameters) {
// Get the key early since |client| will be invalidated when moved below. // Get the key early since |client| will be invalidated when moved below.
const std::string api_key = client->GetApiKey();
GURL server_url(client->GetServerUrl()); GURL server_url(client->GetServerUrl());
DCHECK(server_url.is_valid()); DCHECK(server_url.is_valid());
std::unique_ptr<Service> service = std::make_unique<Service>(
client->GetApiKey(), server_url, web_contents->GetBrowserContext(),
client->GetIdentityManagerForPrimaryAccount());
new Controller(web_contents, std::move(client), new Controller(web_contents, std::move(client),
WebController::CreateForWebContents(web_contents), WebController::CreateForWebContents(web_contents),
std::make_unique<Service>(api_key, server_url, std::move(service), std::move(parameters));
web_contents->GetBrowserContext()),
std::move(parameters));
} }
Service* Controller::GetService() { Service* Controller::GetService() {
......
...@@ -41,6 +41,9 @@ class FakeClient : public Client { ...@@ -41,6 +41,9 @@ class FakeClient : public Client {
// Implements Client // Implements Client
std::string GetApiKey() override { return ""; } std::string GetApiKey() override { return ""; }
identity::IdentityManager* GetIdentityManagerForPrimaryAccount() override {
return nullptr;
}
autofill::PersonalDataManager* GetPersonalDataManager() override { autofill::PersonalDataManager* GetPersonalDataManager() override {
return nullptr; return nullptr;
} }
......
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
namespace autofill_assistant { namespace autofill_assistant {
MockService::MockService() : Service("api_key", GURL("http://fake"), nullptr) {} MockService::MockService()
: Service("api_key", GURL("http://fake"), nullptr, nullptr) {}
MockService::~MockService() {} MockService::~MockService() {}
} // namespace autofill_assistant } // namespace autofill_assistant
...@@ -11,22 +11,32 @@ ...@@ -11,22 +11,32 @@
#include <vector> #include <vector>
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "components/autofill_assistant/browser/service.pb.h" #include "components/autofill_assistant/browser/service.pb.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "services/identity/public/cpp/primary_account_access_token_fetcher.h"
#include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace content { namespace content {
class BrowserContext; class BrowserContext;
} } // namespace content
namespace identity {
class IdentityManager;
} // namespace identity
namespace autofill_assistant { namespace autofill_assistant {
// Autofill assistant service to communicate with the server to get scripts and // Autofill assistant service to communicate with the server to get scripts and
// client actions. // client actions.
class Service { class Service {
public: public:
// |context| and |identity_manager| must remain valid for the lifetime of the
// service instance. |identity_manager| might be nullptr.
Service(const std::string& api_key, Service(const std::string& api_key,
const GURL& server_url, const GURL& server_url,
content::BrowserContext* context); content::BrowserContext* context,
identity::IdentityManager* identity_manager);
virtual ~Service(); virtual ~Service();
using ResponseCallback = using ResponseCallback =
...@@ -56,16 +66,32 @@ class Service { ...@@ -56,16 +66,32 @@ class Service {
Loader(); Loader();
~Loader(); ~Loader();
GURL url;
std::string request_body;
ResponseCallback callback; ResponseCallback callback;
std::unique_ptr<::network::SimpleURLLoader> loader; std::unique_ptr<::network::SimpleURLLoader> loader;
bool retried_with_fresh_access_token;
}; };
std::unique_ptr<::network::SimpleURLLoader> CreateAndStartLoader(
const GURL& server_url, void SendRequest(Loader* loader);
const std::string& request,
Loader* loader); // Creates a loader and adds it to |loaders_|.
Loader* AddLoader(const GURL& url,
const std::string& request_body,
ResponseCallback callback);
// Sends a request with the given loader, using the current auth token, if one
// is available.
void StartLoader(Loader* loader);
void OnURLLoaderComplete(Loader* loader, void OnURLLoaderComplete(Loader* loader,
std::unique_ptr<std::string> response_body); std::unique_ptr<std::string> response_body);
// Fetches the access token and, once this is done, starts all pending loaders
// in |loaders_|.
void FetchAccessToken();
void OnFetchAccessToken(GoogleServiceAuthError error,
identity::AccessTokenInfo access_token_info);
content::BrowserContext* context_; content::BrowserContext* context_;
GURL script_server_url_; GURL script_server_url_;
GURL script_action_server_url_; GURL script_action_server_url_;
...@@ -73,6 +99,28 @@ class Service { ...@@ -73,6 +99,28 @@ class Service {
// Destroying this object will cancel ongoing requests. // Destroying this object will cancel ongoing requests.
std::map<Loader*, std::unique_ptr<Loader>> loaders_; std::map<Loader*, std::unique_ptr<Loader>> loaders_;
// API key to add to the URL of unauthenticated requests.
std::string api_key_;
// Pointer must remain valid for the lifetime of the Service instance. Might
// be nullptr, if auth_enabled_ is false.
identity::IdentityManager* const identity_manager_;
// Whether requests should be authenticated.
bool auth_enabled_;
// An OAuth 2 token. Empty if not fetched yet or if the token has been
// invalidated.
std::string access_token_;
// Account id |access_token_| is for.
std::string account_id_;
// Active OAuth2 token fetcher.
std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher> token_fetcher_;
base::WeakPtrFactory<Service> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(Service); DISALLOW_COPY_AND_ASSIGN(Service);
}; };
......
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