Ash: Treat RAPT errors as SCOPE_LIMITED_UNRECOVERABLE_ERROR
Treat RAPT errors as SCOPE_LIMITED_UNRECOVERABLE_ERROR on Ash. Please check the attached bug for context. Bug: b/295127872 Test: google_apis_unittests --gtest_filter="*OAuth2AccessTokenFetcherImplTest*" Change-Id: I0c4e3379ccbe78642763d5c407e485e64a77198b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4765130 Reviewed-by: Anastasiia N <anastasiian@chromium.org> Commit-Queue: Kush Sinha <sinhak@chromium.org> Reviewed-by: Monica Basta <msalama@chromium.org> Cr-Commit-Position: refs/heads/main@{#1184643}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
ba5ca05406
commit
2c0e568975
@ -189,7 +189,7 @@ std::string GoogleServiceAuthError::ToString() const {
|
||||
return base::StringPrintf("Service responded with error: '%s'",
|
||||
error_message_.c_str());
|
||||
case SCOPE_LIMITED_UNRECOVERABLE_ERROR:
|
||||
return base::StringPrintf("Service responded with error: '%s'",
|
||||
return base::StringPrintf("OAuth scope error: '%s'",
|
||||
error_message_.c_str());
|
||||
case CHALLENGE_RESPONSE_REQUIRED:
|
||||
return "Service responded with a token binding challenge.";
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include "google_apis/gaia/oauth2_access_token_fetcher_impl.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -16,6 +15,7 @@
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
#include "build/chromeos_buildflags.h"
|
||||
#include "google_apis/credentials_mode.h"
|
||||
#include "google_apis/gaia/gaia_auth_util.h"
|
||||
#include "google_apis/gaia/google_service_auth_error.h"
|
||||
@ -25,6 +25,12 @@
|
||||
#include "services/network/public/cpp/simple_url_loader.h"
|
||||
#include "services/network/public/mojom/url_response_head.mojom.h"
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
BASE_FEATURE(kIgnoreRaptErrors,
|
||||
"IgnoreRaptErrors",
|
||||
base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char kGetAccessTokenBodyFormat[] =
|
||||
@ -54,6 +60,11 @@ constexpr char kErrorKey[] = "error";
|
||||
constexpr char kErrorSubTypeKey[] = "error_subtype";
|
||||
constexpr char kErrorDescriptionKey[] = "error_description";
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
constexpr char kRaptRequiredError[] = "rapt_required";
|
||||
constexpr char kInvalidRaptError[] = "invalid_rapt";
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
||||
OAuth2AccessTokenFetcherImpl::OAuth2Response
|
||||
OAuth2ResponseErrorToOAuth2Response(const std::string& error) {
|
||||
if (error.empty())
|
||||
@ -120,6 +131,33 @@ static std::unique_ptr<network::SimpleURLLoader> CreateURLLoader(
|
||||
|
||||
return url_loader;
|
||||
}
|
||||
|
||||
GoogleServiceAuthError CreateErrorForInvalidGrant(
|
||||
const std::string& error_subtype,
|
||||
const std::string& error_description) {
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
if (base::FeatureList::IsEnabled(kIgnoreRaptErrors)) {
|
||||
// ChromeOS cannot handle RAPT-type re-authentication requests and is
|
||||
// supposed to be excluded from RAPT re-authentication on the server side.
|
||||
// Just to be safe we need to handle this anyways. If we do not handle this,
|
||||
// any service requesting a RAPT re-auth protected OAuth scope can
|
||||
// potentially invalidate the entire ChromeOS session and send the user into
|
||||
// a never ending re-authentication loop.
|
||||
std::string error_subtype_lowercase = base::ToLowerASCII(error_subtype);
|
||||
if (error_subtype_lowercase == kRaptRequiredError ||
|
||||
error_subtype_lowercase == kInvalidRaptError) {
|
||||
return GoogleServiceAuthError::FromScopeLimitedUnrecoverableError(
|
||||
error_description);
|
||||
}
|
||||
}
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
||||
// Persistent error requiring the user to sign in again.
|
||||
return GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
|
||||
GoogleServiceAuthError::InvalidGaiaCredentialsReason::
|
||||
CREDENTIALS_REJECTED_BY_SERVER);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
OAuth2AccessTokenFetcherImpl::OAuth2AccessTokenFetcherImpl(
|
||||
@ -229,10 +267,7 @@ void OAuth2AccessTokenFetcherImpl::EndGetAccessToken(
|
||||
break;
|
||||
|
||||
case kInvalidGrant:
|
||||
// Persistent error requiring the user to sign in again.
|
||||
error = GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
|
||||
GoogleServiceAuthError::InvalidGaiaCredentialsReason::
|
||||
CREDENTIALS_REJECTED_BY_SERVER);
|
||||
error = CreateErrorForInvalidGrant(error_subtype, error_description);
|
||||
break;
|
||||
|
||||
case kInvalidScope:
|
||||
@ -277,9 +312,7 @@ void OAuth2AccessTokenFetcherImpl::EndGetAccessToken(
|
||||
// HTTP_BAD_REQUEST errors usually contains errors as per
|
||||
// http://tools.ietf.org/html/rfc6749#section-5.2.
|
||||
if (response == kInvalidGrant) {
|
||||
error = GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
|
||||
GoogleServiceAuthError::InvalidGaiaCredentialsReason::
|
||||
CREDENTIALS_REJECTED_BY_SERVER);
|
||||
error = CreateErrorForInvalidGrant(error_subtype, error_description);
|
||||
} else {
|
||||
error = GoogleServiceAuthError::FromServiceError(response_str);
|
||||
}
|
||||
|
@ -10,8 +10,10 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/component_export.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "build/chromeos_buildflags.h"
|
||||
#include "google_apis/gaia/oauth2_access_token_consumer.h"
|
||||
#include "google_apis/gaia/oauth2_access_token_fetcher.h"
|
||||
#include "net/traffic_annotation/network_traffic_annotation.h"
|
||||
@ -24,6 +26,10 @@ class SimpleURLLoader;
|
||||
class SharedURLLoaderFactory;
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
COMPONENT_EXPORT(GOOGLE_APIS) BASE_DECLARE_FEATURE(kIgnoreRaptErrors);
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
||||
// Abstracts the details to get OAuth2 access token from OAuth2 refresh token.
|
||||
// See general document about Oauth2 in https://tools.ietf.org/html/rfc6749.
|
||||
//
|
||||
|
@ -13,8 +13,10 @@
|
||||
#include "base/run_loop.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/test/metrics/histogram_tester.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "base/time/time.h"
|
||||
#include "build/chromeos_buildflags.h"
|
||||
#include "google_apis/gaia/gaia_access_token_fetcher.h"
|
||||
#include "google_apis/gaia/gaia_urls.h"
|
||||
#include "google_apis/gaia/google_service_auth_error.h"
|
||||
@ -222,6 +224,38 @@ TEST_F(OAuth2AccessTokenFetcherImplTest, CancelOngoingRequest) {
|
||||
base::RunLoop().RunUntilIdle();
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
TEST_F(OAuth2AccessTokenFetcherImplTest, GetAccessTokenRaptRequiredFailure) {
|
||||
base::test::ScopedFeatureList feature_list;
|
||||
feature_list.InitAndEnableFeature(kIgnoreRaptErrors);
|
||||
SetupGetAccessToken(net::OK, net::HTTP_BAD_REQUEST,
|
||||
kRaptRequiredErrorResponse);
|
||||
EXPECT_CALL(consumer_,
|
||||
OnGetTokenFailure(
|
||||
GoogleServiceAuthError::FromScopeLimitedUnrecoverableError(
|
||||
"reauth related error")))
|
||||
.Times(1);
|
||||
fetcher_->Start("client_id", "client_secret", ScopeList());
|
||||
base::RunLoop().RunUntilIdle();
|
||||
}
|
||||
|
||||
TEST_F(OAuth2AccessTokenFetcherImplTest,
|
||||
GetAccessTokenRaptRequiredFailureIfIgnoreRaptErrorsIsDisabled) {
|
||||
base::test::ScopedFeatureList feature_list;
|
||||
feature_list.InitAndDisableFeature(kIgnoreRaptErrors);
|
||||
SetupGetAccessToken(net::OK, net::HTTP_BAD_REQUEST,
|
||||
kRaptRequiredErrorResponse);
|
||||
EXPECT_CALL(consumer_,
|
||||
OnGetTokenFailure(
|
||||
GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
|
||||
GoogleServiceAuthError::InvalidGaiaCredentialsReason::
|
||||
CREDENTIALS_REJECTED_BY_SERVER)))
|
||||
.Times(1);
|
||||
fetcher_->Start("client_id", "client_secret", ScopeList());
|
||||
base::RunLoop().RunUntilIdle();
|
||||
}
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
|
||||
TEST_F(OAuth2AccessTokenFetcherImplTest, MakeGetAccessTokenBodyNoScope) {
|
||||
std::string body =
|
||||
"client_id=cid1&"
|
||||
|
Reference in New Issue
Block a user