2021-10-01 15:03:38 +00:00
|
|
|
import React, { useState } from "react";
|
|
|
|
import { useTranslation } from "react-i18next";
|
|
|
|
import { Controller, UseFormMethods } from "react-hook-form";
|
|
|
|
import {
|
|
|
|
FormGroup,
|
|
|
|
Select,
|
|
|
|
SelectOption,
|
|
|
|
SelectVariant,
|
|
|
|
TextInput,
|
|
|
|
ValidatedOptions,
|
|
|
|
} from "@patternfly/react-core";
|
|
|
|
|
|
|
|
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
|
|
|
import _ from "lodash";
|
|
|
|
import type IdentityProviderMapperRepresentation from "@keycloak/keycloak-admin-client/lib/defs/identityProviderMapperRepresentation";
|
|
|
|
import type { IdentityProviderAddMapperParams } from "../routes/AddMapper";
|
|
|
|
import { useParams } from "react-router-dom";
|
|
|
|
import type { IdPMapperRepresentationWithAttributes } from "./AddMapper";
|
|
|
|
|
|
|
|
type AddMapperFormProps = {
|
|
|
|
mapperTypes?: Record<string, IdentityProviderMapperRepresentation>;
|
|
|
|
mapperType: string;
|
|
|
|
id: string;
|
|
|
|
updateMapperType: (mapperType: string) => void;
|
|
|
|
form: UseFormMethods<IdPMapperRepresentationWithAttributes>;
|
|
|
|
formValues: IdPMapperRepresentationWithAttributes;
|
2021-10-06 11:04:17 +00:00
|
|
|
isSocialIdP: boolean;
|
2021-10-01 15:03:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
export const AddMapperForm = ({
|
|
|
|
mapperTypes,
|
|
|
|
mapperType,
|
|
|
|
form,
|
|
|
|
id,
|
|
|
|
updateMapperType,
|
|
|
|
formValues,
|
2021-10-06 11:04:17 +00:00
|
|
|
isSocialIdP,
|
2021-10-01 15:03:38 +00:00
|
|
|
}: AddMapperFormProps) => {
|
|
|
|
const { t } = useTranslation("identity-providers");
|
|
|
|
|
|
|
|
const { control, register, errors } = form;
|
|
|
|
|
|
|
|
const [mapperTypeOpen, setMapperTypeOpen] = useState(false);
|
|
|
|
|
|
|
|
const syncModes = ["inherit", "import", "legacy", "force"];
|
|
|
|
const [syncModeOpen, setSyncModeOpen] = useState(false);
|
|
|
|
const { providerId } = useParams<IdentityProviderAddMapperParams>();
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<FormGroup
|
|
|
|
label={t("common:name")}
|
|
|
|
labelIcon={
|
|
|
|
<HelpItem
|
|
|
|
helpText="identity-providers-help:addIdpMapperName"
|
2021-12-14 14:56:36 +00:00
|
|
|
fieldLabelId="name"
|
2021-10-01 15:03:38 +00:00
|
|
|
/>
|
|
|
|
}
|
|
|
|
fieldId="kc-name"
|
|
|
|
isRequired
|
|
|
|
validated={
|
|
|
|
errors.name ? ValidatedOptions.error : ValidatedOptions.default
|
|
|
|
}
|
|
|
|
helperTextInvalid={t("common:required")}
|
|
|
|
>
|
|
|
|
<TextInput
|
|
|
|
ref={register({ required: true })}
|
|
|
|
type="text"
|
|
|
|
datatest-id="name-input"
|
|
|
|
id="kc-name"
|
|
|
|
name="name"
|
|
|
|
isDisabled={!!id}
|
|
|
|
validated={
|
|
|
|
errors.name ? ValidatedOptions.error : ValidatedOptions.default
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
<FormGroup
|
|
|
|
label={t("syncModeOverride")}
|
|
|
|
isRequired
|
|
|
|
labelIcon={
|
|
|
|
<HelpItem
|
|
|
|
helpText="identity-providers-help:syncModeOverride"
|
2021-12-14 14:56:36 +00:00
|
|
|
fieldLabelId="identity-providers:syncModeOverride"
|
2021-10-01 15:03:38 +00:00
|
|
|
/>
|
|
|
|
}
|
|
|
|
fieldId="syncMode"
|
|
|
|
>
|
|
|
|
<Controller
|
|
|
|
name="config.syncMode"
|
2021-10-28 14:51:26 +00:00
|
|
|
defaultValue={syncModes[0].toUpperCase()}
|
2021-10-01 15:03:38 +00:00
|
|
|
control={control}
|
|
|
|
render={({ onChange, value }) => (
|
|
|
|
<Select
|
|
|
|
toggleId="syncMode"
|
|
|
|
datatest-id="syncmode-select"
|
|
|
|
required
|
|
|
|
direction="down"
|
|
|
|
onToggle={() => setSyncModeOpen(!syncModeOpen)}
|
|
|
|
onSelect={(_, value) => {
|
|
|
|
onChange(value.toString().toUpperCase());
|
|
|
|
setSyncModeOpen(false);
|
|
|
|
}}
|
|
|
|
selections={t(`syncModes.${value.toLowerCase()}`)}
|
|
|
|
variant={SelectVariant.single}
|
|
|
|
aria-label={t("syncMode")}
|
|
|
|
isOpen={syncModeOpen}
|
|
|
|
>
|
|
|
|
{syncModes.map((option) => (
|
|
|
|
<SelectOption
|
|
|
|
selected={option === value}
|
|
|
|
key={option}
|
|
|
|
data-testid={option}
|
|
|
|
value={option.toUpperCase()}
|
|
|
|
>
|
|
|
|
{t(`syncModes.${option}`)}
|
|
|
|
</SelectOption>
|
|
|
|
))}
|
|
|
|
</Select>
|
|
|
|
)}
|
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
<FormGroup
|
|
|
|
label={t("mapperType")}
|
|
|
|
labelIcon={
|
|
|
|
<HelpItem
|
|
|
|
helpText={
|
|
|
|
formValues.identityProviderMapper ===
|
|
|
|
"saml-user-attribute-idp-mapper" &&
|
2021-10-06 11:04:17 +00:00
|
|
|
(providerId === "oidc" ||
|
|
|
|
providerId === "keycloak-oidc" ||
|
|
|
|
isSocialIdP)
|
2021-10-01 15:03:38 +00:00
|
|
|
? `identity-providers-help:oidcAttributeImporter`
|
|
|
|
: `identity-providers-help:${mapperType}`
|
|
|
|
}
|
2021-12-14 14:56:36 +00:00
|
|
|
fieldLabelId="identity-providers:mapperType"
|
2021-10-01 15:03:38 +00:00
|
|
|
/>
|
|
|
|
}
|
|
|
|
fieldId="identityProviderMapper"
|
|
|
|
>
|
|
|
|
<Controller
|
|
|
|
name="identityProviderMapper"
|
|
|
|
defaultValue={
|
2021-10-06 11:04:17 +00:00
|
|
|
isSocialIdP
|
|
|
|
? `${providerId.toLowerCase()}-user-attribute-mapper`
|
|
|
|
: providerId === "saml"
|
2021-10-01 15:03:38 +00:00
|
|
|
? "saml-advanced-role-idp-mapper"
|
2021-10-28 14:51:26 +00:00
|
|
|
: "hardcoded-user-session-attribute-idp-mapper"
|
2021-10-01 15:03:38 +00:00
|
|
|
}
|
|
|
|
control={control}
|
|
|
|
render={({ onChange, value }) => (
|
|
|
|
<Select
|
|
|
|
toggleId="identityProviderMapper"
|
|
|
|
data-testid="idp-mapper-select"
|
|
|
|
isDisabled={!!id}
|
|
|
|
required
|
|
|
|
direction="down"
|
|
|
|
onToggle={() => setMapperTypeOpen(!mapperTypeOpen)}
|
|
|
|
onSelect={(e, value) => {
|
|
|
|
const theMapper =
|
|
|
|
mapperTypes &&
|
|
|
|
Object.values(mapperTypes).find(
|
|
|
|
(item) =>
|
|
|
|
item.name?.toLowerCase() ===
|
|
|
|
value.toString().toLowerCase()
|
|
|
|
);
|
|
|
|
|
|
|
|
updateMapperType(_.camelCase(value.toString()));
|
|
|
|
onChange(theMapper?.id);
|
|
|
|
setMapperTypeOpen(false);
|
|
|
|
}}
|
|
|
|
selections={
|
|
|
|
mapperTypes &&
|
|
|
|
Object.values(mapperTypes).find(
|
|
|
|
(item) => item.id?.toLowerCase() === value
|
|
|
|
)?.name
|
|
|
|
}
|
|
|
|
variant={SelectVariant.single}
|
|
|
|
aria-label={t("syncMode")}
|
|
|
|
isOpen={mapperTypeOpen}
|
|
|
|
>
|
|
|
|
{mapperTypes &&
|
|
|
|
Object.values(mapperTypes).map((option) => (
|
|
|
|
<SelectOption
|
|
|
|
selected={option === value}
|
|
|
|
datatest-id={option.id}
|
|
|
|
key={option.name}
|
|
|
|
value={option.name?.toUpperCase()}
|
|
|
|
>
|
|
|
|
{t(`mapperTypes.${_.camelCase(option.name)}`)}
|
|
|
|
</SelectOption>
|
|
|
|
))}
|
|
|
|
</Select>
|
|
|
|
)}
|
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|