Kerberos and LDAP settings: Change hour and minute format to match old admin console UI (#353)

* change hour minute fmt to match old ui

* rm required max lifespan

* fix day of week default value

* create one shared cache settings component

* fix eslint and tests

* rm obsolete separate cache components

* try fixed snap
This commit is contained in:
mfrances17 2021-02-11 15:51:51 -05:00 committed by GitHub
parent 3430642003
commit afaa08fbc6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 56 additions and 322 deletions

View file

@ -10,7 +10,7 @@ import {
} from "@patternfly/react-core"; } from "@patternfly/react-core";
import { KerberosSettingsRequired } from "./kerberos/KerberosSettingsRequired"; import { KerberosSettingsRequired } from "./kerberos/KerberosSettingsRequired";
import { KerberosSettingsCache } from "./kerberos/KerberosSettingsCache"; import { SettingsCache } from "./shared/SettingsCache";
import { useRealm } from "../context/realm-context/RealmContext"; import { useRealm } from "../context/realm-context/RealmContext";
import { convertToFormValues } from "../util"; import { convertToFormValues } from "../util";
import ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation"; import ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation";
@ -150,7 +150,7 @@ export const UserFederationKerberosSettings = () => {
<KerberosSettingsRequired form={form} showSectionHeading /> <KerberosSettingsRequired form={form} showSectionHeading />
</PageSection> </PageSection>
<PageSection variant="light" isFilled> <PageSection variant="light" isFilled>
<KerberosSettingsCache form={form} showSectionHeading /> <SettingsCache form={form} showSectionHeading />
<Form onSubmit={form.handleSubmit(save)}> <Form onSubmit={form.handleSubmit(save)}>
<ActionGroup> <ActionGroup>
<Button variant="primary" type="submit"> <Button variant="primary" type="submit">

View file

@ -2,7 +2,7 @@ import { Wizard } from "@patternfly/react-core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import React from "react"; import React from "react";
import { KerberosSettingsRequired } from "./kerberos/KerberosSettingsRequired"; import { KerberosSettingsRequired } from "./kerberos/KerberosSettingsRequired";
import { KerberosSettingsCache } from "./kerberos/KerberosSettingsCache"; import { SettingsCache } from "./shared/SettingsCache";
import ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation"; import ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
@ -24,11 +24,7 @@ export const UserFederationKerberosWizard = () => {
{ {
name: t("cacheSettings"), name: t("cacheSettings"),
component: ( component: (
<KerberosSettingsCache <SettingsCache form={form} showSectionHeading showSectionDescription />
form={form}
showSectionHeading
showSectionDescription
/>
), ),
nextButtonText: t("common:finish"), // TODO: needs to disable until cache policy is valid nextButtonText: t("common:finish"), // TODO: needs to disable until cache policy is valid
}, },

View file

@ -12,7 +12,7 @@ import {
import { LdapSettingsAdvanced } from "./ldap/LdapSettingsAdvanced"; import { LdapSettingsAdvanced } from "./ldap/LdapSettingsAdvanced";
import { LdapSettingsKerberosIntegration } from "./ldap/LdapSettingsKerberosIntegration"; import { LdapSettingsKerberosIntegration } from "./ldap/LdapSettingsKerberosIntegration";
import { LdapSettingsCache } from "./ldap/LdapSettingsCache"; import { SettingsCache } from "./shared/SettingsCache";
import { LdapSettingsSynchronization } from "./ldap/LdapSettingsSynchronization"; import { LdapSettingsSynchronization } from "./ldap/LdapSettingsSynchronization";
import { LdapSettingsGeneral } from "./ldap/LdapSettingsGeneral"; import { LdapSettingsGeneral } from "./ldap/LdapSettingsGeneral";
import { LdapSettingsConnection } from "./ldap/LdapSettingsConnection"; import { LdapSettingsConnection } from "./ldap/LdapSettingsConnection";
@ -208,7 +208,7 @@ export const UserFederationLdapSettings = () => {
<LdapSettingsSearching form={form} /> <LdapSettingsSearching form={form} />
<LdapSettingsSynchronization form={form} /> <LdapSettingsSynchronization form={form} />
<LdapSettingsKerberosIntegration form={form} /> <LdapSettingsKerberosIntegration form={form} />
<LdapSettingsCache form={form} /> <SettingsCache form={form} />
<LdapSettingsAdvanced form={form} /> <LdapSettingsAdvanced form={form} />
</ScrollForm> </ScrollForm>
<Form onSubmit={form.handleSubmit(save)}> <Form onSubmit={form.handleSubmit(save)}>

View file

@ -10,7 +10,7 @@ import { LdapSettingsConnection } from "./ldap/LdapSettingsConnection";
import { LdapSettingsSearching } from "./ldap/LdapSettingsSearching"; import { LdapSettingsSearching } from "./ldap/LdapSettingsSearching";
import { LdapSettingsSynchronization } from "./ldap/LdapSettingsSynchronization"; import { LdapSettingsSynchronization } from "./ldap/LdapSettingsSynchronization";
import { LdapSettingsKerberosIntegration } from "./ldap/LdapSettingsKerberosIntegration"; import { LdapSettingsKerberosIntegration } from "./ldap/LdapSettingsKerberosIntegration";
import { LdapSettingsCache } from "./ldap/LdapSettingsCache"; import { SettingsCache } from "./shared/SettingsCache";
import { LdapSettingsAdvanced } from "./ldap/LdapSettingsAdvanced"; import { LdapSettingsAdvanced } from "./ldap/LdapSettingsAdvanced";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation"; import ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation";
@ -81,11 +81,7 @@ export const UserFederationLdapWizard = () => {
name: t("cacheSettings"), name: t("cacheSettings"),
id: "ldapCacheSettingsStep", id: "ldapCacheSettingsStep",
component: ( component: (
<LdapSettingsCache <SettingsCache form={form} showSectionHeading showSectionDescription />
form={form}
showSectionHeading
showSectionDescription
/>
), ),
}, },
{ {

View file

@ -41,7 +41,7 @@
"allowKerberosAuthenticationHelp": "Enable/disable HTTP authentication of users with SPNEGO/Kerberos tokens. The data about authenticated users will be provisioned from this LDAP server.", "allowKerberosAuthenticationHelp": "Enable/disable HTTP authentication of users with SPNEGO/Kerberos tokens. The data about authenticated users will be provisioned from this LDAP server.",
"useKerberosForPasswordAuthenticationHelp": "User Kerberos login module for authenticating username/password against Kerberos server instead of authenticating against LDAP server with Directory Service API", "useKerberosForPasswordAuthenticationHelp": "User Kerberos login module for authenticating username/password against Kerberos server instead of authenticating against LDAP server with Directory Service API",
"ldapCacheSettingsDescription": "This section contains options useful for caching users, which were loaded from this user storage provider.", "cacheSettingsDescription": "This section contains options useful for caching users, which were loaded from this user storage provider.",
"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.", "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", "evictionDayHelp": "Day of the week the entry will become invalid",
"evictionHourHelp": "Hour of the day the entry will become invalid", "evictionHourHelp": "Hour of the day the entry will become invalid",
@ -66,8 +66,6 @@
"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.", "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", "updateFirstLoginHelp": "Update profile on first login",
"kerberosCacheSettingsDescription": "This section contains a few basic options common to all user storage providers.",
"nameHelp": "Name of the mapper", "nameHelp": "Name of the mapper",
"mapperTypeHelp": "", "mapperTypeHelp": "",

View file

@ -1,281 +0,0 @@
import {
FormGroup,
Select,
SelectOption,
SelectVariant,
TextInput,
} from "@patternfly/react-core";
import { useTranslation } from "react-i18next";
import { HelpItem } from "../../components/help-enabler/HelpItem";
import React, { useState } from "react";
import { UseFormMethods, Controller, useWatch } from "react-hook-form";
import { FormAccess } from "../../components/form-access/FormAccess";
import _ from "lodash";
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
export type KerberosSettingsCacheProps = {
form: UseFormMethods;
showSectionHeading?: boolean;
showSectionDescription?: boolean;
};
export const KerberosSettingsCache = ({
form,
showSectionHeading = false,
showSectionDescription = false,
}: KerberosSettingsCacheProps) => {
const { t } = useTranslation("user-federation");
const helpText = useTranslation("user-federation-help").t;
const cachePolicyType = useWatch({
control: form.control,
name: "config.cachePolicy",
});
const [isCachePolicyDropdownOpen, setIsCachePolicyDropdownOpen] = useState(
false
);
const [isEvictionHourDropdownOpen, setIsEvictionHourDropdownOpen] = useState(
false
);
const [
isEvictionMinuteDropdownOpen,
setIsEvictionMinuteDropdownOpen,
] = useState(false);
const [isEvictionDayDropdownOpen, setIsEvictionDayDropdownOpen] = useState(
false
);
const hourOptions = [<SelectOption key={0} value={[`${1}`]} isPlaceholder />];
for (let index = 2; index <= 24; index++) {
hourOptions.push(<SelectOption key={index - 1} value={[`${index}`]} />);
}
const minuteOptions = [
<SelectOption key={0} value={[`${1}`]} isPlaceholder />,
];
for (let index = 2; index <= 60; index++) {
minuteOptions.push(<SelectOption key={index - 1} value={[`${index}`]} />);
}
return (
<>
{showSectionHeading && (
<WizardSectionHeader
title={t("cacheSettings")}
description={helpText("kerberosCacheSettingsDescription")}
showDescription={showSectionDescription}
/>
)}
{/* Cache settings */}
<FormAccess role="manage-realm" isHorizontal>
<FormGroup
label={t("cachePolicy")}
labelIcon={
<HelpItem
helpText={helpText("cachePolicyHelp")}
forLabel={t("cachePolicy")}
forID="kc-cache-policy"
/>
}
fieldId="kc-cache-policy"
>
<Controller
name="config.cachePolicy"
defaultValue={["DEFAULT"]}
control={form.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={["DEFAULT"]} isPlaceholder />
<SelectOption key={1} value={["EVICT_DAILY"]} />
<SelectOption key={2} value={["EVICT_WEEKLY"]} />
<SelectOption key={3} value={["MAX_LIFESPAN"]} />
<SelectOption key={4} value={["NO_CACHE"]} />
</Select>
)}
></Controller>
</FormGroup>
{_.isEqual(cachePolicyType, ["EVICT_WEEKLY"]) ? (
<FormGroup
label={t("evictionDay")}
labelIcon={
<HelpItem
helpText={helpText("evictionDayHelp")}
forLabel={t("evictionDay")}
forID="kc-eviction-day"
/>
}
isRequired
fieldId="kc-eviction-day"
>
<Controller
name="config.evictionDay"
defaultValue={[t("common:Sunday")]}
control={form.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={["1"]} isPlaceholder>
{t("common:Sunday")}
</SelectOption>
<SelectOption key={1} value={["2"]}>
{t("common:Monday")}
</SelectOption>
<SelectOption key={2} value={["3"]}>
{t("common:Tuesday")}
</SelectOption>
<SelectOption key={3} value={["4"]}>
{t("common:Wednesday")}
</SelectOption>
<SelectOption key={4} value={["5"]}>
{t("common:Thursday")}
</SelectOption>
<SelectOption key={5} value={["6"]}>
{t("common:Friday")}
</SelectOption>
<SelectOption key={6} value={["7"]}>
{t("common:Saturday")}
</SelectOption>
</Select>
)}
></Controller>
</FormGroup>
) : (
<></>
)}
{_.isEqual(cachePolicyType, ["EVICT_DAILY"]) ||
_.isEqual(cachePolicyType, ["EVICT_WEEKLY"]) ? (
<>
<FormGroup
label={t("evictionHour")}
labelIcon={
<HelpItem
helpText={helpText("evictionHourHelp")}
forLabel={t("evictionHour")}
forID="kc-eviction-hour"
/>
}
isRequired
fieldId="kc-eviction-hour"
>
<Controller
name="config.evictionHour"
defaultValue={["1"]}
control={form.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>
<FormGroup
label={t("evictionMinute")}
labelIcon={
<HelpItem
helpText={helpText("evictionMinuteHelp")}
forLabel={t("evictionMinute")}
forID="kc-eviction-minute"
/>
}
isRequired
fieldId="kc-eviction-minute"
>
<Controller
name="config.evictionMinute"
defaultValue={["1"]}
control={form.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>
</>
) : (
<></>
)}
{_.isEqual(cachePolicyType, ["MAX_LIFESPAN"]) ? (
<FormGroup
label={t("maxLifespan")}
labelIcon={
<HelpItem
helpText={helpText("maxLifespanHelp")}
forLabel={t("maxLifespan")}
forID="kc-max-lifespan"
/>
}
isRequired
fieldId="kc-max-lifespan"
>
<TextInput
isRequired
type="text"
id="kc-max-lifespan"
name="config.maxLifespan[0]"
ref={form.register}
/>
</FormGroup>
) : (
<></>
)}
</FormAccess>
</>
);
};

View file

@ -13,17 +13,17 @@ import { FormAccess } from "../../components/form-access/FormAccess";
import _ from "lodash"; import _ from "lodash";
import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader"; import { WizardSectionHeader } from "../../components/wizard-section-header/WizardSectionHeader";
export type LdapSettingsCacheProps = { export type SettingsCacheProps = {
form: UseFormMethods; form: UseFormMethods;
showSectionHeading?: boolean; showSectionHeading?: boolean;
showSectionDescription?: boolean; showSectionDescription?: boolean;
}; };
export const LdapSettingsCache = ({ export const SettingsCache = ({
form, form,
showSectionHeading = false, showSectionHeading = false,
showSectionDescription = false, showSectionDescription = false,
}: LdapSettingsCacheProps) => { }: SettingsCacheProps) => {
const { t } = useTranslation("user-federation"); const { t } = useTranslation("user-federation");
const helpText = useTranslation("user-federation-help").t; const helpText = useTranslation("user-federation-help").t;
@ -49,16 +49,42 @@ export const LdapSettingsCache = ({
false false
); );
const hourOptions = [<SelectOption key={0} value={[`${1}`]} isPlaceholder />]; const hourOptions = [
for (let index = 2; index <= 24; index++) { <SelectOption key={0} value={[`${0}`]} isPlaceholder>
hourOptions.push(<SelectOption key={index - 1} value={[`${index}`]} />); {[`0${0}`]}
</SelectOption>,
];
let hourDisplay = "";
for (let index = 1; index < 24; index++) {
if (index < 10) {
hourDisplay = `0${index}`;
} else {
hourDisplay = `${index}`;
}
hourOptions.push(
<SelectOption key={index} value={[`${index}`]}>
{hourDisplay}
</SelectOption>
);
} }
const minuteOptions = [ const minuteOptions = [
<SelectOption key={0} value={[`${1}`]} isPlaceholder />, <SelectOption key={0} value={[`${0}`]} isPlaceholder>
{[`0${0}`]}
</SelectOption>,
]; ];
for (let index = 2; index <= 60; index++) { let minuteDisplay = "";
minuteOptions.push(<SelectOption key={index - 1} value={[`${index}`]} />); for (let index = 1; index < 60; index++) {
if (index < 10) {
minuteDisplay = `0${index}`;
} else {
minuteDisplay = `${index}`;
}
minuteOptions.push(
<SelectOption key={index} value={[`${index}`]}>
{minuteDisplay}
</SelectOption>
);
} }
return ( return (
@ -66,7 +92,7 @@ export const LdapSettingsCache = ({
{showSectionHeading && ( {showSectionHeading && (
<WizardSectionHeader <WizardSectionHeader
title={t("cacheSettings")} title={t("cacheSettings")}
description={helpText("ldapCacheSettingsDescription")} description={helpText("cacheSettingsDescription")}
showDescription={showSectionDescription} showDescription={showSectionDescription}
/> />
)} )}
@ -124,8 +150,8 @@ export const LdapSettingsCache = ({
fieldId="kc-eviction-day" fieldId="kc-eviction-day"
> >
<Controller <Controller
name="config.evictionDay" name="config.evictionDay[0]"
defaultValue={[t("common:Sunday")]} defaultValue={"1"}
control={form.control} control={form.control}
render={({ onChange, value }) => ( render={({ onChange, value }) => (
<Select <Select
@ -142,25 +168,25 @@ export const LdapSettingsCache = ({
selections={value} selections={value}
variant={SelectVariant.single} variant={SelectVariant.single}
> >
<SelectOption key={0} value={["1"]} isPlaceholder> <SelectOption key={0} value="1" isPlaceholder>
{t("common:Sunday")} {t("common:Sunday")}
</SelectOption> </SelectOption>
<SelectOption key={1} value={["2"]}> <SelectOption key={1} value="2">
{t("common:Monday")} {t("common:Monday")}
</SelectOption> </SelectOption>
<SelectOption key={2} value={["3"]}> <SelectOption key={2} value="3">
{t("common:Tuesday")} {t("common:Tuesday")}
</SelectOption> </SelectOption>
<SelectOption key={3} value={["4"]}> <SelectOption key={3} value="4">
{t("common:Wednesday")} {t("common:Wednesday")}
</SelectOption> </SelectOption>
<SelectOption key={4} value={["5"]}> <SelectOption key={4} value="5">
{t("common:Thursday")} {t("common:Thursday")}
</SelectOption> </SelectOption>
<SelectOption key={5} value={["6"]}> <SelectOption key={5} value="6">
{t("common:Friday")} {t("common:Friday")}
</SelectOption> </SelectOption>
<SelectOption key={6} value={["7"]}> <SelectOption key={6} value="7">
{t("common:Saturday")} {t("common:Saturday")}
</SelectOption> </SelectOption>
</Select> </Select>
@ -187,7 +213,7 @@ export const LdapSettingsCache = ({
> >
<Controller <Controller
name="config.evictionHour" name="config.evictionHour"
defaultValue={["1"]} defaultValue={["0"]}
control={form.control} control={form.control}
render={({ onChange, value }) => ( render={({ onChange, value }) => (
<Select <Select
@ -222,7 +248,7 @@ export const LdapSettingsCache = ({
> >
<Controller <Controller
name="config.evictionMinute" name="config.evictionMinute"
defaultValue={["1"]} defaultValue={["0"]}
control={form.control} control={form.control}
render={({ onChange, value }) => ( render={({ onChange, value }) => (
<Select <Select
@ -262,7 +288,6 @@ export const LdapSettingsCache = ({
fieldId="kc-max-lifespan" fieldId="kc-max-lifespan"
> >
<TextInput <TextInput
isRequired
type="text" type="text"
id="kc-max-lifespan" id="kc-max-lifespan"
name="config.maxLifespan[0]" name="config.maxLifespan[0]"