From 45b6be4fe819e52d9d8eafc7b7fbf426143205dc Mon Sep 17 00:00:00 2001 From: mfrances17 <39063664+mfrances17@users.noreply.github.com> Date: Wed, 16 Mar 2022 07:25:01 -0400 Subject: [PATCH] Fixes SAML provider AuthnContext Constraints fields (#2231) * no multiline for now * multiline work in progress * changed to JSON.stringify * both multiline fields working * check for undefined to prevent JSON issue * streamline saml and oidc provider tests * final tests and misc fixes Co-authored-by: Erik Jan de Wit --- .../identity_providers_oidc_test.spec.ts | 29 +++--------- .../identity_providers_saml_test.spec.ts | 47 +++++++++---------- .../identity_providers/CreateProviderPage.ts | 35 +++++++++++++- src/identity-providers/add/DetailSettings.tsx | 22 +++++++++ .../add/ReqAuthnConstraintsSettings.tsx | 44 +++++++++++++---- .../component/DisplayOrder.tsx | 1 + src/identity-providers/messages.ts | 2 + 7 files changed, 122 insertions(+), 58 deletions(-) diff --git a/cypress/integration/identity_providers_oidc_test.spec.ts b/cypress/integration/identity_providers_oidc_test.spec.ts index 94fab7d996..e9d4b8bd17 100644 --- a/cypress/integration/identity_providers_oidc_test.spec.ts +++ b/cypress/integration/identity_providers_oidc_test.spec.ts @@ -26,7 +26,6 @@ describe("OIDC identity provider test", () => { const authorizationUrl = `${keycloakServer}/realms/master/protocol/openid-connect/auth`; describe("OIDC Identity provider creation", () => { - const identityProviderName = "github"; const oidcProviderName = "oidc"; const secret = "123"; @@ -36,25 +35,14 @@ describe("OIDC identity provider test", () => { sidebarPage.goToIdentityProviders(); }); - it("should create provider", () => { - createProviderPage.checkGitHubCardVisible().clickGitHubCard(); - - createProviderPage.checkAddButtonDisabled(); - createProviderPage - .fill(identityProviderName) - .clickAdd() - .checkClientIdRequiredMessage(true); - createProviderPage.fill(identityProviderName, secret).clickAdd(); - masthead.checkNotificationMessage(createSuccessMsg, true); - - sidebarPage.goToIdentityProviders(); - listingPage.itemExist(identityProviderName); - }); - it("should create an OIDC provider using discovery url", () => { createProviderPage - .clickCreateDropdown() - .clickItem(oidcProviderName) + .checkVisible(oidcProviderName) + .clickCard(oidcProviderName); + + createProviderPage.checkAddButtonDisabled(); + + createProviderPage .fillDiscoveryUrl(discoveryUrl) .shouldBeSuccessful() .fill(oidcProviderName, secret) @@ -88,11 +76,6 @@ describe("OIDC identity provider test", () => { listingPage.itemExist(oidcProviderName).deleteItem(oidcProviderName); modalUtils.checkModalTitle(deletePrompt).confirmModal(); masthead.checkNotificationMessage(deleteSuccessMsg, true); - listingPage - .itemExist(identityProviderName) - .deleteItem(identityProviderName); - modalUtils.checkModalTitle(deletePrompt).confirmModal(); - masthead.checkNotificationMessage(deleteSuccessMsg, true); }); }); }); diff --git a/cypress/integration/identity_providers_saml_test.spec.ts b/cypress/integration/identity_providers_saml_test.spec.ts index b2a2a3d7eb..4285ec7000 100644 --- a/cypress/integration/identity_providers_saml_test.spec.ts +++ b/cypress/integration/identity_providers_saml_test.spec.ts @@ -7,7 +7,7 @@ import CreateProviderPage from "../support/pages/admin_console/manage/identity_p import ModalUtils from "../support/util/ModalUtils"; import AddMapperPage from "../support/pages/admin_console/manage/identity_providers/AddMapperPage"; -describe("Identity provider test", () => { +describe("SAML identity provider test", () => { const loginPage = new LoginPage(); const sidebarPage = new SidebarPage(); const masthead = new Masthead(); @@ -16,19 +16,22 @@ describe("Identity provider test", () => { const addMapperPage = new AddMapperPage(); const createSuccessMsg = "Identity provider successfully created"; + const saveSuccessMsg = "Provider successfully updated"; + const createMapperSuccessMsg = "Mapper created successfully."; const saveMapperSuccessMsg = "Mapper saved successfully."; const deletePrompt = "Delete provider?"; const deleteSuccessMsg = "Provider successfully deleted"; + const classRefName = "acClassRef-1"; + const declRefName = "acDeclRef-1"; + const keycloakServer = Cypress.env("KEYCLOAK_SERVER"); const samlDiscoveryUrl = `${keycloakServer}/realms/master/protocol/saml/descriptor`; describe("SAML identity provider creation", () => { - const identityProviderName = "github"; const samlProviderName = "saml"; - const secret = "123"; beforeEach(() => { keycloakBefore(); @@ -36,31 +39,30 @@ describe("Identity provider test", () => { sidebarPage.goToIdentityProviders(); }); - it("should create provider", () => { - createProviderPage.checkGitHubCardVisible().clickGitHubCard(); - + it("should create a SAML provider using entity descriptor", () => { + createProviderPage + .checkVisible(samlProviderName) + .clickCard(samlProviderName); createProviderPage.checkAddButtonDisabled(); createProviderPage - .fill(identityProviderName) - .clickAdd() - .checkClientIdRequiredMessage(true); - createProviderPage.fill(identityProviderName, secret).clickAdd(); - masthead.checkNotificationMessage(createSuccessMsg, true); - - sidebarPage.goToIdentityProviders(); - listingPage.itemExist(identityProviderName); - }); - - it("should create a SAML provider using SSO service url", () => { - createProviderPage - .clickCreateDropdown() - .clickItem(samlProviderName) .fillDiscoveryUrl(samlDiscoveryUrl) .shouldBeSuccessful() .clickAdd(); masthead.checkNotificationMessage(createSuccessMsg, true); }); + it("should add auth constraints to existing SAML provider", () => { + sidebarPage.goToIdentityProviders(); + listingPage.goToItemDetails(samlProviderName); + createProviderPage + .fillAuthnContextClassRefs(classRefName) + .clickClassRefsAdd() + .fillAuthnContextDeclRefs(declRefName) + .clickDeclRefsAdd() + .clickSave(); + masthead.checkNotificationMessage(saveSuccessMsg, true); + }); + it("should add SAML mapper of type Advanced Attribute to Role", () => { sidebarPage.goToIdentityProviders(); listingPage.goToItemDetails(samlProviderName); @@ -153,11 +155,6 @@ describe("Identity provider test", () => { listingPage.itemExist(samlProviderName).deleteItem(samlProviderName); modalUtils.checkModalTitle(deletePrompt).confirmModal(); masthead.checkNotificationMessage(deleteSuccessMsg, true); - listingPage - .itemExist(identityProviderName) - .deleteItem(identityProviderName); - modalUtils.checkModalTitle(deletePrompt).confirmModal(); - masthead.checkNotificationMessage(deleteSuccessMsg, true); }); }); }); diff --git a/cypress/support/pages/admin_console/manage/identity_providers/CreateProviderPage.ts b/cypress/support/pages/admin_console/manage/identity_providers/CreateProviderPage.ts index 31fb877043..c0f13b2347 100644 --- a/cypress/support/pages/admin_console/manage/identity_providers/CreateProviderPage.ts +++ b/cypress/support/pages/admin_console/manage/identity_providers/CreateProviderPage.ts @@ -7,7 +7,13 @@ export default class CreateProviderPage { private discoveryEndpoint = "discoveryEndpoint"; private authorizationUrl = "authorizationUrl"; private addButton = "createProvider"; + private saveButton = "save"; private ssoServiceUrl = "sso-service-url"; + private authnContextClassRefs = "classref-field"; + private authnContextDeclRefs = "declref-field"; + private addProvider = "Add provider"; + private addClassRef = "Add AuthnContext ClassRef"; + private addDeclRef = "Add AuthnContext DeclRef"; checkVisible(name: string) { cy.findByTestId(`${name}-card`).should("exist"); @@ -47,8 +53,23 @@ export default class CreateProviderPage { return this; } + clickSave() { + cy.findByTestId(this.saveButton).click(); + return this; + } + + clickClassRefsAdd() { + cy.contains(this.addClassRef).click(); + return this; + } + + clickDeclRefsAdd() { + cy.contains(this.addDeclRef).click(); + return this; + } + clickCreateDropdown() { - cy.contains("Add provider").click(); + cy.contains(this.addProvider).click(); return this; } @@ -77,6 +98,18 @@ export default class CreateProviderPage { return this; } + fillAuthnContextClassRefs(value: string) { + cy.findByTestId(this.authnContextClassRefs).type("x"); + cy.findByTestId(this.authnContextClassRefs).clear().type(value).blur(); + return this; + } + + fillAuthnContextDeclRefs(value: string) { + cy.findByTestId(this.authnContextDeclRefs).type("x"); + cy.findByTestId(this.authnContextDeclRefs).clear().type(value).blur(); + return this; + } + fillSsoServiceUrl(value: string) { cy.findByTestId(this.ssoServiceUrl).type("x"); cy.findByTestId(this.ssoServiceUrl).clear().type(value).blur(); diff --git a/src/identity-providers/add/DetailSettings.tsx b/src/identity-providers/add/DetailSettings.tsx index b36fb750eb..4a6baad89d 100644 --- a/src/identity-providers/add/DetailSettings.tsx +++ b/src/identity-providers/add/DetailSettings.tsx @@ -141,12 +141,34 @@ export default function DetailSettings() { reset(fetchedProvider); setProvider(fetchedProvider); + + if (fetchedProvider.config!.authnContextClassRefs) { + form.setValue( + "config.authnContextClassRefs", + JSON.parse(fetchedProvider.config?.authnContextClassRefs) + ); + } + + if (fetchedProvider.config!.authnContextDeclRefs) { + form.setValue( + "config.authnContextDeclRefs", + JSON.parse(fetchedProvider.config?.authnContextDeclRefs) + ); + } }, [] ); const save = async (provider?: IdentityProviderRepresentation) => { const p = provider || getValues(); + if (p.config?.authnContextClassRefs) + p.config.authnContextClassRefs = JSON.stringify( + p.config.authnContextClassRefs + ); + if (p.config?.authnContextDeclRefs) + p.config.authnContextDeclRefs = JSON.stringify( + p.config.authnContextDeclRefs + ); try { await adminClient.identityProviders.update( { alias }, diff --git a/src/identity-providers/add/ReqAuthnConstraintsSettings.tsx b/src/identity-providers/add/ReqAuthnConstraintsSettings.tsx index c8cd8878a6..e29594321a 100644 --- a/src/identity-providers/add/ReqAuthnConstraintsSettings.tsx +++ b/src/identity-providers/add/ReqAuthnConstraintsSettings.tsx @@ -8,7 +8,7 @@ import { SelectVariant, } from "@patternfly/react-core"; -import { TextField } from "../component/TextField"; +import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput"; import { HelpItem } from "../../components/help-enabler/HelpItem"; const comparisonValues = ["exact", "minimum", "maximum", "better"]; @@ -61,14 +61,40 @@ export const ReqAuthnConstraints = () => { )} /> - - + + } + > + + + + } + > + + ); }; diff --git a/src/identity-providers/component/DisplayOrder.tsx b/src/identity-providers/component/DisplayOrder.tsx index eaf444015a..f86073618d 100644 --- a/src/identity-providers/component/DisplayOrder.tsx +++ b/src/identity-providers/component/DisplayOrder.tsx @@ -27,6 +27,7 @@ export const DisplayOrder = () => { defaultValue="" render={({ onChange, value }) => (