From 83d5624bf4c78e5424ecf74a8c3f18518895b8aa Mon Sep 17 00:00:00 2001 From: Jenny <32821331+jenny-s51@users.noreply.github.com> Date: Wed, 22 Sep 2021 16:27:30 -0400 Subject: [PATCH] Identity Providers(Mappers): Edit mappers (#1140) * rebase dont fetch rolesbyID if mapperId save attributes fix cypress test cypress test updates fix cancel route route fix with Erik Apply suggestions from Jon's code review Co-authored-by: Jon Koops pr feedback from jon remove unused import * usefindbytestid * PR feedback from Jon * fix tests * fix save bug and feedback from Jon * remove unnecessary type * fix cypress test --- .../integration/identity_providers.spec.ts | 64 ++++--- .../identity_providers/AddMapperPage.ts | 38 ++++ .../attribute-form/AttributeForm.tsx | 4 +- .../IdentityProvidersSection.tsx | 36 ++-- .../add/AddIdentityProvider.tsx | 48 ++--- src/identity-providers/add/AddMapper.tsx | 167 ++++++++++++++---- src/identity-providers/add/DetailSettings.tsx | 45 ++++- .../add/OIDCGeneralSettings.tsx | 4 +- .../add/SamlGeneralSettings.tsx | 4 +- src/identity-providers/messages.ts | 5 +- src/identity-providers/routes.ts | 8 +- src/identity-providers/routes/AddMapper.ts | 4 +- src/identity-providers/routes/EditMapper.ts | 24 +++ .../routes/IdentityProvider.ts | 17 +- .../routes/IdentityProviderCreate.ts | 22 +++ .../routes/IdentityProviderKeycloakOidc.ts | 2 +- .../routes/IdentityProviderOidc.ts | 2 +- .../routes/IdentityProviderSaml.ts | 2 +- .../routes/IdentityProviderTab.ts | 25 --- src/realm-roles/AssociatedRolesModal.tsx | 21 +-- src/user/UserIdentityProviderLinks.tsx | 24 ++- 21 files changed, 395 insertions(+), 171 deletions(-) create mode 100644 src/identity-providers/routes/EditMapper.ts create mode 100644 src/identity-providers/routes/IdentityProviderCreate.ts delete mode 100644 src/identity-providers/routes/IdentityProviderTab.ts diff --git a/cypress/integration/identity_providers.spec.ts b/cypress/integration/identity_providers.spec.ts index 4be98d5bd1..e467cd17aa 100644 --- a/cypress/integration/identity_providers.spec.ts +++ b/cypress/integration/identity_providers.spec.ts @@ -19,6 +19,8 @@ describe("Identity provider test", () => { const createSuccessMsg = "Identity provider successfully created"; const createMapperSuccessMsg = "Mapper created successfully."; + const saveMapperSuccessMsg = "Mapper saved successfully."; + const changeSuccessMsg = "Successfully changed display order of identity providers"; const deletePrompt = "Delete provider?"; @@ -53,17 +55,10 @@ describe("Identity provider test", () => { listingPage.itemExist(identityProviderName); }); - it("should delete provider", () => { - const modalUtils = new ModalUtils(); - listingPage.deleteItem(identityProviderName); - modalUtils.checkModalTitle(deletePrompt).confirmModal(); - - masthead.checkNotificationMessage(deleteSuccessMsg); - }); - it("should create facebook provider", () => { createProviderPage - .clickCard("facebook") + .clickCreateDropdown() + .clickItem("facebook") .fill("facebook", "123") .clickAdd(); masthead.checkNotificationMessage(createSuccessMsg); @@ -71,18 +66,11 @@ describe("Identity provider test", () => { it("should change order of providers", () => { const orderDialog = new OrderDialog(); - const providers = ["facebook", identityProviderName, "bitbucket"]; + const providers = [identityProviderName, "facebook", "bitbucket"]; sidebarPage.goToIdentityProviders(); listingPage.itemExist("facebook"); - createProviderPage - .clickCreateDropdown() - .clickItem(identityProviderName) - .fill(identityProviderName, "123") - .clickAdd(); - - cy.wait(2000); sidebarPage.goToIdentityProviders(); listingPage.itemExist(identityProviderName); @@ -93,13 +81,14 @@ describe("Identity provider test", () => { .clickAdd(); cy.wait(2000); + sidebarPage.goToIdentityProviders(); listingPage.itemExist(identityProviderName); orderDialog.openDialog().checkOrder(providers); orderDialog.moveRowTo("facebook", identityProviderName); - orderDialog.checkOrder(["facebook", "bitbucket", identityProviderName]); + orderDialog.checkOrder(["bitbucket", identityProviderName, "facebook"]); orderDialog.clickSave(); masthead.checkNotificationMessage(changeSuccessMsg); @@ -129,6 +118,14 @@ describe("Identity provider test", () => { masthead.checkNotificationMessage(createSuccessMsg); }); + it("should delete provider", () => { + const modalUtils = new ModalUtils(); + listingPage.deleteItem(identityProviderName); + modalUtils.checkModalTitle(deletePrompt).confirmModal(); + + masthead.checkNotificationMessage(deleteSuccessMsg); + }); + it("should add facebook social mapper", () => { sidebarPage.goToIdentityProviders(); @@ -159,6 +156,32 @@ describe("Identity provider test", () => { masthead.checkNotificationMessage(createMapperSuccessMsg); }); + it("should edit facebook mapper", () => { + sidebarPage.goToIdentityProviders(); + + listingPage.goToItemDetails("facebook"); + + addMapperPage.goToMappersTab(); + + listingPage.goToItemDetails("facebook mapper"); + + addMapperPage.editSocialMapper(); + }); + + it("should edit SAML mapper", () => { + sidebarPage.goToIdentityProviders(); + + listingPage.goToItemDetails("saml"); + + addMapperPage.goToMappersTab(); + + listingPage.goToItemDetails("SAML mapper"); + + addMapperPage.editSAMLorOIDCMapper(); + + masthead.checkNotificationMessage(saveMapperSuccessMsg); + }); + it("clean up providers", () => { const modalUtils = new ModalUtils(); @@ -172,11 +195,6 @@ describe("Identity provider test", () => { modalUtils.checkModalTitle(deletePrompt).confirmModal(); masthead.checkNotificationMessage(deleteSuccessMsg); - sidebarPage.goToIdentityProviders(); - listingPage.itemExist("github").deleteItem("github"); - modalUtils.checkModalTitle(deletePrompt).confirmModal(); - masthead.checkNotificationMessage(deleteSuccessMsg); - sidebarPage.goToIdentityProviders(); listingPage.itemExist("oidc").deleteItem("oidc"); modalUtils.checkModalTitle(deletePrompt).confirmModal(); diff --git a/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts b/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts index 8558b63aae..4b26a8e572 100644 --- a/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts +++ b/cypress/support/pages/admin_console/manage/identity_providers/AddMapperPage.ts @@ -113,4 +113,42 @@ export default class AddMapperPage { return this; } + + editSocialMapper() { + cy.get(this.syncmodeSelectToggle).click(); + + cy.findByTestId("inherit").click(); + + cy.findByTestId(this.userSessionAttribute).clear(); + cy.findByTestId(this.userSessionAttribute).type( + "user session attribute_edited" + ); + cy.findByTestId(this.userSessionAttributeValue).clear(); + + cy.findByTestId(this.userSessionAttributeValue).type( + "user session attribute value_edited" + ); + + this.saveNewMapper(); + + return this; + } + + editSAMLorOIDCMapper() { + cy.get(this.syncmodeSelectToggle).click(); + + cy.findByTestId("legacy").click(); + + cy.get(this.attributesKeyInput).clear(); + cy.get(this.attributesKeyInput).type("key_edited"); + + cy.get(this.attributesValueInput).clear(); + cy.get(this.attributesValueInput).type("value_edited"); + + this.toggleSwitch(this.regexAttributeValuesSwitch); + + this.saveNewMapper(); + + return this; + } } diff --git a/src/components/attribute-form/AttributeForm.tsx b/src/components/attribute-form/AttributeForm.tsx index bc681ac53c..767e969ee2 100644 --- a/src/components/attribute-form/AttributeForm.tsx +++ b/src/components/attribute-form/AttributeForm.tsx @@ -68,6 +68,8 @@ export const AttributesForm = ({ const columns = ["Key", "Value"]; + const noSaveCancelButtons = !save && !reset; + const watchLast = inConfig ? watch(`config.attributes[${fields.length - 1}].key`, "") : watch(`attributes[${fields.length - 1}].key`, ""); @@ -78,8 +80,6 @@ export const AttributesForm = ({ } }, [fields]); - const noSaveCancelButtons = !save && !reset; - return ( { const { t } = useTranslation("identity-providers"); @@ -43,7 +44,6 @@ export const IdentityProvidersSection = () => { "groupName" ); const { realm } = useRealm(); - const { url } = useRouteMatch(); const history = useHistory(); const [key, setKey] = useState(0); const refresh = () => setKey(new Date().getTime()); @@ -73,9 +73,9 @@ export const IdentityProvidersSection = () => { const DetailLink = (identityProvider: IdentityProviderRepresentation) => ( { ); const navigateToCreate = (providerId: string) => - history.push(`${url}/${providerId}`); + history.push( + toIdentityProviderCreate({ + realm, + providerId, + }) + ); const identityProviderOptions = () => Object.keys(identityProviders).map((group) => ( @@ -105,11 +110,18 @@ export const IdentityProvidersSection = () => { navigateToCreate(provider.id)} - > - {provider.name} - + component={ + + {provider.name} + + } + /> ))} )); @@ -243,7 +255,7 @@ export const IdentityProvidersSection = () => { }, { name: "providerId", - displayKey: "identity-providers:provider", + displayKey: "identity-providers:providerDetails", cellFormatters: [upperCaseFormatter()], }, ]} diff --git a/src/identity-providers/add/AddIdentityProvider.tsx b/src/identity-providers/add/AddIdentityProvider.tsx index 70646ddd70..4edcb4828a 100644 --- a/src/identity-providers/add/AddIdentityProvider.tsx +++ b/src/identity-providers/add/AddIdentityProvider.tsx @@ -9,7 +9,6 @@ import { PageSection, } from "@patternfly/react-core"; -import type { BreadcrumbData } from "use-react-router-breadcrumbs"; import type IdentityProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/identityProviderRepresentation"; import { ViewHeader } from "../../components/view-header/ViewHeader"; import { toUpperCase } from "../../util"; @@ -18,34 +17,12 @@ import { useAdminClient } from "../../context/auth/AdminClient"; import { useRealm } from "../../context/realm-context/RealmContext"; import { useAlerts } from "../../components/alert/Alerts"; import { GeneralSettings } from "./GeneralSettings"; -import { toIdentityProviderTab } from "../routes/IdentityProviderTab"; - -export const IdentityProviderCrumb = ({ match, location }: BreadcrumbData) => { - const { t } = useTranslation(); - const { - params: { id }, - } = match as unknown as { - params: { [id: string]: string }; - }; - return ( - <> - {t( - `identity-providers:${ - location.pathname.endsWith("settings") - ? "provider" - : "addIdentityProvider" - }`, - { - provider: toUpperCase(id), - } - )} - - ); -}; +import { toIdentityProvider } from "../routes/IdentityProvider"; +import type { IdentityProviderCreateParams } from "../routes/IdentityProviderCreate"; export const AddIdentityProvider = () => { const { t } = useTranslation("identity-providers"); - const { id } = useParams<{ id: string }>(); + const { providerId } = useParams(); const form = useForm(); const { handleSubmit, @@ -61,11 +38,18 @@ export const AddIdentityProvider = () => { try { await adminClient.identityProviders.create({ ...provider, - providerId: id, - alias: id, + providerId, + alias: providerId, }); addAlert(t("createSuccess"), AlertVariant.success); - history.push(toIdentityProviderTab({ realm, providerId: id, alias: id })); + history.push( + toIdentityProvider({ + realm, + providerId: providerId!, + alias: providerId!, + tab: "settings", + }) + ); } catch (error) { addError("identity-providers:createError", error); } @@ -74,7 +58,9 @@ export const AddIdentityProvider = () => { return ( <> { onSubmit={handleSubmit(save)} > - +