From 9d63ad0dea50dbf63ffc3b34ff1bffb9aee19657 Mon Sep 17 00:00:00 2001
From: Dominik Kawka <31955648+dominikkawka@users.noreply.github.com>
Date: Sat, 5 Nov 2022 19:01:28 +0000
Subject: [PATCH] IDP SAML testing (#3713)
---
.../e2e/identity_providers_saml_test.spec.ts | 27 ++
.../social/ProviderSAMLSettings.ts | 248 ++++++++++++++++++
.../add/DescriptorSettings.tsx | 9 +
3 files changed, 284 insertions(+)
create mode 100644 apps/admin-ui/cypress/support/pages/admin_console/manage/identity_providers/social/ProviderSAMLSettings.ts
diff --git a/apps/admin-ui/cypress/e2e/identity_providers_saml_test.spec.ts b/apps/admin-ui/cypress/e2e/identity_providers_saml_test.spec.ts
index 8c5b1f943f..6ddba1d3a4 100644
--- a/apps/admin-ui/cypress/e2e/identity_providers_saml_test.spec.ts
+++ b/apps/admin-ui/cypress/e2e/identity_providers_saml_test.spec.ts
@@ -6,6 +6,7 @@ import ListingPage from "../support/pages/admin_console/ListingPage";
import CreateProviderPage from "../support/pages/admin_console/manage/identity_providers/CreateProviderPage";
import ModalUtils from "../support/util/ModalUtils";
import AddMapperPage from "../support/pages/admin_console/manage/identity_providers/AddMapperPage";
+import ProviderSAMLSettings from "../support/pages/admin_console/manage/identity_providers/social/ProviderSAMLSettings";
describe("SAML identity provider test", () => {
const loginPage = new LoginPage();
@@ -148,6 +149,32 @@ describe("SAML identity provider test", () => {
masthead.checkNotificationMessage(saveMapperSuccessMsg, true);
});
+ it("should edit SAML settings", () => {
+ const providerSAMLSettings = new ProviderSAMLSettings();
+
+ sidebarPage.goToIdentityProviders();
+ listingPage.goToItemDetails(samlProviderName);
+ providerSAMLSettings.disableProviderSwitch();
+ sidebarPage.goToIdentityProviders();
+ cy.findByText("Disabled");
+ listingPage.goToItemDetails(samlProviderName);
+ providerSAMLSettings.enableProviderSwitch();
+
+ cy.get(".pf-c-jump-links__list").contains("SAML settings").click();
+ providerSAMLSettings.assertIdAndURLFields();
+ providerSAMLSettings.assertNameIdPolicyFormat();
+ providerSAMLSettings.assertPrincipalType();
+ providerSAMLSettings.assertSAMLSwitches();
+ providerSAMLSettings.assertSignatureAlgorithm();
+ providerSAMLSettings.assertValidateSignatures();
+ providerSAMLSettings.assertTextFields();
+
+ cy.get(".pf-c-jump-links__list")
+ .contains("Requested AuthnContext Constraints")
+ .click();
+ providerSAMLSettings.assertAuthnContext();
+ });
+
it("clean up providers", () => {
const modalUtils = new ModalUtils();
diff --git a/apps/admin-ui/cypress/support/pages/admin_console/manage/identity_providers/social/ProviderSAMLSettings.ts b/apps/admin-ui/cypress/support/pages/admin_console/manage/identity_providers/social/ProviderSAMLSettings.ts
new file mode 100644
index 0000000000..7d155246f7
--- /dev/null
+++ b/apps/admin-ui/cypress/support/pages/admin_console/manage/identity_providers/social/ProviderSAMLSettings.ts
@@ -0,0 +1,248 @@
+import PageObject from "../../../components/PageObject";
+import Masthead from "../../../Masthead";
+
+const masthead = new Masthead();
+
+export default class ProviderSAMLSettings extends PageObject {
+ private samlSwitch = "#Saml-switch";
+ private modalConfirm = "#modal-confirm";
+ private serviceProviderEntityID = "serviceProviderEntityId";
+ private identityProviderEntityId = "identityProviderEntityId";
+ private ssoServiceUrl = "sso-service-url";
+ private singleLogoutServiceUrl = "single-logout-service-url";
+ private nameIdPolicyFormat = "#kc-nameIdPolicyFormat";
+ private principalType = "#kc-principalType";
+ private principalAttribute = "principalAttribute";
+ private principalSubjectNameId = "subjectNameId-option";
+ private principalAttributeName = "attributeName-option";
+ private principalFriendlyAttribute = "attributeFriendlyName-option";
+
+ private transientPolicy = "transient-option";
+ private emailPolicy = "email-option";
+ private kerberosPolicy = "kerberos-option";
+ private x509Policy = "x509-option";
+ private windowsDomainQNPolicy = "windowsDomainQN-option";
+ private unspecifiedPolicy = "unspecified-option";
+ private persistentPolicy = "persistent-option";
+
+ private allowCreate = "#allowCreate";
+ private httpPostBindingResponse = "#httpPostBindingResponse";
+ private httpPostBindingAuthnRequest = "#httpPostBindingAuthnRequest";
+ private httpPostBindingLogout = "#httpPostBindingLogout";
+ private wantAuthnRequestsSigned = "#wantAuthnRequestsSigned";
+
+ private signatureAlgorithm = "#kc-signatureAlgorithm";
+ private samlSignatureKeyName = "#kc-samlSignatureKeyName";
+
+ private wantAssertionsSigned = "#wantAssertionsSigned";
+ private wantAssertionsEncrypted = "#wantAssertionsEncrypted";
+ private forceAuthentication = "#forceAuthentication";
+ private validateSignature = "#validateSignature";
+ private validatingX509Certs = "validatingX509Certs";
+ private signServiceProviderMetadata = "#signServiceProviderMetadata";
+ private passSubject = "#passSubject";
+ private allowedClockSkew = "allowedClockSkew";
+ private attributeConsumingServiceIndex = "attributeConsumingServiceIndex";
+ private attributeConsumingServiceName = "attributeConsumingServiceName";
+
+ private comparison = "#comparison";
+ private saveBtn = "save";
+ private revertBtn = "revert";
+
+ public clickSaveBtn() {
+ cy.findByTestId(this.saveBtn).click();
+ }
+
+ public clickRevertBtn() {
+ cy.findByTestId(this.revertBtn).click();
+ }
+
+ public enableProviderSwitch() {
+ cy.get(this.samlSwitch).parent().click();
+ masthead.checkNotificationMessage("Provider successfully updated");
+ }
+
+ public disableProviderSwitch() {
+ cy.get(this.samlSwitch).parent().click();
+ cy.get(this.modalConfirm).click();
+ masthead.checkNotificationMessage("Provider successfully updated");
+ }
+
+ public typeServiceProviderEntityId(entityId: string) {
+ cy.findByTestId(this.serviceProviderEntityID)
+ .click()
+ .clear()
+ .type(entityId);
+ return this;
+ }
+
+ public typeIdentityProviderEntityId(entityId: string) {
+ cy.findByTestId(this.identityProviderEntityId)
+ .click()
+ .clear()
+ .type(entityId);
+ return this;
+ }
+
+ public typeSsoServiceUrl(url: string) {
+ cy.findByTestId(this.ssoServiceUrl).click().clear().type(url);
+ return this;
+ }
+
+ public typeSingleLogoutServiceUrl(url: string) {
+ cy.findByTestId(this.singleLogoutServiceUrl).click().clear().type(url);
+ return this;
+ }
+
+ public typeX509Certs(cert: string) {
+ cy.findByTestId(this.validatingX509Certs).click().clear().type(cert);
+ return this;
+ }
+
+ public selectNamePolicyIdFormat() {
+ cy.get(this.nameIdPolicyFormat).scrollIntoView().click();
+ }
+
+ public selectPrincipalFormat() {
+ cy.get(this.principalType).scrollIntoView().click();
+ }
+
+ public selectSignatureAlgorithm(algorithm: string) {
+ cy.get(this.signatureAlgorithm).scrollIntoView().click();
+ cy.findByText(algorithm).click();
+ }
+
+ public selectSAMLSignature(key: string) {
+ cy.get(this.samlSignatureKeyName).scrollIntoView().click();
+ cy.findByText(key).click();
+ }
+
+ public selectComparison(comparison: string) {
+ cy.get(this.comparison).scrollIntoView().click();
+ cy.findByText(comparison).scrollIntoView().click();
+ }
+
+ public assertIdAndURLFields() {
+ const ssoServiceUrlError =
+ "Could not update the provider The url [singleSignOnServiceUrl] is malformed";
+ const singleLogoutServiceUrlError =
+ "Could not update the provider The url [singleLogoutServiceUrl] is malformed";
+ this.typeServiceProviderEntityId("ServiceProviderEntityId");
+ this.typeIdentityProviderEntityId("IdentityProviderEntityId");
+ this.clickSaveBtn();
+
+ this.typeSsoServiceUrl("Not a real URL");
+ this.clickSaveBtn();
+ masthead.checkNotificationMessage(ssoServiceUrlError);
+ this.clickRevertBtn();
+
+ this.typeSingleLogoutServiceUrl("Not a real URL");
+ this.clickSaveBtn();
+ masthead.checkNotificationMessage(singleLogoutServiceUrlError);
+ return this;
+ }
+
+ public assertNameIdPolicyFormat() {
+ this.selectNamePolicyIdFormat();
+ cy.findByTestId(this.transientPolicy).click();
+ this.selectNamePolicyIdFormat();
+ cy.findByTestId(this.emailPolicy).click();
+ this.selectNamePolicyIdFormat();
+ cy.findByTestId(this.kerberosPolicy).click();
+ this.selectNamePolicyIdFormat();
+ cy.findByTestId(this.x509Policy).click();
+ this.selectNamePolicyIdFormat();
+ cy.findByTestId(this.windowsDomainQNPolicy).click();
+ this.selectNamePolicyIdFormat();
+ cy.findByTestId(this.unspecifiedPolicy).click();
+ this.selectNamePolicyIdFormat();
+ cy.findByTestId(this.persistentPolicy).click();
+ return this;
+ }
+
+ public assertSignatureAlgorithm() {
+ cy.get(this.wantAuthnRequestsSigned).parent().click();
+ cy.get(this.signatureAlgorithm).should("not.exist");
+ cy.get(this.samlSignatureKeyName).should("not.exist");
+ this.clickRevertBtn();
+ cy.get(this.signatureAlgorithm).should("exist");
+ cy.get(this.samlSignatureKeyName).should("exist");
+
+ this.selectSignatureAlgorithm("RSA_SHA1");
+ this.selectSignatureAlgorithm("RSA_SHA256");
+ this.selectSignatureAlgorithm("RSA_SHA256_MGF1");
+ this.selectSignatureAlgorithm("RSA_SHA512");
+ this.selectSignatureAlgorithm("RSA_SHA512_MGF1");
+ this.selectSignatureAlgorithm("DSA_SHA1");
+
+ this.selectSAMLSignature("NONE");
+ this.selectSAMLSignature("KEY_ID");
+ this.selectSAMLSignature("CERT_SUBJECT");
+
+ return this;
+ }
+
+ public assertPrincipalType() {
+ this.selectPrincipalFormat();
+ cy.findByTestId(this.principalAttributeName).click();
+ cy.findByTestId(this.principalAttribute).should("exist").scrollIntoView();
+ this.selectPrincipalFormat();
+ cy.findByTestId(this.principalFriendlyAttribute).click();
+ cy.findByTestId(this.principalAttribute).should("exist");
+ this.selectPrincipalFormat();
+ cy.findByTestId(this.principalSubjectNameId).click();
+ cy.findByTestId(this.principalAttribute).should("not.exist");
+ return this;
+ }
+
+ public assertSAMLSwitches() {
+ cy.get(this.allowCreate).parent().click();
+ cy.get(this.httpPostBindingResponse).parent().click();
+ cy.get(this.httpPostBindingLogout).parent().click();
+ cy.get(this.httpPostBindingAuthnRequest).parent().click();
+
+ cy.get(this.wantAssertionsSigned).parent().click();
+ cy.get(this.wantAssertionsEncrypted).parent().click();
+ cy.get(this.forceAuthentication).parent().click();
+
+ cy.get(this.signServiceProviderMetadata).parent().click();
+ cy.get(this.passSubject).parent().click();
+
+ return this;
+ }
+
+ public assertValidateSignatures() {
+ cy.get(this.validateSignature).parent().click();
+ cy.findByTestId(this.validatingX509Certs).should("not.exist");
+ cy.get(this.validateSignature).parent().click();
+ this.typeX509Certs("X509 Certificate");
+ this.clickRevertBtn();
+ cy.findByTestId(this.validatingX509Certs);
+ this.clickSaveBtn();
+ return this;
+ }
+
+ public assertTextFields() {
+ cy.findByTestId(this.allowedClockSkew)
+ .click()
+ .type("not a number")
+ .should("be.empty")
+ .type("111");
+
+ cy.findByTestId(this.attributeConsumingServiceIndex)
+ .click()
+ .type("not a number")
+ .should("be.empty")
+ .type("111");
+
+ cy.findByTestId(this.attributeConsumingServiceName).click().type("name");
+ }
+
+ public assertAuthnContext() {
+ this.selectComparison("minimum");
+ this.selectComparison("maximum");
+ this.selectComparison("better");
+ this.selectComparison("exact");
+ return this;
+ }
+}
diff --git a/apps/admin-ui/src/identity-providers/add/DescriptorSettings.tsx b/apps/admin-ui/src/identity-providers/add/DescriptorSettings.tsx
index fe7391a542..90181304fd 100644
--- a/apps/admin-ui/src/identity-providers/add/DescriptorSettings.tsx
+++ b/apps/admin-ui/src/identity-providers/add/DescriptorSettings.tsx
@@ -132,6 +132,7 @@ const Fields = ({ readOnly }: DescriptorSettingsProps) => {
/>
}
fieldId="single-logout-service-url"
+ data-testid="single-logout-service-url"
validated={
errors.config?.singleLogoutServiceUrl
? ValidatedOptions.error
@@ -150,6 +151,7 @@ const Fields = ({ readOnly }: DescriptorSettingsProps) => {
{
{
)}
@@ -471,6 +477,7 @@ const Fields = ({ readOnly }: DescriptorSettingsProps) => {
min="0"
max="2147483"
id="allowedClockSkew"
+ data-testid="allowedClockSkew"
name="config.allowedClockSkew"
ref={register}
isReadOnly={readOnly}
@@ -493,6 +500,7 @@ const Fields = ({ readOnly }: DescriptorSettingsProps) => {
min="0"
max="65535"
id="attributeConsumingServiceIndex"
+ data-testid="attributeConsumingServiceIndex"
name="config.attributeConsumingServiceIndex"
ref={register}
isReadOnly={readOnly}
@@ -513,6 +521,7 @@ const Fields = ({ readOnly }: DescriptorSettingsProps) => {