Commit c9c615b6 authored by Maciek Slusarczyk's avatar Maciek Slusarczyk Committed by Commit Bot

Changing sync token verifiy auth to API key.

In order to authorize verifyToken operation PasswordSyncTokenFetcher
gets login scope OAuth token. This CL changes this authorization method
to an API key. As a result we will save on network traffic (no need to
fetch access token) and enable token verification in the login screen
context. OAuth token stays the only valid option for createToken and
getToken.

Bug: 1090341
Change-Id: If802a156abd73cd8344b1be8d7f3ef3cbc7bfca3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2421588Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarMaksim Ivanov <emaxx@chromium.org>
Reviewed-by: default avatarDenis Kuznetsov [CET] <antrim@chromium.org>
Reviewed-by: default avatarRoman Sorokin [CET] <rsorokin@chromium.org>
Commit-Queue: Maciek Slusarczyk <mslus@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811067}
parent 05461a01
......@@ -24,6 +24,8 @@
#include "google_apis/gaia/gaia_auth_fetcher.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/google_api_keys.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_request_context_getter.h"
......@@ -52,28 +54,34 @@ const char kTokenTypeValue[] = "SAML_PASSWORD";
const char kAcceptValue[] =
"Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
const char kPasswordSyncTokenCreateEndPoint[] =
const char kPasswordSyncTokenBaseEndPoint[] =
"https://chromedevicetoken.googleapis.com/v1/tokens";
const char kPasswordSyncTokenGetEndPoint[] =
"https://chromedevicetoken.googleapis.com/v1/"
"tokens?token_type=SAML_PASSWORD";
const char kPasswordSyncTokenCreateEndPoint[] = "";
const char kPasswordSyncTokenGetEndPoint[] = "?token_type=SAML_PASSWORD";
const char kPasswordSyncTokenVerifyEndPoint[] =
"https://chromedevicetoken.googleapis.com/v1/tokens/"
"%s:verify?token_type=SAML_PASSWORD";
"/%s:verify?token_type=SAML_PASSWORD&key=%s";
std::string GetBaseEndPoint() {
return kPasswordSyncTokenBaseEndPoint;
}
GURL sync_token_create_url() {
return GURL(kPasswordSyncTokenCreateEndPoint);
GURL GetSyncTokenCreateUrl() {
return GURL(GetBaseEndPoint() +
std::string(kPasswordSyncTokenCreateEndPoint));
}
GURL sync_token_get_url() {
return GURL(kPasswordSyncTokenGetEndPoint);
GURL GetSyncTokenGetUrl() {
return GURL(GetBaseEndPoint() + std::string(kPasswordSyncTokenGetEndPoint));
}
GURL sync_token_verify_url(const std::string& sync_token) {
return GURL(
base::StringPrintf(kPasswordSyncTokenVerifyEndPoint, sync_token.c_str()));
GURL GetSyncTokenVerifyUrl(const std::string& sync_token,
const std::string& escaped_api_key) {
return GURL(GetBaseEndPoint() +
base::StringPrintf(kPasswordSyncTokenVerifyEndPoint,
sync_token.c_str(), escaped_api_key.c_str()));
}
} // namespace
......@@ -112,7 +120,7 @@ void PasswordSyncTokenFetcher::StartTokenVerify(const std::string& sync_token) {
DCHECK_EQ(request_type_, RequestType::kNone);
request_type_ = RequestType::kVerifyToken;
sync_token_ = sync_token;
StartAccessTokenFetch();
FetchSyncToken(/*access_token=*/std::string());
}
void PasswordSyncTokenFetcher::StartAccessTokenFetch() {
......@@ -179,13 +187,15 @@ void PasswordSyncTokenFetcher::FetchSyncToken(const std::string& access_token) {
auto resource_request = std::make_unique<network::ResourceRequest>();
switch (request_type_) {
case RequestType::kCreateToken:
resource_request->url = sync_token_create_url();
resource_request->url = GetSyncTokenCreateUrl();
break;
case RequestType::kGetToken:
resource_request->url = sync_token_get_url();
resource_request->url = GetSyncTokenGetUrl();
break;
case RequestType::kVerifyToken:
resource_request->url = sync_token_verify_url(sync_token_);
resource_request->url = GetSyncTokenVerifyUrl(
sync_token_, net::EscapeQueryParamValue(google_apis::GetAPIKey(),
/*use_plus=*/true));
break;
case RequestType::kNone:
// Error: request type needs to be already set.
......@@ -199,9 +209,11 @@ void PasswordSyncTokenFetcher::FetchSyncToken(const std::string& access_token) {
} else {
resource_request->method = net::HttpRequestHeaders::kGetMethod;
}
if (request_type_ != RequestType::kVerifyToken) {
resource_request->headers.SetHeader(
net::HttpRequestHeaders::kAuthorization,
base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str()));
}
resource_request->headers.SetHeader(net::HttpRequestHeaders::kContentType,
kContentTypeJSON);
resource_request->headers.SetHeader(net::HttpRequestHeaders::kAccept,
......
......@@ -66,6 +66,9 @@ class PasswordSyncTokenFetcher final {
Consumer* consumer);
~PasswordSyncTokenFetcher();
// StartTokenCreate() and StartTokenGet() require fetching OAuth access_token
// to authorize the operation, StartTokenVerify is authenticated with API key
// and proceeds with an empty access_token.
void StartTokenCreate();
void StartTokenGet();
void StartTokenVerify(const std::string& sync_token);
......
......@@ -51,8 +51,13 @@ void PasswordSyncTokenVerifier::RecheckAfter(base::TimeDelta delay) {
void PasswordSyncTokenVerifier::CreateTokenAsync() {
DCHECK(!password_sync_token_fetcher_);
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory =
primary_profile_->GetURLLoaderFactory();
if (!url_loader_factory.get())
return;
password_sync_token_fetcher_ = std::make_unique<PasswordSyncTokenFetcher>(
primary_profile_->GetURLLoaderFactory(), primary_profile_, this);
url_loader_factory, primary_profile_, this);
password_sync_token_fetcher_->StartTokenCreate();
}
......@@ -63,17 +68,23 @@ void PasswordSyncTokenVerifier::CheckForPasswordNotInSync() {
if (!prefs->GetBoolean(prefs::kSamlInSessionPasswordChangeEnabled)) {
return;
}
DCHECK(!password_sync_token_fetcher_);
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory =
primary_profile_->GetURLLoaderFactory();
// url_loader_factory is nullptr in unit tests so constructing
// PasswordSyncTokenFetcher does not make sense there.
if (!url_loader_factory.get())
return;
password_sync_token_fetcher_ = std::make_unique<PasswordSyncTokenFetcher>(
url_loader_factory, primary_profile_, this);
// Get current sync token for primary_user_.
std::string sync_token = prefs->GetString(prefs::kSamlPasswordSyncToken);
// No local sync token on the device - create it by sending user through the
// online re-auth.
if (sync_token.empty())
sync_token = dummy_token;
DCHECK(!password_sync_token_fetcher_);
password_sync_token_fetcher_ = std::make_unique<PasswordSyncTokenFetcher>(
primary_profile_->GetURLLoaderFactory(), primary_profile_, this);
password_sync_token_fetcher_->StartTokenVerify(sync_token);
}
......@@ -84,8 +95,14 @@ void PasswordSyncTokenVerifier::FetchSyncTokenOnReauth() {
}
DCHECK(!password_sync_token_fetcher_);
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory =
primary_profile_->GetURLLoaderFactory();
// No url_loader_factory in unit tests.
if (!url_loader_factory.get())
return;
password_sync_token_fetcher_ = std::make_unique<PasswordSyncTokenFetcher>(
primary_profile_->GetURLLoaderFactory(), primary_profile_, this);
url_loader_factory, primary_profile_, this);
password_sync_token_fetcher_->StartTokenGet();
}
......
......@@ -124,14 +124,9 @@ void PasswordSyncTokenVerifierTest::OnTokenVerified(bool is_verified) {
verifier_->OnTokenVerified(is_verified);
}
bool PasswordSyncTokenVerifierTest::PasswordSyncTokenFetcherIsAllocated() {
return verifier_->password_sync_token_fetcher_ != nullptr;
}
TEST_F(PasswordSyncTokenVerifierTest, EmptySyncToken) {
CreatePasswordSyncTokenVerifier();
verifier_->CheckForPasswordNotInSync();
EXPECT_TRUE(PasswordSyncTokenFetcherIsAllocated());
OnTokenVerified(false);
EXPECT_TRUE(user_manager_->GetActiveUser()->force_online_signin());
}
......@@ -162,7 +157,6 @@ TEST_F(PasswordSyncTokenVerifierTest, SyncTokenValidationAfterDelay) {
OnTokenVerified(true);
EXPECT_FALSE(user_manager_->GetActiveUser()->force_online_signin());
test_environment_.FastForwardBy(kSyncTokenCheckInterval);
EXPECT_TRUE(PasswordSyncTokenFetcherIsAllocated());
OnTokenVerified(false);
EXPECT_TRUE(user_manager_->GetActiveUser()->force_online_signin());
}
......@@ -197,7 +191,6 @@ TEST_F(PasswordSyncTokenVerifierTest, PasswordChangePolicyNotSet) {
TEST_F(PasswordSyncTokenVerifierTest, SyncTokenNotSet) {
CreatePasswordSyncTokenVerifier();
verifier_->FetchSyncTokenOnReauth();
EXPECT_TRUE(PasswordSyncTokenFetcherIsAllocated());
verifier_->OnTokenFetched(kSyncToken);
EXPECT_EQ(
user_manager::known_user::GetPasswordSyncToken(saml_login_account_id_),
......@@ -210,10 +203,8 @@ TEST_F(PasswordSyncTokenVerifierTest, SyncTokenNotSet) {
TEST_F(PasswordSyncTokenVerifierTest, SyncTokenInitForUser) {
CreatePasswordSyncTokenVerifier();
verifier_->FetchSyncTokenOnReauth();
EXPECT_TRUE(PasswordSyncTokenFetcherIsAllocated());
// Token API not initilized for the user - request token creation.
verifier_->OnTokenFetched(std::string());
EXPECT_TRUE(PasswordSyncTokenFetcherIsAllocated());
verifier_->OnTokenCreated(kSyncToken);
EXPECT_EQ(
user_manager::known_user::GetPasswordSyncToken(saml_login_account_id_),
......@@ -223,7 +214,6 @@ TEST_F(PasswordSyncTokenVerifierTest, SyncTokenInitForUser) {
kSyncToken);
// Start regular polling after session init.
test_environment_.FastForwardBy(kSyncTokenCheckInterval);
EXPECT_TRUE(PasswordSyncTokenFetcherIsAllocated());
OnTokenVerified(true);
EXPECT_FALSE(user_manager_->GetActiveUser()->force_online_signin());
}
......
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