0

[code health] Using ReadDict to simplify some JSON parsing

Replaced the base::JSONReader::Read call with
base::JSONReader::ReadDict for more concise and
direct parsing of JSON dictionaries.

Bug: 40912723
Change-Id: I4cfb47ba8a73d700ca4d9d8ad220fe49239a828b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6252218
Reviewed-by: Alex Ilin <alexilin@chromium.org>
Commit-Queue: Ho Cheung <hocheung@chromium.org>
Reviewed-by: David Roger <droger@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1419171}
This commit is contained in:
Ho Cheung
2025-02-12 01:43:34 -08:00
committed by Chromium LUCI CQ
parent 2d786126a4
commit aafd8f45c9
5 changed files with 47 additions and 52 deletions

@ -50,20 +50,21 @@ constexpr char kJsonContentType[] = "application/json;charset=UTF-8";
std::unique_ptr<const GaiaAuthConsumer::ClientOAuthResult>
ExtractOAuth2TokenPairResponse(const std::string& data) {
std::optional<base::Value> value = base::JSONReader::Read(data);
if (!value || !value->is_dict())
std::optional<base::Value::Dict> dict = base::JSONReader::ReadDict(data);
if (!dict) {
return nullptr;
base::Value::Dict& dict = value->GetDict();
}
std::string* refresh_token = dict.FindString("refresh_token");
std::string* access_token = dict.FindString("access_token");
std::optional<int> expires_in_secs = dict.FindInt("expires_in");
if (!refresh_token || !access_token || !expires_in_secs.has_value())
std::string* refresh_token = dict->FindString("refresh_token");
std::string* access_token = dict->FindString("access_token");
std::optional<int> expires_in_secs = dict->FindInt("expires_in");
if (!refresh_token || !access_token || !expires_in_secs) {
return nullptr;
}
// Extract ID token when obtaining refresh token. Do not fail if absent,
// but log to keep track.
std::string* id_token = dict.FindString("id_token");
std::string* id_token = dict->FindString("id_token");
if (!id_token)
LOG(ERROR) << "Missing ID token on refresh token fetch response.";
gaia::TokenServiceFlags service_flags =
@ -71,14 +72,14 @@ ExtractOAuth2TokenPairResponse(const std::string& data) {
bool is_bound_to_key = false;
// If present, indicates special rules of how the token must be used.
std::string* refresh_token_type = dict.FindString("refresh_token_type");
std::string* refresh_token_type = dict->FindString("refresh_token_type");
if (refresh_token_type &&
base::EqualsCaseInsensitiveASCII(*refresh_token_type, "bound_to_key")) {
is_bound_to_key = true;
}
return std::make_unique<const GaiaAuthConsumer::ClientOAuthResult>(
*refresh_token, *access_token, expires_in_secs.value(),
*refresh_token, *access_token, *expires_in_secs,
service_flags.is_child_account,
service_flags.is_under_advanced_protection, is_bound_to_key);
}
@ -93,12 +94,12 @@ GetTokenRevocationStatusFromResponseData(const std::string& data,
if (response_code == net::HTTP_INTERNAL_SERVER_ERROR)
return GaiaAuthConsumer::TokenRevocationStatus::kServerError;
std::optional<base::Value> value = base::JSONReader::Read(data);
if (!value || !value->is_dict())
std::optional<base::Value::Dict> dict = base::JSONReader::ReadDict(data);
if (!dict) {
return GaiaAuthConsumer::TokenRevocationStatus::kUnknownError;
base::Value::Dict& dict = value->GetDict();
}
std::string* error = dict.FindString("error");
std::string* error = dict->FindString("error");
if (!error)
return GaiaAuthConsumer::TokenRevocationStatus::kUnknownError;
@ -111,12 +112,7 @@ GetTokenRevocationStatusFromResponseData(const std::string& data,
}
base::Value::Dict ParseJSONDict(const std::string& data) {
base::Value::Dict response_dict;
std::optional<base::Value> message_value = base::JSONReader::Read(data);
if (message_value && message_value->is_dict()) {
response_dict.Merge(std::move(message_value->GetDict()));
}
return response_dict;
return base::JSONReader::ReadDict(data).value_or(base::Value::Dict());
}
GaiaAuthConsumer::ReAuthProofTokenStatus ErrorMessageToReAuthProofTokenStatus(

@ -101,12 +101,13 @@ std::unique_ptr<GaiaConfig>* GaiaConfig::GetGlobalConfig() {
// static
std::unique_ptr<GaiaConfig> GaiaConfig::ReadConfigFromString(
const std::string& config_contents) {
std::optional<base::Value> dict = base::JSONReader::Read(config_contents);
if (!dict || !dict->is_dict()) {
std::optional<base::Value::Dict> dict =
base::JSONReader::ReadDict(config_contents);
if (!dict) {
LOG(FATAL) << "Couldn't parse Gaia config file";
}
return std::make_unique<GaiaConfig>(std::move(dict->GetDict()));
return std::make_unique<GaiaConfig>(std::move(*dict));
}
// static

@ -523,13 +523,13 @@ void GaiaOAuthClient::Core::HandleResponse(std::unique_ptr<std::string> body,
return;
}
std::optional<base::Value> message_value;
std::optional<base::Value::Dict> response_dict;
if (response_code == net::HTTP_OK && body) {
std::string data = std::move(*body);
message_value = base::JSONReader::Read(data);
response_dict = base::JSONReader::ReadDict(data);
}
if (!message_value.has_value() || !message_value->is_dict()) {
if (!response_dict) {
// If we don't have an access token yet and the the error was not
// RC_BAD_REQUEST, we may need to retry.
if ((max_retries_ != -1) && (num_retries_ >= max_retries_)) {
@ -542,15 +542,13 @@ void GaiaOAuthClient::Core::HandleResponse(std::unique_ptr<std::string> body,
return;
}
const base::Value::Dict& response_dict = message_value->GetDict();
RequestType type = request_type_;
request_type_ = NO_PENDING_REQUEST;
switch (type) {
case USER_EMAIL: {
std::string email;
if (const std::string* dict_value = response_dict.FindString("email")) {
if (const std::string* dict_value = response_dict->FindString("email")) {
email = *dict_value;
}
delegate_->OnGetUserEmailResponse(email);
@ -559,7 +557,7 @@ void GaiaOAuthClient::Core::HandleResponse(std::unique_ptr<std::string> body,
case USER_ID: {
std::string id;
if (const std::string* dict_value = response_dict.FindString("id")) {
if (const std::string* dict_value = response_dict->FindString("id")) {
id = *dict_value;
}
delegate_->OnGetUserIdResponse(id);
@ -567,12 +565,12 @@ void GaiaOAuthClient::Core::HandleResponse(std::unique_ptr<std::string> body,
}
case USER_INFO: {
delegate_->OnGetUserInfoResponse(response_dict);
delegate_->OnGetUserInfoResponse(*response_dict);
break;
}
case TOKEN_INFO: {
delegate_->OnGetTokenInfoResponse(response_dict);
delegate_->OnGetTokenInfoResponse(*response_dict);
break;
}
@ -580,17 +578,17 @@ void GaiaOAuthClient::Core::HandleResponse(std::unique_ptr<std::string> body,
case REFRESH_TOKEN: {
std::string access_token;
if (const std::string* dict_value =
response_dict.FindString(kAccessTokenValue)) {
response_dict->FindString(kAccessTokenValue)) {
access_token = *dict_value;
}
std::string refresh_token;
if (const std::string* dict_value =
response_dict.FindString(kRefreshTokenValue)) {
response_dict->FindString(kRefreshTokenValue)) {
refresh_token = *dict_value;
}
int expires_in_seconds = 0;
if (const std::optional<int> dict_value =
response_dict.FindInt(kExpiresInValue)) {
response_dict->FindInt(kExpiresInValue)) {
expires_in_seconds = *dict_value;
}
@ -609,7 +607,7 @@ void GaiaOAuthClient::Core::HandleResponse(std::unique_ptr<std::string> body,
}
case ACCOUNT_CAPABILITIES: {
delegate_->OnGetAccountCapabilitiesResponse(response_dict);
delegate_->OnGetAccountCapabilitiesResponse(*response_dict);
break;
}

@ -370,11 +370,11 @@ bool OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
const std::string& response_body,
OAuth2AccessTokenConsumer::TokenResponse* token_response) {
CHECK(token_response);
auto value = base::JSONReader::Read(response_body);
if (!value.has_value() || !value->is_dict())
auto dict = base::JSONReader::ReadDict(response_body);
if (!dict) {
return false;
}
const base::Value::Dict* dict = value->GetIfDict();
// Refresh and id token are optional and don't cause an error if missing.
const std::string* refresh_token = dict->FindString(krefreshTokenKey);
if (refresh_token)
@ -408,11 +408,11 @@ bool OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenFailureResponse(
CHECK(error);
CHECK(error_subtype);
CHECK(error_description);
auto value = base::JSONReader::Read(response_body);
if (!value.has_value() || !value->is_dict())
auto dict = base::JSONReader::ReadDict(response_body);
if (!dict) {
return false;
}
const base::Value::Dict* dict = value->GetIfDict();
const std::string* error_value = dict->FindString(kErrorKey);
if (!error_value)
return false;

@ -87,8 +87,9 @@ static GoogleServiceAuthError CreateAuthError(
if (body)
response_body = std::move(*body);
std::optional<base::Value> value = base::JSONReader::Read(response_body);
if (!value || !value->is_dict()) {
std::optional<base::Value::Dict> value =
base::JSONReader::ReadDict(response_body);
if (!value) {
int http_response_code = -1;
if (head && head->headers)
http_response_code = head->headers->response_code();
@ -98,7 +99,7 @@ static GoogleServiceAuthError CreateAuthError(
"HTTP Status of the response is: %d",
http_response_code));
}
const base::Value::Dict* error = value->GetDict().FindDict(kError);
const base::Value::Dict* error = value->FindDict(kError);
if (!error) {
return GoogleServiceAuthError::FromUnexpectedServiceResponse(
"Not able to find a detailed error in a service response.");
@ -325,17 +326,16 @@ void OAuth2MintTokenFlow::ProcessApiCallSuccess(
response_body = std::move(*body);
}
std::optional<base::Value> value = base::JSONReader::Read(response_body);
if (!value || !value->is_dict()) {
std::optional<base::Value::Dict> dict =
base::JSONReader::ReadDict(response_body);
if (!dict) {
RecordApiCallResult(OAuth2MintTokenApiCallResult::kParseJsonFailure);
ReportFailure(GoogleServiceAuthError::FromUnexpectedServiceResponse(
"Not able to parse a JSON object from a service response."));
return;
}
base::Value::Dict& dict = value->GetDict();
std::string* issue_advice_value = dict.FindString(kIssueAdviceKey);
std::string* issue_advice_value = dict->FindString(kIssueAdviceKey);
if (!issue_advice_value) {
RecordApiCallResult(
OAuth2MintTokenApiCallResult::kIssueAdviceKeyNotFoundFailure);
@ -346,7 +346,7 @@ void OAuth2MintTokenFlow::ProcessApiCallSuccess(
if (*issue_advice_value == kIssueAdviceValueRemoteConsent) {
RemoteConsentResolutionData resolution_data;
if (ParseRemoteConsentResponse(dict, &resolution_data)) {
if (ParseRemoteConsentResponse(*dict, &resolution_data)) {
RecordApiCallResult(OAuth2MintTokenApiCallResult::kRemoteConsentSuccess);
ReportRemoteConsentSuccess(resolution_data);
} else {
@ -359,7 +359,7 @@ void OAuth2MintTokenFlow::ProcessApiCallSuccess(
return;
}
if (std::optional<MintTokenResult> result = ParseMintTokenResponse(dict);
if (std::optional<MintTokenResult> result = ParseMintTokenResponse(*dict);
result.has_value()) {
RecordApiCallResult(OAuth2MintTokenApiCallResult::kMintTokenSuccess);
ReportSuccess(result.value());