0

Add ListAccountsUsesBinaryFormat to fieldtrial_testing_config.json

With the enabling of the flag, some tests started failing because the
ListAccounts response was still being formatted using jspb, while the
parsing was done in binary. This fixes the tests by creating the
ListAccounts response in a binary format if the parameter "laf=b64bin"
can be found in the URL. This parameter is set when the flag is enabled.
The old format is still supported.

Bug: 356643207
Change-Id: Iebcb30861f3ac2f835e86b73da9cd18f1e602024
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6415691
Commit-Queue: Amelie Schneider <amelies@google.com>
Reviewed-by: Alex Ilin <alexilin@chromium.org>
Reviewed-by: Anthi Orfanou <anthie@google.com>
Cr-Commit-Position: refs/heads/main@{#1442627}
This commit is contained in:
Amelie Schneider
2025-04-04 01:54:08 -07:00
committed by Chromium LUCI CQ
parent fe1dc7ddb1
commit 6f48889585
9 changed files with 147 additions and 67 deletions

@ -249,7 +249,7 @@ struct Cookie {
// Converts CookieParams to ListedAccounts.
gaia::ListedAccount ListedAccountFromCookieParams(
const signin::CookieParams& params,
const gaia::CookieParams& params,
const CoreAccountId& account_id) {
gaia::ListedAccount listed_account;
listed_account.id = account_id;
@ -638,7 +638,7 @@ class BaseAccountReconcilorTestTable : public AccountReconcilorTest {
}
void ConfigureCookieManagerService(const std::vector<Cookie>& cookies) {
std::vector<signin::CookieParams> cookie_params;
std::vector<gaia::CookieParams> cookie_params;
for (const auto& cookie : cookies) {
GaiaId gaia_id = cookie.gaia_id;
@ -1881,9 +1881,9 @@ TEST_F(AccountReconcilorMirrorTest, GetAccountsFromCookieFailure) {
TEST_F(AccountReconcilorMirrorTest, ExtraCookieChangeNotification) {
AccountInfo account_info = ConnectProfileToAccount(kFakeEmail);
const CoreAccountId account_id = account_info.account_id;
signin::CookieParams cookie_params = {
account_info.email, account_info.gaia, false /* valid */,
false /* signed_out */, true /* verified */};
gaia::CookieParams cookie_params = {account_info.email, account_info.gaia,
false /* valid */, false /* signed_out */,
true /* verified */};
signin::SetListAccountsResponseOneAccountWithParams(
cookie_params, &test_url_loader_factory_);
@ -3063,7 +3063,7 @@ TEST_F(AccountReconcilorTest, OnAccountsInCookieUpdatedLogoutInProgress) {
signin::AccountConsistencyMethod account_consistency =
signin::AccountConsistencyMethod::kDice;
SetAccountConsistency(account_consistency);
signin::CookieParams cookie_params = {
gaia::CookieParams cookie_params = {
kFakeEmail, signin::GetTestGaiaIdForEmail(kFakeEmail), true /* valid */,
false /* signed_out */, true /* verified */};

@ -4,11 +4,11 @@
#include "components/signin/public/base/list_accounts_test_utils.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "google_apis/gaia/gaia_auth_test_util.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_id.h"
#include "google_apis/gaia/gaia_features.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/base/url_util.h"
#include "services/network/test/test_url_loader_factory.h"
namespace signin {
@ -41,28 +41,22 @@ void SetListAccountsResponseWithUnexpectedServiceResponse(
}
void SetListAccountsResponseWithParams(
const std::vector<CookieParams>& params,
const std::vector<gaia::CookieParams>& params,
TestURLLoaderFactory* test_url_loader_factory) {
std::vector<std::string> response_body;
for (const auto& param : params) {
std::string response_part = base::StringPrintf(
"[\"b\", 0, \"n\", \"%s\", \"p\", 0, 0, 0, 0, %d, \"%s\"",
param.email.c_str(), param.valid ? 1 : 0,
param.gaia_id.ToString().c_str());
if (param.signed_out || !param.verified) {
response_part +=
base::StringPrintf(", null, null, null, %d, %d",
param.signed_out ? 1 : 0, param.verified ? 1 : 0);
}
response_part += "]";
response_body.push_back(response_part);
}
test_url_loader_factory->AddResponse(
const std::string url =
GaiaUrls::GetInstance()
->ListAccountsURLWithSource(GaiaConstants::kChromeSource)
.spec(),
std::string("[\"f\", [") + base::JoinString(response_body, ", ") + "]]");
.spec();
std::string value;
bool uses_binary_format =
net::GetValueForKeyInQuery(GURL(url), "laf", &value) && value == "b64bin";
std::string content =
uses_binary_format
? gaia::CreateListAccountsResponseInBinaryFormat(params)
: gaia::CreateListAccountsResponseInLegacyFormat(params);
test_url_loader_factory->AddResponse(url, content);
}
void SetListAccountsResponseNoAccounts(
@ -74,13 +68,13 @@ void SetListAccountsResponseOneAccount(
const std::string& email,
const GaiaId& gaia_id,
TestURLLoaderFactory* test_url_loader_factory) {
CookieParams params = {email, gaia_id, /*valid=*/true,
/*signed_out=*/false, /*verified=*/true};
gaia::CookieParams params = {email, gaia_id, /*valid=*/true,
/*signed_out=*/false, /*verified=*/true};
SetListAccountsResponseWithParams({params}, test_url_loader_factory);
}
void SetListAccountsResponseOneAccountWithParams(
const CookieParams& params,
const gaia::CookieParams& params,
TestURLLoaderFactory* test_url_loader_factory) {
SetListAccountsResponseWithParams({params}, test_url_loader_factory);
}

@ -7,7 +7,7 @@
#include <string>
#include <vector>
#include "google_apis/gaia/gaia_id.h"
#include "google_apis/gaia/gaia_auth_test_util.h"
namespace network {
class TestURLLoaderFactory;
@ -15,15 +15,6 @@ class TestURLLoaderFactory;
namespace signin {
// Parameters for the fake ListAccounts response.
struct CookieParams {
std::string email;
GaiaId gaia_id;
bool valid;
bool signed_out;
bool verified;
};
// Make ListAccounts call return NotFound.
void SetListAccountsResponseHttpNotFound(
network::TestURLLoaderFactory* test_url_loader_factory);
@ -35,7 +26,7 @@ void SetListAccountsResponseWithUnexpectedServiceResponse(
// Make ListAccounts return a list of accounts based on the provided |params|.
void SetListAccountsResponseWithParams(
const std::vector<CookieParams>& params,
const std::vector<gaia::CookieParams>& params,
network::TestURLLoaderFactory* test_url_loader_factory);
// Helper methods, equivalent to calling
@ -54,7 +45,7 @@ void SetListAccountsResponseOneAccount(
// Make ListAccounts return one account based on the provided |params|.
void SetListAccountsResponseOneAccountWithParams(
const CookieParams& params,
const gaia::CookieParams& params,
network::TestURLLoaderFactory* test_url_loader_factory);
// Make ListAccounts return two accounts with the provided emails and gaia_ids.

@ -562,7 +562,7 @@ void SetCookieAccounts(
network::TestURLLoaderFactory* test_url_loader_factory,
const std::vector<CookieParamsForTest>& cookie_accounts) {
// Convert |cookie_accounts| to the format list_accounts_test_utils wants.
std::vector<CookieParams> gaia_cookie_accounts;
std::vector<gaia::CookieParams> gaia_cookie_accounts;
for (const CookieParamsForTest& params : cookie_accounts) {
gaia_cookie_accounts.push_back({params.email, params.gaia_id,
/*valid=*/true, params.signed_out,

@ -98,7 +98,7 @@ class ChildAccountServiceTest : public ::testing::Test {
PrefService& GetUserPerferences() { return syncable_pref_service_; }
void SetListAccountsResponseAndTriggerCookieJarUpdate(
const signin::CookieParams& params) {
const gaia::CookieParams& params) {
signin::SetListAccountsResponseOneAccountWithParams(
params, GetTestURLLoaderFactory());
GetAccountsCookieMutator()->TriggerCookieJarUpdate();

@ -31,7 +31,9 @@
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "google_apis/gaia/gaia_auth_consumer.h"
#include "google_apis/gaia/gaia_auth_test_util.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_features.h"
#include "google_apis/gaia/gaia_id.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/base/url_util.h"
@ -75,10 +77,6 @@ const base::FilePath::CharType kEmbeddedSetupChromeos[] =
const char kAuthHeaderBearer[] = "Bearer ";
const char kAuthHeaderOAuth[] = "OAuth ";
const char kIndividualListedAccountResponseFormat[] =
"[\"gaia.l.a\",1,\"\",\"%s\",\"\",1,1,0,0,1,\"%s\",11,12,13,%d]";
const char kListAccountsResponseFormat[] = "[\"gaia.l.a.r\",[%s]]";
const char kFakeRemoveLocalAccountPath[] = "FakeRemoveLocalAccount";
const char kFakeSAMLContinuePath[] = "FakeSAMLContinue";
@ -775,26 +773,34 @@ void FakeGaia::HandleIssueToken(const HttpRequest& request,
void FakeGaia::HandleListAccounts(const HttpRequest& request,
BasicHttpResponse* http_response) {
const int kAccountIsSignedIn = 0;
const int kAccountIsSignedOut = 1;
std::vector<std::string> listed_accounts;
listed_accounts.push_back(base::StringPrintf(
kIndividualListedAccountResponseFormat, configuration_.email.c_str(),
GetDefaultGaiaId().ToString(), kAccountIsSignedIn));
// Add the primary signed in account.
std::vector<gaia::CookieParams> params{{.email = configuration_.email,
.gaia_id = GetDefaultGaiaId(),
.valid = true,
.signed_out = false,
.verified = true}};
// Add the other signed out accounts.
for (const GaiaId& gaia_id : configuration_.signed_out_gaia_ids) {
DCHECK_NE(GetDefaultGaiaId(), gaia_id);
const std::string email = GetEmailOfGaiaId(gaia_id);
listed_accounts.push_back(base::StringPrintf(
kIndividualListedAccountResponseFormat, email.c_str(),
gaia_id.ToString().c_str(), kAccountIsSignedOut));
params.push_back({.email = GetEmailOfGaiaId(gaia_id),
.gaia_id = gaia_id,
.valid = true,
.signed_out = true,
.verified = true});
}
http_response->set_content(
base::StringPrintf(kListAccountsResponseFormat,
base::JoinString(listed_accounts, ",").c_str()));
std::string value;
bool uses_binary_format =
net::GetValueForKeyInQuery(request.GetURL(), "laf", &value) &&
value == "b64bin";
std::string content =
uses_binary_format
? gaia::CreateListAccountsResponseInBinaryFormat(params)
: gaia::CreateListAccountsResponseInLegacyFormat(params);
http_response->set_content(content);
http_response->set_code(net::HTTP_OK);
}

@ -4,27 +4,78 @@
#include "google_apis/gaia/gaia_auth_test_util.h"
#include "base/base64.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "google_apis/gaia/gaia_id.h"
#include "google_apis/gaia/list_accounts_response.pb.h"
#include "google_apis/gaia/oauth2_mint_token_consent_result.pb.h"
namespace gaia {
#include "google_apis/gaia/gaia_id.h"
std::string GenerateOAuth2MintTokenConsentResult(
std::optional<bool> approved,
const std::optional<std::string>& encrypted_approval_data,
const std::optional<GaiaId>& obfuscated_id,
base::Base64UrlEncodePolicy encode_policy) {
OAuth2MintTokenConsentResult consent_result;
if (approved.has_value())
if (approved.has_value()) {
consent_result.set_approved(approved.value());
if (encrypted_approval_data.has_value())
}
if (encrypted_approval_data.has_value()) {
consent_result.set_encrypted_approval_data(encrypted_approval_data.value());
if (obfuscated_id.has_value())
}
if (obfuscated_id.has_value()) {
consent_result.set_obfuscated_id(obfuscated_id->ToString());
}
std::string serialized_consent = consent_result.SerializeAsString();
std::string encoded_consent;
base::Base64UrlEncode(serialized_consent, encode_policy, &encoded_consent);
return encoded_consent;
}
std::string CreateListAccountsResponseInBinaryFormat(
const std::vector<gaia::CookieParams>& params) {
gaia::ListAccountsResponse response;
for (const auto& param : params) {
gaia::Account* account = response.add_account();
account->set_display_email(param.email);
account->set_valid_session(param.valid);
account->set_obfuscated_id(param.gaia_id.ToString());
account->set_signed_out(param.signed_out);
account->set_is_verified(param.verified);
}
std::string serialized_response;
response.SerializeToString(&serialized_response);
return base::Base64Encode(serialized_response);
}
std::string CreateListAccountsResponseInLegacyFormat(
const std::vector<gaia::CookieParams>& params) {
std::vector<std::string> response_body;
for (const auto& param : params) {
std::string response_part = base::StringPrintf(
"[\"b\", 0, \"n\", \"%s\", \"p\", 0, 0, 0, 0, %d, \"%s\"",
param.email.c_str(), param.valid ? 1 : 0,
param.gaia_id.ToString().c_str());
if (param.signed_out || !param.verified) {
response_part +=
base::StringPrintf(", null, null, null, %d, %d",
param.signed_out ? 1 : 0, param.verified ? 1 : 0);
}
response_part += "]";
response_body.push_back(response_part);
}
return std::string("[\"f\", [") + base::JoinString(response_body, ", ") +
"]]";
}
} // namespace gaia

@ -13,6 +13,15 @@
namespace gaia {
// Parameters for the fake ListAccounts response.
struct CookieParams {
std::string email;
GaiaId gaia_id;
bool valid;
bool signed_out;
bool verified;
};
std::string GenerateOAuth2MintTokenConsentResult(
std::optional<bool> approved,
const std::optional<std::string>& encrypted_approval_data,
@ -20,6 +29,14 @@ std::string GenerateOAuth2MintTokenConsentResult(
base::Base64UrlEncodePolicy encode_policy =
base::Base64UrlEncodePolicy::OMIT_PADDING);
// Creates the content for listing accounts in binary format.
std::string CreateListAccountsResponseInBinaryFormat(
const std::vector<CookieParams>& params);
// Creates the content for listing accounts.
std::string CreateListAccountsResponseInLegacyFormat(
const std::vector<CookieParams>& params);
} // namespace gaia
#endif // GOOGLE_APIS_GAIA_GAIA_AUTH_TEST_UTIL_H_

@ -14056,6 +14056,27 @@
]
}
],
"ListAccountsUsesBinaryFormat": [
{
"platforms": [
"android",
"chromeos",
"fuchsia",
"ios",
"linux",
"mac",
"windows"
],
"experiments": [
{
"name": "Enabled",
"enable_features": [
"ListAccountsUsesBinaryFormat"
]
}
]
}
],
"LiveCaptionChromeOS2": [
{
"platforms": [