0

[gaia] Make kAccessDenied a Scope Limited Unrecoverable error

This limits retries and returns error immediately if the user does not
have access to the OAuth scope.

Bug: 408045334
Fixed: 408932081
Change-Id: I7b98804ff32001101f92f0c4d7864001623f94de
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6434801
Reviewed-by: Erik Chen <erikchen@chromium.org>
Reviewed-by: Boris Sazonov <bsazonov@chromium.org>
Commit-Queue: Duncan Mercer <mercerd@google.com>
Reviewed-by: David Roger <droger@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1443581}
This commit is contained in:
Alex Ilin
2025-04-07 10:16:48 -07:00
committed by Chromium LUCI CQ
parent 6eb85e8583
commit 7eda61c40f
6 changed files with 27 additions and 5 deletions

@ -7,7 +7,7 @@
// versioning. Bump this value before making a change to any of the following
// interfaces / enums.
//
// Next MinVersion: 17
// Next MinVersion: 18
module crosapi.mojom;
@ -91,13 +91,14 @@ struct GoogleServiceAuthError {
kCredentialsMissing = 3,
};
// Next value: 5
// Next value: 6
enum ScopeLimitedUnrecoverableErrorReason {
kInvalidGrantRaptError = 0,
kInvalidScope = 1,
kRestrictedClient = 2,
kAdminPolicyEnforced = 3,
kRemoteConsentResolutionRequired = 4,
kAccessDenied = 5,
};
State state@0;

@ -95,6 +95,10 @@ FromMojoScopeLimitedUnrecoverableErrorReason(
kRemoteConsentResolutionRequired:
return GoogleServiceAuthError::ScopeLimitedUnrecoverableErrorReason::
kRemoteConsentResolutionRequired;
case cm::GoogleServiceAuthError::ScopeLimitedUnrecoverableErrorReason::
kAccessDenied:
return GoogleServiceAuthError::ScopeLimitedUnrecoverableErrorReason::
kAccessDenied;
}
}
@ -122,6 +126,10 @@ ToMojoScopeLimitedUnrecoverableErrorReason(
kRemoteConsentResolutionRequired:
return cm::GoogleServiceAuthError::ScopeLimitedUnrecoverableErrorReason::
kRemoteConsentResolutionRequired;
case GoogleServiceAuthError::ScopeLimitedUnrecoverableErrorReason::
kAccessDenied:
return cm::GoogleServiceAuthError::ScopeLimitedUnrecoverableErrorReason::
kAccessDenied;
}
}

@ -50,6 +50,8 @@ const char* ScopeLimitedUnrecoverableErrorReasonToString(
return "admin policy enforced";
case kRemoteConsentResolutionRequired:
return "remote consent resolution required";
case kAccessDenied:
return "access denied";
}
NOTREACHED();
}

@ -128,7 +128,9 @@ class COMPONENT_EXPORT(GOOGLE_APIS) GoogleServiceAuthError {
// Scope restricted by admin policy.
kAdminPolicyEnforced,
// The user doesn't have consent for this scope.
kRemoteConsentResolutionRequired
kRemoteConsentResolutionRequired,
// The user doesn't have access to this scope.
kAccessDenied
};
bool operator==(const GoogleServiceAuthError &b) const;

@ -274,7 +274,6 @@ void OAuth2AccessTokenFetcherImpl::EndGetAccessToken(
case kRateLimitExceeded:
case kInternalFailure:
case kAccessDenied:
// Transient error.
error = GoogleServiceAuthError::FromServiceUnavailable(response_str);
break;
@ -302,6 +301,12 @@ void OAuth2AccessTokenFetcherImpl::EndGetAccessToken(
kAdminPolicyEnforced);
break;
case kAccessDenied:
error = GoogleServiceAuthError::FromScopeLimitedUnrecoverableErrorReason(
GoogleServiceAuthError::ScopeLimitedUnrecoverableErrorReason::
kAccessDenied);
break;
case kInvalidRequest:
case kInvalidClient:
case kUnauthorizedClient:

@ -405,6 +405,10 @@ class OAuth2ErrorCodesTest
return GoogleServiceAuthError::ScopeLimitedUnrecoverableErrorReason::
kAdminPolicyEnforced;
}
if (error_code == "access_denied") {
return GoogleServiceAuthError::ScopeLimitedUnrecoverableErrorReason::
kAccessDenied;
}
NOTREACHED();
}
};
@ -437,7 +441,7 @@ const OAuth2ErrorCodesTestParam kOAuth2ErrorCodesTable[] = {
OAuth2Response::kAdminPolicyEnforced,
GoogleServiceAuthError::SCOPE_LIMITED_UNRECOVERABLE_ERROR},
{"access_denied", net::HTTP_FORBIDDEN, OAuth2Response::kAccessDenied,
GoogleServiceAuthError::SERVICE_UNAVAILABLE},
GoogleServiceAuthError::SCOPE_LIMITED_UNRECOVERABLE_ERROR},
{"", net::HTTP_BAD_REQUEST, OAuth2Response::kErrorUnexpectedFormat,
GoogleServiceAuthError::SERVICE_ERROR},
{"", net::HTTP_OK, OAuth2Response::kOkUnexpectedFormat,