0

Revert "Remove FedCmIdpSigninStatus feature flag and runtime flag"

This reverts commit 67311fb00c.

Reason for revert: See crbug.com/384866916

Original change's description:
> Remove FedCmIdpSigninStatus feature flag and runtime flag
>
> Bug: 381211734
> Change-Id: I41f8f8bcf308a685533980da7d16e2b634a11636
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6078693
> Reviewed-by: Alex Rudenko <alexrudenko@chromium.org>
> Commit-Queue: suresh potti <sureshpotti@microsoft.com>
> Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
> Reviewed-by: Nicolás Peña <npm@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1397709}

Bug: 381211734
Change-Id: I9f8fb3f45e294ec696b4d8f0ed659d5c7f7e2715
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6097148
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Adem Derinel <derinel@google.com>
Owners-Override: Adem Derinel <derinel@google.com>
Cr-Commit-Position: refs/heads/main@{#1397816}
This commit is contained in:
Adem Derinel
2024-12-18 02:16:07 -08:00
committed by Chromium LUCI CQ
parent 6aa32e348a
commit e125c793de
18 changed files with 177 additions and 30 deletions

@@ -8685,7 +8685,8 @@ class FedCmSpecificTest(ChromeDriverBaseTestWithWebServer):
'enable-experimental-web-platform-features'] 'enable-experimental-web-platform-features']
self._driver = self.CreateDriver( self._driver = self.CreateDriver(
accept_insecure_certs=True, accept_insecure_certs=True,
chrome_switches=self.chrome_switches) chrome_switches=self.chrome_switches +
["--enable-features=FedCmIdpSigninStatusEnabled"])
self._driver.Load(self._url_prefix + "/mark-signed-in") self._driver.Load(self._url_prefix + "/mark-signed-in")

@@ -919,7 +919,9 @@ void FederatedAuthRequestImpl::RequestToken(
permission_delegate_); permission_delegate_);
url::Origin idp_origin = url::Origin::Create(idp_ptr->config->config_url); url::Origin idp_origin = url::Origin::Create(idp_ptr->config->config_url);
if (has_failing_idp_signin_status) { if (has_failing_idp_signin_status &&
webid::GetIdpSigninStatusMode(render_frame_host(), idp_origin) ==
FedCmIdpSigninStatusMode::ENABLED) {
if (idp_get_params_ptr->mode == blink::mojom::RpMode::kPassive) { if (idp_get_params_ptr->mode == blink::mojom::RpMode::kPassive) {
if (IsFedCmMultipleIdentityProvidersEnabled()) { if (IsFedCmMultipleIdentityProvidersEnabled()) {
// In the multi IDP case, we do not want to complete the request // In the multi IDP case, we do not want to complete the request
@@ -1322,7 +1324,11 @@ void FederatedAuthRequestImpl::OnAllConfigAndWellKnownFetched(
webid::ShouldFailAccountsEndpointRequestBecauseNotSignedInWithIdp( webid::ShouldFailAccountsEndpointRequestBecauseNotSignedInWithIdp(
render_frame_host(), identity_provider_config_url, render_frame_host(), identity_provider_config_url,
permission_delegate_); permission_delegate_);
if (idp_info->has_failing_idp_signin_status) { if (idp_info->has_failing_idp_signin_status &&
webid::GetIdpSigninStatusMode(
render_frame_host(),
url::Origin::Create(identity_provider_config_url)) ==
FedCmIdpSigninStatusMode::ENABLED) {
// If the user is logged out and we are in a active-mode, allow the user // If the user is logged out and we are in a active-mode, allow the user
// to sign-in to the IdP and return early. // to sign-in to the IdP and return early.
if (rp_mode_ == blink::mojom::RpMode::kActive) { if (rp_mode_ == blink::mojom::RpMode::kActive) {
@@ -1818,7 +1824,10 @@ void FederatedAuthRequestImpl::HandleAccountsFetchFailure(
std::optional<TokenStatus> token_status) { std::optional<TokenStatus> token_status) {
url::Origin idp_origin = url::Origin idp_origin =
url::Origin::Create(idp_info->provider->config->config_url); url::Origin::Create(idp_info->provider->config->config_url);
if (!old_idp_signin_status.has_value()) { FedCmIdpSigninStatusMode signin_status_mode =
webid::GetIdpSigninStatusMode(render_frame_host(), idp_origin);
if (!old_idp_signin_status.has_value() ||
signin_status_mode == FedCmIdpSigninStatusMode::METRICS_ONLY) {
if (rp_mode_ == blink::mojom::RpMode::kActive) { if (rp_mode_ == blink::mojom::RpMode::kActive) {
MaybeShowActiveModeModalDialog(idp_info->provider->config->config_url, MaybeShowActiveModeModalDialog(idp_info->provider->config->config_url,
idp_info->metadata.idp_login_url); idp_info->metadata.idp_login_url);

@@ -1905,26 +1905,16 @@ TEST_F(FederatedAuthRequestImplTest, MissingAccountsEndpoint) {
EXPECT_EQ("Provider's FedCM config file is invalid.", messages[1]); EXPECT_EQ("Provider's FedCM config file is invalid.", messages[1]);
} }
// Test that request fails if config is missing an IDP login URL. // Test that request does not fail if config is missing an IDP login URL.
TEST_F(FederatedAuthRequestImplTest, MissingLoginURL) { TEST_F(FederatedAuthRequestImplTest, MissingLoginURL) {
// Login URL is only optional when the signin status API is disabled.
base::test::ScopedFeatureList list;
list.InitAndDisableFeature(features::kFedCmIdpSigninStatusEnabled);
MockConfiguration configuration = kConfigurationValid; MockConfiguration configuration = kConfigurationValid;
configuration.idp_info[kProviderUrlFull].config.idp_login_url = ""; configuration.idp_info[kProviderUrlFull].config.idp_login_url = "";
RequestExpectations expectations = { RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
RequestTokenStatus::kError,
FederatedAuthRequestResult::kConfigInvalidResponse,
/*standalone_console_message=*/std::nullopt,
/*selected_idp_config_url=*/std::nullopt};
RunAuthTest(kDefaultRequestParameters, expectations, configuration);
EXPECT_TRUE(DidFetchWellKnownAndConfig()); EXPECT_TRUE(DidFetchWellKnownAndConfig());
std::vector<std::string> messages =
RenderFrameHostTester::For(main_rfh())->GetConsoleMessages();
ASSERT_EQ(2U, messages.size());
EXPECT_EQ(
"Config file is missing or has an invalid URL for the following:\n"
"\"login_url\"\n",
messages[0]);
EXPECT_EQ("Provider's FedCM config file is invalid.", messages[1]);
} }
// Test that client metadata endpoint is not required in config. // Test that client metadata endpoint is not required in config.
@@ -1954,6 +1944,10 @@ TEST_F(FederatedAuthRequestImplTest, AccountEndpointDifferentOriginIdp) {
// Test that request fails if IDP login URL is different origin from IDP config // Test that request fails if IDP login URL is different origin from IDP config
// URL. // URL.
TEST_F(FederatedAuthRequestImplTest, LoginUrlDifferentOriginIdp) { TEST_F(FederatedAuthRequestImplTest, LoginUrlDifferentOriginIdp) {
// We only validate the login_url if IdpSigninStatus is enabled.
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
MockConfiguration configuration = kConfigurationValid; MockConfiguration configuration = kConfigurationValid;
configuration.idp_info[kProviderUrlFull].config.idp_login_url = configuration.idp_info[kProviderUrlFull].config.idp_login_url =
"https://idp2.example/login_url"; "https://idp2.example/login_url";
@@ -3812,6 +3806,9 @@ TEST_F(FederatedAuthRequestImplTest, ReorderMultipleAccounts) {
// Test that first API call with a given IDP is not affected by the // Test that first API call with a given IDP is not affected by the
// IdpSigninStatus bit. // IdpSigninStatus bit.
TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusTestFirstTimeFetchSuccess) { TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusTestFirstTimeFetchSuccess) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
EXPECT_CALL(*test_permission_delegate_, EXPECT_CALL(*test_permission_delegate_,
SetIdpSigninStatus(OriginFromString(kProviderUrlFull), true)) SetIdpSigninStatus(OriginFromString(kProviderUrlFull), true))
.Times(1); .Times(1);
@@ -3829,6 +3826,9 @@ TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusTestFirstTimeFetchSuccess) {
// failure during fetching accounts. // failure during fetching accounts.
TEST_F(FederatedAuthRequestImplTest, TEST_F(FederatedAuthRequestImplTest,
IdpSigninStatusTestFirstTimeFetchNoFailureUi) { IdpSigninStatusTestFirstTimeFetchNoFailureUi) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
EXPECT_CALL(*test_permission_delegate_, EXPECT_CALL(*test_permission_delegate_,
SetIdpSigninStatus(OriginFromString(kProviderUrlFull), false)) SetIdpSigninStatus(OriginFromString(kProviderUrlFull), false))
.Times(1); .Times(1);
@@ -3849,6 +3849,9 @@ TEST_F(FederatedAuthRequestImplTest,
// Test that a failure UI will be displayed if the accounts fetch is failed but // Test that a failure UI will be displayed if the accounts fetch is failed but
// the IdpSigninStatus claims that the user is signed in. // the IdpSigninStatus claims that the user is signed in.
TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusTestShowFailureUi) { TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusTestShowFailureUi) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
test_permission_delegate_ test_permission_delegate_
->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true; ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;
@@ -3871,6 +3874,9 @@ TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusTestShowFailureUi) {
// UI is displayed. // UI is displayed.
TEST_F(FederatedAuthRequestImplTest, TEST_F(FederatedAuthRequestImplTest,
IdpSigninStatusTestApiFailedIfUserNotSignedInWithIdp) { IdpSigninStatusTestApiFailedIfUserNotSignedInWithIdp) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
test_permission_delegate_ test_permission_delegate_
->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = false; ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = false;
@@ -3947,6 +3953,9 @@ class ParseStatusOverrideIdpNetworkRequestManager
// 2) User signs-in // 2) User signs-in
// 3) User selects "Continue" in account chooser dialog. // 3) User selects "Continue" in account chooser dialog.
TEST_F(FederatedAuthRequestImplTest, FailureUiThenSuccessfulSignin) { TEST_F(FederatedAuthRequestImplTest, FailureUiThenSuccessfulSignin) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
SetNetworkRequestManager( SetNetworkRequestManager(
std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>()); std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>());
auto* network_manager = auto* network_manager =
@@ -3997,6 +4006,9 @@ TEST_F(FederatedAuthRequestImplTest, FailureUiThenSuccessfulSignin) {
// 2) User switches tabs // 2) User switches tabs
// 3) User signs into IdP in different tab // 3) User signs into IdP in different tab
TEST_F(FederatedAuthRequestImplTest, FailureUiThenSuccessfulSigninButHidden) { TEST_F(FederatedAuthRequestImplTest, FailureUiThenSuccessfulSigninButHidden) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
SetNetworkRequestManager( SetNetworkRequestManager(
std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>()); std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>());
auto* network_manager = auto* network_manager =
@@ -4046,6 +4058,9 @@ TEST_F(FederatedAuthRequestImplTest, FailureUiThenSuccessfulSigninButHidden) {
// 1) Failure dialog is shown due to IdP sign-in status mismatch // 1) Failure dialog is shown due to IdP sign-in status mismatch
// 2) In a different tab, user signs into different IdP // 2) In a different tab, user signs into different IdP
TEST_F(FederatedAuthRequestImplTest, FailureUiSigninFromDifferentIdp) { TEST_F(FederatedAuthRequestImplTest, FailureUiSigninFromDifferentIdp) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
SetNetworkRequestManager( SetNetworkRequestManager(
std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>()); std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>());
auto* network_manager = auto* network_manager =
@@ -4100,6 +4115,9 @@ TEST_F(FederatedAuthRequestImplTest, FailureUiSigninFromDifferentIdp) {
// That ShowFailureDialog() is called a 2nd time after the IdP sign-in status // That ShowFailureDialog() is called a 2nd time after the IdP sign-in status
// update. // update.
TEST_F(FederatedAuthRequestImplTest, FailureUiAccountEndpointKeepsFailing) { TEST_F(FederatedAuthRequestImplTest, FailureUiAccountEndpointKeepsFailing) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull); url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull);
MockConfiguration configuration = kConfigurationValid; MockConfiguration configuration = kConfigurationValid;
@@ -4157,6 +4175,9 @@ TEST_F(FederatedAuthRequestImplTest, FailureUiAccountEndpointKeepsFailing) {
// status update. // status update.
// That user is shown IdP-sign-in-failure dialog. // That user is shown IdP-sign-in-failure dialog.
TEST_F(FederatedAuthRequestImplTest, FailureUiThenFailDifferentEndpoint) { TEST_F(FederatedAuthRequestImplTest, FailureUiThenFailDifferentEndpoint) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
SetNetworkRequestManager( SetNetworkRequestManager(
std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>()); std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>());
auto* network_manager = auto* network_manager =
@@ -4216,6 +4237,21 @@ TEST_F(FederatedAuthRequestImplTest, FailureUiThenFailDifferentEndpoint) {
CheckAllFedCmSessionIDs(); CheckAllFedCmSessionIDs();
} }
// Test that when IdpSigninStatus API is in the metrics-only mode, that an IDP
// signed-out status stays signed-out regardless of what is returned by the
// accounts endpoint.
TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusMetricsModeStaysSignedout) {
base::test::ScopedFeatureList list;
list.InitWithFeatures({}, {features::kFedCmIdpSigninStatusEnabled});
test_permission_delegate_
->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = false;
EXPECT_CALL(*test_permission_delegate_, SetIdpSigninStatus(_, _)).Times(0);
RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
kConfigurationValid);
}
// Test that when IdpSigninStatus API does not have any state for an IDP, that // Test that when IdpSigninStatus API does not have any state for an IDP, that
// the state transitions to sign-in if the accounts endpoint returns a // the state transitions to sign-in if the accounts endpoint returns a
// non-empty list of accounts. // non-empty list of accounts.
@@ -4231,6 +4267,31 @@ TEST_F(
kConfigurationValid); kConfigurationValid);
} }
// Test that when IdpSigninStatus API is in metrics-only mode, that IDP sign-in
// status transitions to signed-out if the accounts endpoint returns no
// information.
TEST_F(FederatedAuthRequestImplTest,
IdpSigninStatusMetricsModeTransitionsToSignedoutWhenNoAccounts) {
base::test::ScopedFeatureList list;
list.InitWithFeatures({}, {features::kFedCmIdpSigninStatusEnabled});
test_permission_delegate_
->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;
EXPECT_CALL(*test_permission_delegate_,
SetIdpSigninStatus(OriginFromString(kProviderUrlFull), false));
MockConfiguration configuration = kConfigurationValid;
configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
ParseStatus::kInvalidResponseError;
RequestExpectations expectations = {
RequestTokenStatus::kError,
FederatedAuthRequestResult::kAccountsInvalidResponse,
/*standalone_console_message=*/std::nullopt, std::nullopt};
RunAuthTest(kDefaultRequestParameters, expectations, configuration);
EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
EXPECT_FALSE(did_show_accounts_dialog());
}
// Tests that multiple IDPs provided results in an error if the // Tests that multiple IDPs provided results in an error if the
// `kFedCmMultipleIdentityProviders` flag is disabled. // `kFedCmMultipleIdentityProviders` flag is disabled.
TEST_F(FederatedAuthRequestImplTest, MultiIdpDisabled) { TEST_F(FederatedAuthRequestImplTest, MultiIdpDisabled) {
@@ -6421,6 +6482,9 @@ TEST_F(FederatedAuthRequestImplTest, AccountsDialogShownMetric) {
// Tests that when a mismatch dialog is shown, the appropriate metrics are // Tests that when a mismatch dialog is shown, the appropriate metrics are
// recorded. // recorded.
TEST_F(FederatedAuthRequestImplTest, MismatchDialogShownMetric) { TEST_F(FederatedAuthRequestImplTest, MismatchDialogShownMetric) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
base::RunLoop ukm_loop; base::RunLoop ukm_loop;
ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName, ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
ukm_loop.QuitClosure()); ukm_loop.QuitClosure());
@@ -6451,6 +6515,9 @@ TEST_F(FederatedAuthRequestImplTest, MismatchDialogShownMetric) {
// Tests that a mismatch dialog is shown twice. // Tests that a mismatch dialog is shown twice.
TEST_F(FederatedAuthRequestImplTest, DoubleMismatchDialog) { TEST_F(FederatedAuthRequestImplTest, DoubleMismatchDialog) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
base::RunLoop ukm_loop; base::RunLoop ukm_loop;
ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName, ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
ukm_loop.QuitClosure()); ukm_loop.QuitClosure());
@@ -6546,6 +6613,9 @@ TEST_F(FederatedAuthRequestImplTest, AbortedAccountsDialogShownDurationMetric) {
// Tests that when a mismatch dialog is aborted, the appropriate duration // Tests that when a mismatch dialog is aborted, the appropriate duration
// metrics are recorded. // metrics are recorded.
TEST_F(FederatedAuthRequestImplTest, AbortedMismatchDialogShownDurationMetric) { TEST_F(FederatedAuthRequestImplTest, AbortedMismatchDialogShownDurationMetric) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
base::RunLoop ukm_loop; base::RunLoop ukm_loop;
ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName, ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
ukm_loop.QuitClosure()); ukm_loop.QuitClosure());
@@ -6757,6 +6827,9 @@ TEST_F(FederatedAuthRequestImplTest, ErrorUrlDisplayedWithProperUrl) {
// Test that permission is embargoed upon closing a mismatch dialog. // Test that permission is embargoed upon closing a mismatch dialog.
TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusCloseMismatchEmbargo) { TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusCloseMismatchEmbargo) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
test_permission_delegate_ test_permission_delegate_
->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true; ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;
@@ -6779,6 +6852,9 @@ TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusCloseMismatchEmbargo) {
// Test that permission is not embargoed upon closing an IDP sign-in flow // Test that permission is not embargoed upon closing an IDP sign-in flow
// pop-up. // pop-up.
TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusClosePopupEmbargo) { TEST_F(FederatedAuthRequestImplTest, IdpSigninStatusClosePopupEmbargo) {
base::test::ScopedFeatureList list;
list.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
test_permission_delegate_ test_permission_delegate_
->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true; ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;

@@ -144,7 +144,9 @@ void FederatedAuthUserInfoRequest::SetCallbackAndStart(
} }
if (webid::ShouldFailAccountsEndpointRequestBecauseNotSignedInWithIdp( if (webid::ShouldFailAccountsEndpointRequestBecauseNotSignedInWithIdp(
*render_frame_host_, idp_config_url_, permission_delegate_)) { *render_frame_host_, idp_config_url_, permission_delegate_) &&
webid::GetIdpSigninStatusMode(*render_frame_host_, idp_origin) ==
FedCmIdpSigninStatusMode::ENABLED) {
CompleteWithError(FederatedAuthUserInfoRequestResult::kNotSignedInWithIdp); CompleteWithError(FederatedAuthUserInfoRequestResult::kNotSignedInWithIdp);
return; return;
} }
@@ -196,7 +198,10 @@ void FederatedAuthUserInfoRequest::OnAllConfigAndWellKnownFetched(
does_idp_have_failing_signin_status_ = does_idp_have_failing_signin_status_ =
webid::ShouldFailAccountsEndpointRequestBecauseNotSignedInWithIdp( webid::ShouldFailAccountsEndpointRequestBecauseNotSignedInWithIdp(
*render_frame_host_, idp_config_url_, permission_delegate_); *render_frame_host_, idp_config_url_, permission_delegate_);
if (does_idp_have_failing_signin_status_) { if (does_idp_have_failing_signin_status_ &&
webid::GetIdpSigninStatusMode(*render_frame_host_,
url::Origin::Create(idp_config_url_)) ==
FedCmIdpSigninStatusMode::ENABLED) {
CompleteWithError(FederatedAuthUserInfoRequestResult::kNotSignedInWithIdp); CompleteWithError(FederatedAuthUserInfoRequestResult::kNotSignedInWithIdp);
return; return;
} }

@@ -240,10 +240,13 @@ void FederatedProviderFetcher::ValidateAndMaybeSetError(FetchResult& result) {
result.identity_provider_config_url, result.endpoints.accounts); result.identity_provider_config_url, result.endpoints.accounts);
url::Origin idp_origin = url::Origin idp_origin =
url::Origin::Create(result.identity_provider_config_url); url::Origin::Create(result.identity_provider_config_url);
bool is_login_url_valid = bool is_login_url_valid =
result.metadata && webid::GetIdpSigninStatusMode(render_frame_host_.get(), idp_origin) !=
webid::IsEndpointSameOrigin(result.identity_provider_config_url, FedCmIdpSigninStatusMode::ENABLED ||
result.metadata->idp_login_url); (result.metadata &&
webid::IsEndpointSameOrigin(result.identity_provider_config_url,
result.metadata->idp_login_url));
if (!is_token_valid || !is_accounts_valid || !is_login_url_valid) { if (!is_token_valid || !is_accounts_valid || !is_login_url_valid) {
std::string console_message = std::string console_message =

@@ -515,6 +515,8 @@ TEST_F(FederatedProviderFetcherTest, InvalidCrossOriginTokenEndpoint) {
} }
TEST_F(FederatedProviderFetcherTest, InvalidCrossOriginSigninUrl) { TEST_F(FederatedProviderFetcherTest, InvalidCrossOriginSigninUrl) {
feature_list_.InitAndEnableFeature(features::kFedCmIdpSigninStatusEnabled);
FederatedProviderFetcher::FetchResult result; FederatedProviderFetcher::FetchResult result;
result.endpoints.accounts = GURL("https://idp.example/accounts"); result.endpoints.accounts = GURL("https://idp.example/accounts");
result.endpoints.token = GURL("https://idp.example/token"); result.endpoints.token = GURL("https://idp.example/token");

@@ -27,6 +27,13 @@ bool IsFedCmMultipleIdentityProvidersEnabled() {
features::kFedCmMultipleIdentityProviders); features::kFedCmMultipleIdentityProviders);
} }
FedCmIdpSigninStatusMode GetFedCmIdpSigninStatusFlag() {
if (base::FeatureList::IsEnabled(features::kFedCmIdpSigninStatusEnabled)) {
return FedCmIdpSigninStatusMode::ENABLED;
}
return FedCmIdpSigninStatusMode::METRICS_ONLY;
}
bool IsFedCmMetricsEndpointEnabled() { bool IsFedCmMetricsEndpointEnabled() {
return base::FeatureList::IsEnabled(features::kFedCmMetricsEndpoint); return base::FeatureList::IsEnabled(features::kFedCmMetricsEndpoint);
} }

@@ -24,6 +24,11 @@ bool IsFedCmAuthzFlagEnabled();
// Whether multiple identity providers are enabled. // Whether multiple identity providers are enabled.
bool IsFedCmMultipleIdentityProvidersEnabled(); bool IsFedCmMultipleIdentityProvidersEnabled();
// Returns the IdpSigninStatus API mode.
// Most callers should use webid::GetIdpSigninStatusMode() in webid_utils.h
// instead, as that version takes origin trial status into account.
FedCmIdpSigninStatusMode GetFedCmIdpSigninStatusFlag();
// Whether metrics endpoint is enabled. // Whether metrics endpoint is enabled.
bool IsFedCmMetricsEndpointEnabled(); bool IsFedCmMetricsEndpointEnabled();

@@ -423,6 +423,8 @@ class WebIdBrowserTest : public ContentBrowserTest {
class WebIdIdpSigninStatusBrowserTest : public WebIdBrowserTest { class WebIdIdpSigninStatusBrowserTest : public WebIdBrowserTest {
public: public:
void SetUpCommandLine(base::CommandLine* command_line) override { void SetUpCommandLine(base::CommandLine* command_line) override {
scoped_feature_list_.InitAndEnableFeature(
features::kFedCmIdpSigninStatusEnabled);
command_line->AppendSwitch(switches::kIgnoreCertificateErrors); command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
} }
@@ -438,7 +440,9 @@ class WebIdIdpSigninStatusForFetchKeepAliveBrowserTest
public: public:
void SetUpCommandLine(base::CommandLine* command_line) override { void SetUpCommandLine(base::CommandLine* command_line) override {
scoped_feature_list_.InitWithFeatures( scoped_feature_list_.InitWithFeatures(
{blink::features::kKeepAliveInBrowserMigration}, {}); {features::kFedCmIdpSigninStatusEnabled,
blink::features::kKeepAliveInBrowserMigration},
{});
command_line->AppendSwitch(switches::kIgnoreCertificateErrors); command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
} }

@@ -393,6 +393,13 @@ std::string GetDisconnectConsoleErrorMessage(
} }
} }
FedCmIdpSigninStatusMode GetIdpSigninStatusMode(RenderFrameHost& host,
const url::Origin& idp_origin) {
// TODO(crbug.com/40283354): Remove this function in favor of
// GetFedCmIdpSigninStatusFlag.
return GetFedCmIdpSigninStatusFlag();
}
std::string FormatUrlForDisplay(const GURL& url) { std::string FormatUrlForDisplay(const GURL& url) {
// We do not use url_formatter::FormatUrlForSecurityDisplay() directly because // We do not use url_formatter::FormatUrlForSecurityDisplay() directly because
// our UI intentionally shows only the eTLD+1, as it makes for a shorter text // our UI intentionally shows only the eTLD+1, as it makes for a shorter text

@@ -86,6 +86,9 @@ CONTENT_EXPORT std::string GetConsoleErrorMessageFromResult(
CONTENT_EXPORT std::string GetDisconnectConsoleErrorMessage( CONTENT_EXPORT std::string GetDisconnectConsoleErrorMessage(
FedCmDisconnectStatus disconnect_status_for_metrics); FedCmDisconnectStatus disconnect_status_for_metrics);
FedCmIdpSigninStatusMode GetIdpSigninStatusMode(RenderFrameHost& host,
const url::Origin& idp_origin);
// Returns the eTLD+1 for a given url. For localhost, returns the host. // Returns the eTLD+1 for a given url. For localhost, returns the host.
std::string FormatUrlForDisplay(const GURL& url); std::string FormatUrlForDisplay(const GURL& url);

@@ -217,6 +217,9 @@ void SetRuntimeFeaturesFromChromiumFeatures() {
kDefault}, kDefault},
{wf::EnableFedCmIdPRegistration, {wf::EnableFedCmIdPRegistration,
raw_ref(features::kFedCmIdPRegistration), kDefault}, raw_ref(features::kFedCmIdPRegistration), kDefault},
{wf::EnableFedCmIdpSigninStatus,
raw_ref(features::kFedCmIdpSigninStatusEnabled),
kSetOnlyIfOverridden},
{wf::EnableGamepadMultitouch, {wf::EnableGamepadMultitouch,
raw_ref(features::kEnableGamepadMultitouch)}, raw_ref(features::kEnableGamepadMultitouch)},
{wf::EnableSharedStorageAPI, {wf::EnableSharedStorageAPI,

@@ -440,6 +440,14 @@ BASE_FEATURE(kFedCmIdPRegistration,
"FedCmIdPregistration", "FedCmIdPregistration",
base::FEATURE_DISABLED_BY_DEFAULT); base::FEATURE_DISABLED_BY_DEFAULT);
// Enables the IDP signin status API for use with FedCM, including avoiding
// network requests when not signed in and mismatch handling.
// When turned off, Login-Status headers are still parsed and processed
// and FedCM mismatch metrics are collected.
BASE_FEATURE(kFedCmIdpSigninStatusEnabled,
"FedCmIdpSigninStatusEnabled",
base::FEATURE_ENABLED_BY_DEFAULT);
// Enables usage of the FedCM API with metrics endpoint at the same time. // Enables usage of the FedCM API with metrics endpoint at the same time.
BASE_FEATURE(kFedCmMetricsEndpoint, BASE_FEATURE(kFedCmMetricsEndpoint,
"FedCmMetricsEndpoint", "FedCmMetricsEndpoint",

@@ -113,6 +113,7 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmAuthz);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmButtonMode); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmButtonMode);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmDelegation); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmDelegation);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmIdPRegistration); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmIdPRegistration);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmIdpSigninStatusEnabled);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmMetricsEndpoint); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmMetricsEndpoint);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmMultipleIdentityProviders); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmMultipleIdentityProviders);
CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmSelectiveDisclosure); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmSelectiveDisclosure);

@@ -2070,7 +2070,12 @@ void AuthenticationCredentialsContainer::GetForIdentity(
UseCounter::Count(resolver->GetExecutionContext(), UseCounter::Count(resolver->GetExecutionContext(),
WebFeature::kFedCmIframe); WebFeature::kFedCmIframe);
} }
// Track when websites use FedCM with the IDP sign-in status opt-in
if (RuntimeEnabledFeatures::FedCmIdpSigninStatusEnabled(
resolver->GetExecutionContext())) {
UseCounter::Count(resolver->GetExecutionContext(),
WebFeature::kFedCmIdpSigninStatusApi);
}
int provider_index = 0; int provider_index = 0;
Vector<mojom::blink::IdentityProviderRequestOptionsPtr> Vector<mojom::blink::IdentityProviderRequestOptionsPtr>
identity_provider_ptrs; identity_provider_ptrs;

@@ -27,7 +27,7 @@ dictionary IdentityProviderToken {
[CallWith=ScriptState, RaisesException, MeasureAs=FedCmUserInfo] [CallWith=ScriptState, RaisesException, MeasureAs=FedCmUserInfo]
static Promise<sequence<IdentityUserInfo>> getUserInfo(IdentityProviderConfig config); static Promise<sequence<IdentityUserInfo>> getUserInfo(IdentityProviderConfig config);
[CallWith=ScriptState] [RuntimeEnabled=FedCmIdpSigninStatus, CallWith=ScriptState]
static void close(); static void close();
[RuntimeEnabled=FedCmIdPRegistration, CallWith=ScriptState, ImplementedAs=registerIdentityProvider] [RuntimeEnabled=FedCmIdPRegistration, CallWith=ScriptState, ImplementedAs=registerIdentityProvider]

@@ -14,13 +14,13 @@ enum LoginStatus {
ImplementedAs=NavigatorLogin ImplementedAs=NavigatorLogin
] ]
partial interface Navigator { partial interface Navigator {
[SecureContext, RuntimeEnabled=FedCm] readonly attribute NavigatorLogin login; [SecureContext, RuntimeEnabled=FedCmIdpSigninStatus] readonly attribute NavigatorLogin login;
}; };
[ [
Exposed=Window, Exposed=Window,
SecureContext, SecureContext,
RuntimeEnabled=FedCm RuntimeEnabled=FedCmIdpSigninStatus
] ]
interface NavigatorLogin { interface NavigatorLogin {
[CallWith=ScriptState, MeasureAs=FedCmIdpSigninStatusJsApi] [CallWith=ScriptState, MeasureAs=FedCmIdpSigninStatusJsApi]

@@ -1806,6 +1806,14 @@
status: "test", status: "test",
base_feature: "none", base_feature: "none",
}, },
{
name: "FedCmIdpSigninStatus",
depends_on: ["FedCm"],
public: true,
status: "stable",
base_feature: "none",
browser_process_read_access: true,
},
{ {
name: "FedCmMultipleIdentityProviders", name: "FedCmMultipleIdentityProviders",
depends_on: ["FedCm"], depends_on: ["FedCm"],