Add User federation kerberos settings controllers (#224)
* add form controllers to user fed kerberos settings * comments out test buttons * add optional settings with todos * correct the kerberos help text * updates cache policy dropdowns * use ComponentRepresentation * use FormAccess component * fix required settings and i18n * remove unused form * remove unused file Co-authored-by: jenny-s51 <jshandel12@gmail.com>
This commit is contained in:
parent
dc2ceef27b
commit
ad09c883e3
6 changed files with 330 additions and 93 deletions
|
@ -56,6 +56,14 @@
|
|||
"required": "Required field",
|
||||
"maxLength": "Max length {{length}}",
|
||||
|
||||
"createRealm": "Create Realm"
|
||||
"createRealm": "Create Realm",
|
||||
|
||||
"Sunday": "Sunday",
|
||||
"Monday": "Monday",
|
||||
"Tuesday": "Tuesday",
|
||||
"Wednesday": "Wednesday",
|
||||
"Thursday": "Thursday",
|
||||
"Friday": "Friday",
|
||||
"Saturday": "Saturday"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,55 @@
|
|||
import { Form, FormGroup, Select, SelectOption } from "@patternfly/react-core";
|
||||
import {
|
||||
FormGroup,
|
||||
Select,
|
||||
SelectOption,
|
||||
SelectVariant,
|
||||
TextInput,
|
||||
} from "@patternfly/react-core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import React from "react";
|
||||
import { HelpItem } from "../components/help-enabler/HelpItem";
|
||||
import React, { useState } from "react";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation";
|
||||
import { FormAccess } from "../components/form-access/FormAccess";
|
||||
|
||||
export const KerberosSettingsCache = () => {
|
||||
const { t } = useTranslation("user-federation");
|
||||
const helpText = useTranslation("user-federation-help").t;
|
||||
|
||||
const [isCachePolicyDropdownOpen, setIsCachePolicyDropdownOpen] = useState(
|
||||
false
|
||||
);
|
||||
const [isEvictionHourDropdownOpen, setIsEvictionHourDropdownOpen] = useState(
|
||||
false
|
||||
);
|
||||
const [
|
||||
isEvictionMinuteDropdownOpen,
|
||||
setIsEvictionMinuteDropdownOpen,
|
||||
] = useState(false);
|
||||
const [isEvictionDayDropdownOpen, setIsEvictionDayDropdownOpen] = useState(
|
||||
false
|
||||
);
|
||||
|
||||
const { control, register } = useForm<ComponentRepresentation>();
|
||||
|
||||
const hourOptions = [
|
||||
<SelectOption key={0} value={t("common:selectOne")} isPlaceholder />,
|
||||
];
|
||||
for (let index = 1; index <= 24; index++) {
|
||||
hourOptions.push(<SelectOption key={index + 1} value={index} />);
|
||||
}
|
||||
|
||||
const minuteOptions = [
|
||||
<SelectOption key={0} value={t("common:selectOne")} isPlaceholder />,
|
||||
];
|
||||
for (let index = 1; index <= 60; index++) {
|
||||
minuteOptions.push(<SelectOption key={index + 1} value={index} />);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Cache settings */}
|
||||
<Form isHorizontal>
|
||||
<FormAccess role="manage-realm" isHorizontal>
|
||||
<FormGroup
|
||||
label={t("cachePolicy")}
|
||||
labelIcon={
|
||||
|
@ -22,30 +61,180 @@ export const KerberosSettingsCache = () => {
|
|||
}
|
||||
fieldId="kc-cache-policy"
|
||||
>
|
||||
<Select
|
||||
toggleId="kc-cache-policy"
|
||||
// isOpen={openType}
|
||||
onToggle={() => {}}
|
||||
// variant={SelectVariant.single}
|
||||
// value={selected}
|
||||
// selections={selected}
|
||||
// onSelect={(_, value) => {
|
||||
// setSelected(value as string);
|
||||
// setOpenType(false);
|
||||
// }}
|
||||
aria-label="Select Input"
|
||||
>
|
||||
{/* {configFormats.map((configFormat) => ( */}
|
||||
<SelectOption
|
||||
key={"key"}
|
||||
value={"value"}
|
||||
// isSelected={selected === configFormat.id}
|
||||
>
|
||||
{"display name"}
|
||||
</SelectOption>
|
||||
</Select>
|
||||
<Controller
|
||||
name="cachePolicy"
|
||||
defaultValue=""
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
<Select
|
||||
toggleId="kc-cache-policy"
|
||||
required
|
||||
onToggle={() =>
|
||||
setIsCachePolicyDropdownOpen(!isCachePolicyDropdownOpen)
|
||||
}
|
||||
isOpen={isCachePolicyDropdownOpen}
|
||||
onSelect={(_, value) => {
|
||||
onChange(value as string);
|
||||
setIsCachePolicyDropdownOpen(false);
|
||||
}}
|
||||
selections={value}
|
||||
variant={SelectVariant.single}
|
||||
>
|
||||
<SelectOption
|
||||
key={0}
|
||||
value={t("common:selectOne")}
|
||||
isPlaceholder
|
||||
/>
|
||||
<SelectOption key={1} value="Default" />
|
||||
<SelectOption key={2} value="Something" />
|
||||
</Select>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
|
||||
{/* TODO: Field shows only if cache policy is EVICT_WEEKLY */}
|
||||
<FormGroup
|
||||
label={t("evictionDay")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={helpText("evictionDayHelp")}
|
||||
forLabel={t("evictionDay")}
|
||||
forID="kc-eviction-day"
|
||||
/>
|
||||
}
|
||||
fieldId="kc-eviction-day"
|
||||
>
|
||||
<Controller
|
||||
name="evictionDay"
|
||||
defaultValue=""
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
<Select
|
||||
toggleId="kc-eviction-day"
|
||||
required
|
||||
onToggle={() =>
|
||||
setIsEvictionDayDropdownOpen(!isEvictionDayDropdownOpen)
|
||||
}
|
||||
isOpen={isEvictionDayDropdownOpen}
|
||||
onSelect={(_, value) => {
|
||||
onChange(value as string);
|
||||
setIsEvictionDayDropdownOpen(false);
|
||||
}}
|
||||
selections={value}
|
||||
variant={SelectVariant.single}
|
||||
>
|
||||
<SelectOption
|
||||
key={0}
|
||||
value={t("common:selectOne")}
|
||||
isPlaceholder
|
||||
/>
|
||||
<SelectOption key={1} value={t("common:Sunday")} />
|
||||
<SelectOption key={2} value={t("common:Monday")} />
|
||||
<SelectOption key={3} value={t("common:Tuesday")} />
|
||||
<SelectOption key={4} value={t("common:Wednesday")} />
|
||||
<SelectOption key={5} value={t("common:Thursday")} />
|
||||
<SelectOption key={6} value={t("common:Friday")} />
|
||||
<SelectOption key={7} value={t("common:Saturday")} />
|
||||
</Select>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
|
||||
{/* TODO: Field shows only if cache policy is EVICT_WEEKLY or EVICT_DAILY */}
|
||||
{/* TODO: Investigate whether this should be a number field instead of a dropdown/text field */}
|
||||
<FormGroup
|
||||
label={t("evictionHour")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={helpText("evictionHourHelp")}
|
||||
forLabel={t("evictionHour")}
|
||||
forID="kc-eviction-hour"
|
||||
/>
|
||||
}
|
||||
fieldId="kc-eviction-hour"
|
||||
>
|
||||
<Controller
|
||||
name="evictionHour"
|
||||
defaultValue=""
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
<Select
|
||||
toggleId="kc-eviction-hour"
|
||||
onToggle={() =>
|
||||
setIsEvictionHourDropdownOpen(!isEvictionHourDropdownOpen)
|
||||
}
|
||||
isOpen={isEvictionHourDropdownOpen}
|
||||
onSelect={(_, value) => {
|
||||
onChange(value as string);
|
||||
setIsEvictionHourDropdownOpen(false);
|
||||
}}
|
||||
selections={value}
|
||||
variant={SelectVariant.single}
|
||||
>
|
||||
{hourOptions}
|
||||
</Select>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
|
||||
{/* TODO: Field shows only if cache policy is EVICT_WEEKLY or EVICT_DAILY */}
|
||||
{/* TODO: Investigate whether this should be a number field instead of a dropdown/text field */}
|
||||
<FormGroup
|
||||
label={t("evictionMinute")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={helpText("evictionMinuteHelp")}
|
||||
forLabel={t("evictionMinute")}
|
||||
forID="kc-eviction-minute"
|
||||
/>
|
||||
}
|
||||
fieldId="kc-eviction-minute"
|
||||
>
|
||||
<Controller
|
||||
name="evictionMinute"
|
||||
defaultValue=""
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
<Select
|
||||
toggleId="kc-eviction-minute"
|
||||
onToggle={() =>
|
||||
setIsEvictionMinuteDropdownOpen(!isEvictionMinuteDropdownOpen)
|
||||
}
|
||||
isOpen={isEvictionMinuteDropdownOpen}
|
||||
onSelect={(_, value) => {
|
||||
onChange(value as string);
|
||||
setIsEvictionMinuteDropdownOpen(false);
|
||||
}}
|
||||
selections={value}
|
||||
variant={SelectVariant.single}
|
||||
>
|
||||
{minuteOptions}
|
||||
</Select>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
|
||||
{/* TODO: Field shows only if cache policy is MAX_LIFESPAN */}
|
||||
<FormGroup
|
||||
label={t("maxLifespan")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={helpText("maxLifespanHelp")}
|
||||
forLabel={t("maxLifespan")}
|
||||
forID="kc-max-lifespan"
|
||||
/>
|
||||
}
|
||||
fieldId="kc-max-lifespan"
|
||||
>
|
||||
<TextInput
|
||||
isRequired
|
||||
type="text"
|
||||
id="kc-max-lifespan"
|
||||
name="maxLifespan"
|
||||
ref={register}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FormAccess>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,23 +1,29 @@
|
|||
import {
|
||||
Form,
|
||||
FormGroup,
|
||||
Select,
|
||||
SelectOption,
|
||||
SelectVariant,
|
||||
Switch,
|
||||
TextInput,
|
||||
} from "@patternfly/react-core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import React from "react";
|
||||
import { HelpItem } from "../components/help-enabler/HelpItem";
|
||||
import React, { useState } from "react";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation";
|
||||
import { FormAccess } from "../components/form-access/FormAccess";
|
||||
|
||||
export const KerberosSettingsRequired = () => {
|
||||
const { t } = useTranslation("user-federation");
|
||||
const helpText = useTranslation("user-federation-help").t;
|
||||
|
||||
const [isEditModeDropdownOpen, setIsEditModeDropdownOpen] = useState(false);
|
||||
const { register, control } = useForm<ComponentRepresentation>();
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Required settings */}
|
||||
<Form isHorizontal>
|
||||
<FormAccess role="manage-realm" isHorizontal>
|
||||
<FormGroup
|
||||
label={t("consoleDisplayName")}
|
||||
labelIcon={
|
||||
|
@ -34,9 +40,8 @@ export const KerberosSettingsRequired = () => {
|
|||
isRequired
|
||||
type="text"
|
||||
id="kc-console-display-name"
|
||||
name="kc-console-display-name"
|
||||
// value={value1}
|
||||
// onChange={this.handleTextInputChange1}
|
||||
name="consoleDisplayName"
|
||||
ref={register}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
|
@ -56,9 +61,8 @@ export const KerberosSettingsRequired = () => {
|
|||
isRequired
|
||||
type="text"
|
||||
id="kc-kerberos-realm"
|
||||
name="kc-kerberos-realm"
|
||||
// value={value1}
|
||||
// onChange={this.handleTextInputChange1}
|
||||
name="kerberosRealm"
|
||||
ref={register}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
|
@ -78,9 +82,8 @@ export const KerberosSettingsRequired = () => {
|
|||
isRequired
|
||||
type="text"
|
||||
id="kc-server-principal"
|
||||
name="kc-server-principal"
|
||||
// value={value1}
|
||||
// onChange={this.handleTextInputChange1}
|
||||
name="serverPrincipal"
|
||||
ref={register}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
|
@ -100,9 +103,8 @@ export const KerberosSettingsRequired = () => {
|
|||
isRequired
|
||||
type="text"
|
||||
id="kc-key-tab"
|
||||
name="kc-key-tab"
|
||||
// value={value1}
|
||||
// onChange={this.handleTextInputChange1}
|
||||
name="keyTab"
|
||||
ref={register}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
|
@ -118,14 +120,22 @@ export const KerberosSettingsRequired = () => {
|
|||
fieldId="kc-debug"
|
||||
hasNoPaddingTop
|
||||
>
|
||||
<Switch
|
||||
id={"kc-debug"}
|
||||
isChecked={true}
|
||||
isDisabled={false}
|
||||
onChange={() => undefined as any}
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
/>
|
||||
{" "}
|
||||
<Controller
|
||||
name="debug"
|
||||
defaultValue={false}
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
<Switch
|
||||
id={"kc-debug"}
|
||||
isDisabled={false}
|
||||
onChange={onChange}
|
||||
isChecked={value}
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
/>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
|
@ -140,50 +150,64 @@ export const KerberosSettingsRequired = () => {
|
|||
fieldId="kc-allow-password-authentication"
|
||||
hasNoPaddingTop
|
||||
>
|
||||
<Switch
|
||||
id={"kc-allow-password-authentication"}
|
||||
isChecked={true}
|
||||
isDisabled={false}
|
||||
onChange={() => undefined as any}
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
/>
|
||||
<Controller
|
||||
name="allowPasswordAuthentication"
|
||||
defaultValue={false}
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
<Switch
|
||||
id={"kc-allow-password-authentication"}
|
||||
isDisabled={false}
|
||||
onChange={onChange}
|
||||
isChecked={value}
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
/>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
|
||||
{/* TODO: Field shows only if allowPasswordAuthentication is TRUE */}
|
||||
<FormGroup
|
||||
label={t("editMode")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={helpText("editModeHelp")}
|
||||
helpText={helpText("editModeKerberosHelp")}
|
||||
forLabel={t("editMode")}
|
||||
forID="kc-edit-mode"
|
||||
/>
|
||||
}
|
||||
fieldId="kc-edit-mode"
|
||||
>
|
||||
<Select
|
||||
toggleId="kc-edit-mode"
|
||||
// isOpen={openType}
|
||||
onToggle={() => {}}
|
||||
// variant={SelectVariant.single}
|
||||
// value={selected}
|
||||
// selections={selected}
|
||||
// onSelect={(_, value) => {
|
||||
// setSelected(value as string);
|
||||
// setOpenType(false);
|
||||
// }}
|
||||
aria-label="edit mode" // TODO
|
||||
>
|
||||
{/* {configFormats.map((configFormat) => ( */}
|
||||
<SelectOption
|
||||
key={"key"}
|
||||
value={"value"}
|
||||
// isSelected={selected === configFormat.id}
|
||||
>
|
||||
{"display name"}
|
||||
</SelectOption>
|
||||
{/* ))} */}
|
||||
</Select>
|
||||
{" "}
|
||||
<Controller
|
||||
name="editMode"
|
||||
defaultValue=""
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
<Select
|
||||
toggleId="kc-edit-mode"
|
||||
required
|
||||
onToggle={() =>
|
||||
setIsEditModeDropdownOpen(!isEditModeDropdownOpen)
|
||||
}
|
||||
isOpen={isEditModeDropdownOpen}
|
||||
onSelect={(_, value) => {
|
||||
onChange(value as string);
|
||||
setIsEditModeDropdownOpen(false);
|
||||
}}
|
||||
selections={value}
|
||||
variant={SelectVariant.single}
|
||||
>
|
||||
<SelectOption
|
||||
key={0}
|
||||
value={t("common:selectOne")}
|
||||
isPlaceholder
|
||||
/>
|
||||
<SelectOption key={1} value="UNSYNCED" />
|
||||
</Select>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
|
@ -198,16 +222,23 @@ export const KerberosSettingsRequired = () => {
|
|||
fieldId="kc-update-first-login"
|
||||
hasNoPaddingTop
|
||||
>
|
||||
<Switch
|
||||
id={"kc-update-first-login"}
|
||||
isChecked={true}
|
||||
isDisabled={false}
|
||||
onChange={() => undefined as any}
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
/>
|
||||
<Controller
|
||||
name="updateFirstLogin"
|
||||
defaultValue={false}
|
||||
control={control}
|
||||
render={({ onChange, value }) => (
|
||||
<Switch
|
||||
id={"kc-update-first-login"}
|
||||
isDisabled={false}
|
||||
onChange={onChange}
|
||||
isChecked={value}
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
/>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
</FormAccess>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -22,7 +22,7 @@ export const LdapSettingsSearching = () => {
|
|||
label={t("editMode")}
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText={helpText("editModeHelp")}
|
||||
helpText={helpText("editModeLdapHelp")}
|
||||
forLabel={t("editMode")}
|
||||
forID="kc-edit-mode"
|
||||
/>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"bindDnHelp": "DN of the LDAP admin, which will be used by Keycloak to access LDAP server",
|
||||
"bindCredentialsHelp": "Password of LDAP admin. This field is able to obtain its value from vault, use ${vault.ID} format.",
|
||||
|
||||
"editModeHelp": "READ_ONLY is a read-only LDAP store. WRITABLE means data will be synced back to LDAP on demand. UNSYNCED means user data will be imported, but not synced back to LDAP.",
|
||||
"editModeLdapHelp": "READ_ONLY is a read-only LDAP store. WRITABLE means data will be synced back to LDAP on demand. UNSYNCED means user data will be imported, but not synced back to LDAP.",
|
||||
"usersDNHelp": "Full DN of LDAP tree where your users are. This DN is the parent of LDAP users. It could be for example 'ou=users,dc=example,dc=com' assuming that your typical user will have DN like 'uid='john',ou=users,dc=example,dc=com'",
|
||||
"usernameLdapAttributeHelp": "Name of LDAP attribute, which is mapped as Keycloak username. For many LDAP server vendors it can be 'uid'. For Active directory it can be 'sAMAccountName' or 'cn'. The attribute should be filled for all LDAP user records you want to import from LDAP to Keycloak.",
|
||||
"rdnLdapAttributeHelp": "Name of LDAP attribute, which is used as RDN (top attribute) of typical user DN. Usually it's the same as Username LDAP attribute, however it is not required. For example for Active directory, it is common to use 'cn' as RDN attribute when username attribute might be 'sAMAccountName'.",
|
||||
|
@ -33,6 +33,10 @@
|
|||
"useKerberosForPasswordAuthenticationHelp": "User Kerberos login module for authenticate username/password against Kerberos server instead of authenticating against LDAP server with Directory Service API",
|
||||
|
||||
"cachePolicyHelp": "Cache Policy for this storage provider. 'DEFAULT' is whatever the default settings are for the global cache. 'EVICT_DAILY' is a time of day every day that the cache will be invalidated. 'EVICT_WEEKLY' is a day of the week and time the cache will be invalidated. 'MAX_LIFESPAN' is the time in milliseconds that will be the lifespan of a cache entry.",
|
||||
"evictionDayHelp": "Day of the week the entry will become invalid",
|
||||
"evictionHourHelp": "Hour of the day the entry will become invalid",
|
||||
"evictionMinuteHelp": "Minute of the hour the entry will become invalid",
|
||||
"maxLifespanHelp": "Max lifespan of cache entry in milliseconds",
|
||||
|
||||
"enableLdapv3PasswordHelp": "Use the LDAPv3 Password Modify Extended Operation (RFC-3062). The password modify extended operation usually requires that LDAP user already has password in the LDAP server. So when this is used with 'Sync Registrations', it can be good to add also 'Hardcoded LDAP attribute mapper' with randomly generated initial password.",
|
||||
"validatePasswordPolicyHelp": "Determines if Keycloak should validate the password with the realm password policy before updating it",
|
||||
|
@ -46,6 +50,7 @@
|
|||
"keyTabHelp": "Location of Kerberos KeyTab file containing the credentials of server principal. For example, /etc/krb5.keytab",
|
||||
"debugHelp": "Enable/disable debug logging to standard output for Krb5LoginModule",
|
||||
"allowPasswordAuthenticationHelp": "Enable/disable possibility of username/password authentication against Kerberos database",
|
||||
"editModeKerberosHelp": "READ_ONLY means that password updates are not allowed and user always authenticates with Kerberos password. UNSYNCED means that the user can change the password in the Keycloak database and this one will be used instead of the Kerberos password",
|
||||
"updateFirstLoginHelp": "Update profile on first login"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,10 @@
|
|||
|
||||
"cacheSettings": "Cache settings",
|
||||
"cachePolicy": "Cache policy",
|
||||
"evictionDay": "Eviction day",
|
||||
"evictionHour": "Eviction hour",
|
||||
"evictionMinute": "Eviction minute",
|
||||
"maxLifespan": "Max lifespan",
|
||||
|
||||
"advancedSettings": "Advanced settings",
|
||||
"enableLdapv3Password": "Enable the LDAPv3 password modify extended operation",
|
||||
|
|
Loading…
Reference in a new issue