blob: 39a37f4fca42cd69be0f72fdbe7b3ee613ddf0c2 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/webid/fedcm_mappers.h"
#include <string>
#include <vector>
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/webid/fedcm_metrics.h"
#include "content/public/browser/identity_request_dialog_controller.h"
#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom.h"
#include "third_party/blink/public/mojom/webid/federated_auth_request.mojom.h"
using blink::mojom::FederatedAuthRequestResult;
using blink::mojom::RequestTokenStatus;
using ParseStatus = content::IdpNetworkRequestManager::ParseStatus;
using LifecycleStateImpl = content::RenderFrameHostImpl::LifecycleStateImpl;
namespace content {
std::vector<std::string> DisclosureFieldsToStringList(
const std::vector<IdentityRequestDialogDisclosureField>& fields) {
std::vector<std::string> list;
for (auto field : fields) {
switch (field) {
case IdentityRequestDialogDisclosureField::kName:
list.push_back(kFedCmDefaultFieldName);
break;
case IdentityRequestDialogDisclosureField::kEmail:
list.push_back(kFedCmDefaultFieldEmail);
break;
case IdentityRequestDialogDisclosureField::kPicture:
list.push_back(kFedCmDefaultFieldPicture);
break;
case IdentityRequestDialogDisclosureField::kPhoneNumber:
list.push_back(kFedCmFieldPhoneNumber);
break;
case IdentityRequestDialogDisclosureField::kUsername:
list.push_back(kFedCmFieldUsername);
break;
}
}
return list;
}
RequestTokenStatus FederatedAuthRequestResultToRequestTokenStatus(
FederatedAuthRequestResult result) {
// Avoids exposing to renderer detailed error messages which may leak cross
// site information to the API call site.
switch (result) {
case FederatedAuthRequestResult::kSuccess: {
return RequestTokenStatus::kSuccess;
}
case FederatedAuthRequestResult::kTooManyRequests: {
return RequestTokenStatus::kErrorTooManyRequests;
}
case FederatedAuthRequestResult::kCanceled: {
return RequestTokenStatus::kErrorCanceled;
}
case FederatedAuthRequestResult::kShouldEmbargo:
case FederatedAuthRequestResult::kIdpNotPotentiallyTrustworthy:
case FederatedAuthRequestResult::kDisabledInSettings:
case FederatedAuthRequestResult::kDisabledInFlags:
case FederatedAuthRequestResult::kWellKnownHttpNotFound:
case FederatedAuthRequestResult::kWellKnownNoResponse:
case FederatedAuthRequestResult::kWellKnownInvalidResponse:
case FederatedAuthRequestResult::kWellKnownListEmpty:
case FederatedAuthRequestResult::kWellKnownInvalidContentType:
case FederatedAuthRequestResult::kConfigNotInWellKnown:
case FederatedAuthRequestResult::kWellKnownTooBig:
case FederatedAuthRequestResult::kConfigHttpNotFound:
case FederatedAuthRequestResult::kConfigNoResponse:
case FederatedAuthRequestResult::kConfigInvalidResponse:
case FederatedAuthRequestResult::kConfigInvalidContentType:
case FederatedAuthRequestResult::kClientMetadataHttpNotFound:
case FederatedAuthRequestResult::kClientMetadataNoResponse:
case FederatedAuthRequestResult::kClientMetadataInvalidResponse:
case FederatedAuthRequestResult::kClientMetadataInvalidContentType:
case FederatedAuthRequestResult::kAccountsHttpNotFound:
case FederatedAuthRequestResult::kAccountsNoResponse:
case FederatedAuthRequestResult::kAccountsInvalidResponse:
case FederatedAuthRequestResult::kAccountsListEmpty:
case FederatedAuthRequestResult::kAccountsInvalidContentType:
case FederatedAuthRequestResult::kIdTokenHttpNotFound:
case FederatedAuthRequestResult::kIdTokenNoResponse:
case FederatedAuthRequestResult::kIdTokenInvalidResponse:
case FederatedAuthRequestResult::kIdTokenIdpErrorResponse:
case FederatedAuthRequestResult::kIdTokenCrossSiteIdpErrorResponse:
case FederatedAuthRequestResult::kIdTokenInvalidContentType:
case FederatedAuthRequestResult::kRpPageNotVisible:
case FederatedAuthRequestResult::kSilentMediationFailure:
case FederatedAuthRequestResult::kThirdPartyCookiesBlocked:
case FederatedAuthRequestResult::kNotSignedInWithIdp:
case FederatedAuthRequestResult::kMissingTransientUserActivation:
case FederatedAuthRequestResult::kReplacedByActiveMode:
case FederatedAuthRequestResult::kInvalidFieldsSpecified:
case FederatedAuthRequestResult::kRelyingPartyOriginIsOpaque:
case FederatedAuthRequestResult::kTypeNotMatching:
case FederatedAuthRequestResult::kUiDismissedNoEmbargo:
case FederatedAuthRequestResult::kCorsError:
case FederatedAuthRequestResult::kSuppressedBySegmentationPlatform:
case FederatedAuthRequestResult::kError: {
return RequestTokenStatus::kError;
}
}
}
MetricsEndpointErrorCode FederatedAuthRequestResultToMetricsEndpointErrorCode(
blink::mojom::FederatedAuthRequestResult result) {
switch (result) {
case FederatedAuthRequestResult::kSuccess: {
return MetricsEndpointErrorCode::kNone;
}
case FederatedAuthRequestResult::kTooManyRequests:
case FederatedAuthRequestResult::kMissingTransientUserActivation:
case FederatedAuthRequestResult::kRelyingPartyOriginIsOpaque:
case FederatedAuthRequestResult::kInvalidFieldsSpecified:
case FederatedAuthRequestResult::kCanceled: {
return MetricsEndpointErrorCode::kRpFailure;
}
case FederatedAuthRequestResult::kAccountsInvalidResponse:
case FederatedAuthRequestResult::kAccountsListEmpty:
case FederatedAuthRequestResult::kAccountsInvalidContentType: {
return MetricsEndpointErrorCode::kAccountsEndpointInvalidResponse;
}
case FederatedAuthRequestResult::kIdTokenInvalidResponse:
case FederatedAuthRequestResult::kIdTokenIdpErrorResponse:
case FederatedAuthRequestResult::kIdTokenCrossSiteIdpErrorResponse:
case FederatedAuthRequestResult::kIdTokenInvalidContentType:
case FederatedAuthRequestResult::kCorsError: {
return MetricsEndpointErrorCode::kTokenEndpointInvalidResponse;
}
case FederatedAuthRequestResult::kShouldEmbargo:
case FederatedAuthRequestResult::kUiDismissedNoEmbargo:
case FederatedAuthRequestResult::kDisabledInFlags:
case FederatedAuthRequestResult::kDisabledInSettings:
case FederatedAuthRequestResult::kThirdPartyCookiesBlocked:
case FederatedAuthRequestResult::kRpPageNotVisible:
case FederatedAuthRequestResult::kReplacedByActiveMode:
case FederatedAuthRequestResult::kNotSignedInWithIdp: {
return MetricsEndpointErrorCode::kUserFailure;
}
case FederatedAuthRequestResult::kWellKnownHttpNotFound:
case FederatedAuthRequestResult::kWellKnownNoResponse:
case FederatedAuthRequestResult::kConfigHttpNotFound:
case FederatedAuthRequestResult::kConfigNoResponse:
case FederatedAuthRequestResult::kClientMetadataHttpNotFound:
case FederatedAuthRequestResult::kClientMetadataNoResponse:
case FederatedAuthRequestResult::kAccountsHttpNotFound:
case FederatedAuthRequestResult::kAccountsNoResponse:
case FederatedAuthRequestResult::kIdTokenHttpNotFound:
case FederatedAuthRequestResult::kIdTokenNoResponse: {
return MetricsEndpointErrorCode::kIdpServerUnavailable;
}
case FederatedAuthRequestResult::kConfigNotInWellKnown:
case FederatedAuthRequestResult::kWellKnownTooBig: {
return MetricsEndpointErrorCode::kManifestError;
}
case FederatedAuthRequestResult::kWellKnownListEmpty:
case FederatedAuthRequestResult::kWellKnownInvalidResponse:
case FederatedAuthRequestResult::kConfigInvalidResponse:
case FederatedAuthRequestResult::kClientMetadataInvalidResponse:
case FederatedAuthRequestResult::kWellKnownInvalidContentType:
case FederatedAuthRequestResult::kConfigInvalidContentType:
case FederatedAuthRequestResult::kClientMetadataInvalidContentType: {
return MetricsEndpointErrorCode::kIdpServerInvalidResponse;
}
case FederatedAuthRequestResult::kIdpNotPotentiallyTrustworthy:
case FederatedAuthRequestResult::kError:
case FederatedAuthRequestResult::kSilentMediationFailure:
case FederatedAuthRequestResult::kTypeNotMatching:
case FederatedAuthRequestResult::kSuppressedBySegmentationPlatform: {
return MetricsEndpointErrorCode::kOther;
}
}
}
std::pair<FederatedAuthRequestResult, FedCmRequestIdTokenStatus>
AccountParseStatusToRequestResultAndTokenStatus(ParseStatus parse_status) {
switch (parse_status) {
case ParseStatus::kHttpNotFoundError: {
return {FederatedAuthRequestResult::kAccountsHttpNotFound,
FedCmRequestIdTokenStatus::kAccountsHttpNotFound};
}
case ParseStatus::kNoResponseError: {
return {FederatedAuthRequestResult::kAccountsNoResponse,
FedCmRequestIdTokenStatus::kAccountsNoResponse};
}
case ParseStatus::kInvalidResponseError: {
return {FederatedAuthRequestResult::kAccountsInvalidResponse,
FedCmRequestIdTokenStatus::kAccountsInvalidResponse};
}
case ParseStatus::kEmptyListError: {
return {FederatedAuthRequestResult::kAccountsListEmpty,
FedCmRequestIdTokenStatus::kAccountsListEmpty};
}
case ParseStatus::kInvalidContentTypeError: {
return {FederatedAuthRequestResult::kAccountsInvalidContentType,
FedCmRequestIdTokenStatus::kAccountsInvalidContentType};
}
case ParseStatus::kSuccess: {
NOTREACHED() << "Should not be invoked on success";
}
}
}
FedCmLifecycleStateFailureReason
LifecycleStateImplLifecycleStateImplToFedCmLifecycleStateFailureReason(
LifecycleStateImpl lifecycle_state) {
switch (lifecycle_state) {
case LifecycleStateImpl::kSpeculative: {
return FedCmLifecycleStateFailureReason::kSpeculative;
}
case LifecycleStateImpl::kPendingCommit: {
return FedCmLifecycleStateFailureReason::kPendingCommit;
}
case LifecycleStateImpl::kPrerendering: {
return FedCmLifecycleStateFailureReason::kPrerendering;
}
case LifecycleStateImpl::kInBackForwardCache: {
return FedCmLifecycleStateFailureReason::kInBackForwardCache;
}
case LifecycleStateImpl::kRunningUnloadHandlers: {
return FedCmLifecycleStateFailureReason::kRunningUnloadHandlers;
}
case LifecycleStateImpl::kReadyToBeDeleted: {
return FedCmLifecycleStateFailureReason::kReadyToBeDeleted;
}
default: {
return FedCmLifecycleStateFailureReason::kOther;
}
}
}
} // namespace content