Skip to content

Commit

Permalink
Add support for FedCM commands
Browse files Browse the repository at this point in the history
As specified in:
https://fedidcg.github.io/FedCM/#automation

Currently implemented in Chromium.
  • Loading branch information
cbiesinger committed Jun 13, 2023
1 parent 4d70bd8 commit 7951073
Show file tree
Hide file tree
Showing 18 changed files with 673 additions and 0 deletions.
17 changes: 17 additions & 0 deletions common/src/web/fedcm/accounts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"accounts": [{
"id": "1234",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
"approved_clients": ["123", "456", "789"]
}, {
"id": "5678",
"given_name": "Aisha",
"name": "Aisha Ahmad",
"email": "aisha@idp.example",
"picture": "https://idp.example/profile/567",
"approved_clients": []
}]
}
4 changes: 4 additions & 0 deletions common/src/web/fedcm/client_metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"privacy_policy_url": "https://rp.example/privacy_policy.html",
"terms_of_service_url": "https://rp.example/terms_of_service.html"
}
20 changes: 20 additions & 0 deletions common/src/web/fedcm/fedcm.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<script>

let configURL = `https://${location.host}/fedcm/fedcm.json`;
let promise = null;

function triggerFedCm() {
console.log(configURL);
promise = navigator.credentials.get({
identity: {
providers: [{
configURL: configURL,
clientId: '1',
}]
}
});
return promise;
}

</script>
6 changes: 6 additions & 0 deletions common/src/web/fedcm/fedcm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"accounts_endpoint": "accounts.json",
"client_metadata_endpoint": "client_metadata.json",
"id_assertion_endpoint": "id_assertion",
"signin_url": "/signin"
}
1 change: 1 addition & 0 deletions java/src/org/openqa/selenium/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ java_export(
name = "core",
srcs = glob([
"*.java",
"federatedcredentialmanagement/*.java",
"html5/*.java",
"internal/*.java",
"interactions/**/*.java",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.openqa.selenium.federatedcredentialmanagement;

import java.util.Map;

/**
* Represents an account displayed in a FedCM account list.
*
* @see <a href="https://fedidcg.github.io/FedCM/#dictdef-identityprovideraccount">
* https://fedidcg.github.io/FedCM/#dictdef-identityprovideraccount</a>
* @see <a href="https://fedidcg.github.io/FedCM/#webdriver-accountlist">
* https://fedidcg.github.io/FedCM/#webdriver-accountlist</a>
*/
public class FederatedCredentialManagementAccount {
private final String accountId;
private final String email;
private final String name;
private final String givenName;
private final String pictureUrl;
/**
* The config URL of the identity provider that provided this account.
*
* This allows identifying the IDP in multi-IDP cases.
*/
private final String idpConfigUrl;
/**
* The login state for this account.
*
* One of LOGIN_STATE_SIGNIN and LOGIN_STATE_SIGNUP.
*/
private final String loginState;
private final String termsOfServiceUrl;
private final String privacyPolicyUrl;

public static final String LOGIN_STATE_SIGNIN = "SignIn";
public static final String LOGIN_STATE_SIGNUP = "SignUp";

public FederatedCredentialManagementAccount(Map<String, String> dict) {
accountId = (String) dict.getOrDefault("accountId", null);
email = (String) dict.getOrDefault("email", null);
name = (String) dict.getOrDefault("name", null);
givenName = (String) dict.getOrDefault("givenName", null);
pictureUrl = (String) dict.getOrDefault("pictureUrl", null);
idpConfigUrl = (String) dict.getOrDefault("idpConfigUrl", null);
loginState = (String) dict.getOrDefault("loginState", null);
termsOfServiceUrl = (String) dict.getOrDefault("termsOfServiceUrl", null);
privacyPolicyUrl = (String) dict.getOrDefault("privacyPolicyUrl", null);
}

public String getAccountid() {
return accountId;
}

public String getEmail() {
return email;
}

public String getName() {
return name;
}

public String getGivenName() {
return givenName;
}

public String getPictureUrl() {
return pictureUrl;
}

public String getIdpConfigUrl() {
return idpConfigUrl;
}

public String getLoginState() {
return loginState;
}

public String getTermsOfServiceUrl() {
return termsOfServiceUrl;
}

public String getPrivacyPolicyUrl() {
return privacyPolicyUrl;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.openqa.selenium.federatedcredentialmanagement;

import java.util.List;

/**
* Represents an open dialog of the Federated Credential Management API.
*
* @see <a href="https://fedidcg.github.io/FedCM/">https://fedidcg.github.io/FedCM/</a>
*/
public interface FederatedCredentialManagementDialog {

String DIALOG_TYPE_ACCOUNT_LIST = "AccountChooser";
String DIALOG_TYPE_AUTO_REAUTH = "AutoReauthn";

/**
* Closes the dialog as if the user had clicked X.
*/
void cancelDialog();

/**
* Selects an account as if the user had clicked on it.
*
* @param index The index of the account to select from the list
* returned by getAccounts().
*/
void selectAccount(int index);

/**
* Returns the type of the open dialog.
*
* One of DIALOG_TYPE_ACCOUNT_LIST and DIALOG_TYPE_AUTO_REAUTH.
*/
String getDialogType();

/**
* Returns the title of the dialog.
*/
String getTitle();

/**
* Returns the subtitle of the dialog or null if none.
*/
String getSubtitle();

/**
* Returns the accounts shown in the account chooser.
*
* If this is an auto reauth dialog, returns the single account
* that is being signed in.
*/
List<FederatedCredentialManagementAccount> getAccounts();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.openqa.selenium.federatedcredentialmanagement;

import org.openqa.selenium.Beta;

/**
* Used by classes to indicate that they can interact with FedCM dialogs.
*/
@Beta
public interface HasFederatedCredentialManagement {
/**
* Disables the promise rejection delay.
*
* FedCM by default delays promise resolution in failure cases for privacy
* reasons (https://fedidcg.github.io/FedCM/#ref-for-setdelayenabled);
* this function allows turning it off to let tests run faster where this
* is not relevant.
*/
void setDelayEnabled(boolean enabled);

/**
* Resets the FedCM dialog cooldown.
*
* If a user agent triggers a cooldown when the account chooser is dismissed,
* this function resets that cooldown so that the dialog can be triggered
* again immediately.
*/
void resetCooldown();

/**
* Gets the currently open FedCM dialog, or null if there is no dialog.
*
* Can be used with WebDriverWait like:
* wait.until(driver -> ((HasFederatedCredentialManagement) driver).
* getFederatedCredentialManagementDialog() != null);
*/
FederatedCredentialManagementDialog getFederatedCredentialManagementDialog();
}

5 changes: 5 additions & 0 deletions java/src/org/openqa/selenium/grid/web/ResourceHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static com.google.common.net.MediaType.GIF;
import static com.google.common.net.MediaType.HTML_UTF_8;
import static com.google.common.net.MediaType.JAVASCRIPT_UTF_8;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static com.google.common.net.MediaType.JPEG;
import static com.google.common.net.MediaType.OCTET_STREAM;
import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
Expand Down Expand Up @@ -160,6 +161,10 @@ private String mediaType(String uri) {
type = JAVASCRIPT_UTF_8;
break;

case "json":
type = JSON_UTF_8;
break;

case "md":
case "txt":
type = PLAIN_TEXT_UTF_8;
Expand Down
19 changes: 19 additions & 0 deletions java/src/org/openqa/selenium/remote/DriverCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ public interface DriverCommand {
String REMOVE_CREDENTIAL = "removeCredential";
String REMOVE_ALL_CREDENTIALS = "removeAllCredentials";
String SET_USER_VERIFIED = "setUserVerified";
// Federated Credential Management API
// https://fedidcg.github.io/FedCM/#automation
String CANCEL_DIALOG = "cancelDialog";
String SELECT_ACCOUNT = "selectAccount";
String GET_ACCOUNTS = "getAccounts";
String GET_FEDCM_TITLE = "getFedCmTitle";
String GET_FEDCM_DIALOG_TYPE = "getFedCmDialogType";
String SET_DELAY_ENABLED = "setDelayEnabled";
String RESET_COOLDOWN = "resetCooldown";

static CommandPayload NEW_SESSION(Capabilities capabilities) {
Require.nonNull("Capabilities", capabilities);
Expand Down Expand Up @@ -401,4 +410,14 @@ static CommandPayload SET_CURRENT_WINDOW_SIZE(Dimension targetSize) {
SET_CURRENT_WINDOW_SIZE,
ImmutableMap.of("width", targetSize.width, "height", targetSize.height));
}

static CommandPayload SELECT_ACCOUNT(int index) {
return new CommandPayload(
SELECT_ACCOUNT, ImmutableMap.of("accountIndex", index));
}

static CommandPayload SET_DELAY_ENABLED(boolean enabled) {
return new CommandPayload(
SET_DELAY_ENABLED, ImmutableMap.of("enabled", enabled));
}
}
Loading

0 comments on commit 7951073

Please sign in to comment.