User Federation: populate Kerberos required and cache settings data (#243)

* pull in kerberos data

* fix build fails and cleanup msgs

* fix 2x build errs

* fix broken test

* fix route, bcrumb, and card click

* lint fixes

* final changes from PR review

* add old breadcrumb functionality back

* fix breadcrumb test

* lint fix
This commit is contained in:
mfrances17 2020-12-08 01:30:53 -05:00 committed by GitHub
parent 41062f88f4
commit ff43970e9a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 122 additions and 38 deletions

View file

@ -103,7 +103,7 @@ export const ClientScopeForm = () => {
>
<Tab
eventKey={0}
title={<TabTitleText>{t("settings")}</TabTitleText>}
title={<TabTitleText>{t("common:settings")}</TabTitleText>}
>
<Form
isHorizontal

View file

@ -19,8 +19,6 @@
"deleteMappingConfirm": "Are you sure you want to delete this mapping?",
"mappingUpdatedSuccess": "Mapping successfully updated",
"mappingUpdatedError": "Could not update mapping: '{{error}}'",
"mappingCreatedSuccess": "Mapping successfully created",
"mappingCreatedError": "Could not create mapping: '{{error}}'",
"realmRolePrefix": "Realm role prefix",
"multiValued": "Multivalued",
"tokenClaimName": "Token claim name",
@ -33,7 +31,6 @@
"createError": "Could not create client scope: '{{error}}'",
"updateSuccess": "Client scope updated",
"updateError": "Could not update client scope: '{{error}}'",
"settings": "Settings",
"mappers": "Mappers",
"mappersSearchFor": "Search for mapper",
"addMapper": "Add mapper",

View file

@ -210,7 +210,7 @@ export const ClientDetails = () => {
>
<Tab
eventKey={0}
title={<TabTitleText>{t("settings")}</TabTitleText>}
title={<TabTitleText>{t("common:settings")}</TabTitleText>}
>
<ClientSettings form={form} save={save} />
</Tab>

View file

@ -11,7 +11,6 @@
"name": "Name",
"formatOption": "Format option",
"downloadAdaptorTitle": "Download adaptor configs",
"settings": "Settings",
"credentials": "Credentials",
"clientScopes": "Client scopes",
"addClientScope": "Add client scope",

View file

@ -52,6 +52,8 @@
"identityProviders": "Identity providers",
"userFederation": "User federation",
"settings": "Settings",
"required": "Required field",
"maxLength": "Max length {{length}}",

View file

@ -13,6 +13,7 @@ import {
FlexItem,
} from "@patternfly/react-core";
import "./keycloak-card.css";
import { useHistory } from "react-router-dom";
export type KeycloakCardProps = {
id: string;
@ -26,6 +27,7 @@ export type KeycloakCardProps = {
};
export const KeycloakCard = ({
id,
dropdownItems,
title,
labelText,
@ -33,12 +35,23 @@ export const KeycloakCard = ({
footerText,
}: KeycloakCardProps) => {
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const history = useHistory();
const onDropdownToggle = () => {
setIsDropdownOpen(!isDropdownOpen);
};
const handleCardMenuClick = (e: any) => {
e.stopPropagation();
};
const openSettings = () => {
history.push(`/user-federation/${id}`);
};
return (
<Card>
<Card isSelectable onClick={openSettings}>
<CardHeader>
<CardActions>
{dropdownItems && (
@ -46,6 +59,7 @@ export const KeycloakCard = ({
isPlain
position={"right"}
toggle={<KebabToggle onToggle={onDropdownToggle} />}
onClick={(e) => handleCardMenuClick(e)}
isOpen={isDropdownOpen}
dropdownItems={dropdownItems}
/>

View file

@ -20,6 +20,7 @@ import { UserFederationSection } from "./user-federation/UserFederationSection";
import { UsersSection } from "./user/UsersSection";
import { MappingDetails } from "./client-scopes/details/MappingDetails";
import { ClientDetails } from "./clients/ClientDetails";
import { UserFederationKerberosSettings } from "./user-federation/UserFederationKerberosSettings";
import { RoleMappingForm } from "./client-scopes/add/RoleMappingForm";
export type RouteDef = {
@ -164,6 +165,12 @@ export const routes: RoutesFn = (t: TFunction) => [
breadcrumb: t("userFederation"),
access: "view-realm",
},
{
path: "/user-federation/:id",
component: UserFederationKerberosSettings,
breadcrumb: t("common:settings"),
access: "view-realm",
},
{
path: "/",
component: ClientsSection,

View file

@ -7,15 +7,63 @@ import {
} from "@patternfly/react-core";
import { useTranslation } from "react-i18next";
import { HelpItem } from "../components/help-enabler/HelpItem";
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { convertToFormValues } from "../util";
import ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation";
import { FormAccess } from "../components/form-access/FormAccess";
import { useAdminClient } from "../context/auth/AdminClient";
import { useParams } from "react-router-dom";
export const KerberosSettingsCache = () => {
const { t } = useTranslation("user-federation");
const helpText = useTranslation("user-federation-help").t;
const adminClient = useAdminClient();
const { register, control, setValue } = useForm<ComponentRepresentation>();
const { id } = useParams<{ id: string }>();
const convertToDays = (num: string) => {
switch (num) {
case "1":
return t("common:Sunday");
case "2":
return t("common:Monday");
case "3":
return t("common:Tuesday");
case "4":
return t("common:Wednesday");
case "5":
return t("common:Thursday");
case "6":
return t("common:Friday");
case "7":
return t("common:Saturday");
default:
return t("common:selectOne");
}
};
const setupForm = (component: ComponentRepresentation) => {
Object.entries(component).map((entry) => {
if (entry[0] === "config") {
convertToFormValues(entry[1], "config", setValue);
setValue("config.evictionDay", convertToDays(entry[1].evictionDay[0]));
} else {
setValue(entry[0], entry[1]);
}
});
};
useEffect(() => {
(async () => {
const fetchedComponent = await adminClient.components.findOne({ id });
if (fetchedComponent) {
setupForm(fetchedComponent);
}
})();
}, []);
const [isCachePolicyDropdownOpen, setIsCachePolicyDropdownOpen] = useState(
false
);
@ -30,8 +78,6 @@ export const KerberosSettingsCache = () => {
false
);
const { control, register } = useForm<ComponentRepresentation>();
const hourOptions = [
<SelectOption key={0} value={t("common:selectOne")} isPlaceholder />,
];
@ -62,7 +108,7 @@ export const KerberosSettingsCache = () => {
fieldId="kc-cache-policy"
>
<Controller
name="cachePolicy"
name="config.cachePolicy"
defaultValue=""
control={control}
render={({ onChange, value }) => (
@ -85,14 +131,15 @@ export const KerberosSettingsCache = () => {
value={t("common:selectOne")}
isPlaceholder
/>
<SelectOption key={1} value="Default" />
<SelectOption key={2} value="Something" />
<SelectOption key={1} value="DEFAULT" />
<SelectOption key={2} value="EVICT_DAILY" />
<SelectOption key={3} value="EVICT_WEEKLY" />
<SelectOption key={4} value="MAX_LIFESPAN" />
<SelectOption key={5} value="NO_CACHE" />
</Select>
)}
></Controller>
</FormGroup>
{/* TODO: Field shows only if cache policy is EVICT_WEEKLY */}
<FormGroup
label={t("evictionDay")}
labelIcon={
@ -105,7 +152,7 @@ export const KerberosSettingsCache = () => {
fieldId="kc-eviction-day"
>
<Controller
name="evictionDay"
name="config.evictionDay"
defaultValue=""
control={control}
render={({ onChange, value }) => (
@ -139,8 +186,6 @@ export const KerberosSettingsCache = () => {
)}
></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")}
@ -154,7 +199,7 @@ export const KerberosSettingsCache = () => {
fieldId="kc-eviction-hour"
>
<Controller
name="evictionHour"
name="config.evictionHour"
defaultValue=""
control={control}
render={({ onChange, value }) => (
@ -176,8 +221,6 @@ export const KerberosSettingsCache = () => {
)}
></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")}
@ -191,7 +234,7 @@ export const KerberosSettingsCache = () => {
fieldId="kc-eviction-minute"
>
<Controller
name="evictionMinute"
name="config.evictionMinute"
defaultValue=""
control={control}
render={({ onChange, value }) => (
@ -213,8 +256,6 @@ export const KerberosSettingsCache = () => {
)}
></Controller>
</FormGroup>
{/* TODO: Field shows only if cache policy is MAX_LIFESPAN */}
<FormGroup
label={t("maxLifespan")}
labelIcon={
@ -230,7 +271,7 @@ export const KerberosSettingsCache = () => {
isRequired
type="text"
id="kc-max-lifespan"
name="maxLifespan"
name="config.maxLifespan"
ref={register}
/>
</FormGroup>

View file

@ -1,3 +1,4 @@
import React, { useEffect, useState } from "react";
import {
FormGroup,
Select,
@ -8,17 +9,39 @@ import {
} from "@patternfly/react-core";
import { useTranslation } from "react-i18next";
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";
import { useAdminClient } from "../context/auth/AdminClient";
import { useParams } from "react-router-dom";
import { convertToFormValues } from "../util";
export const KerberosSettingsRequired = () => {
const { t } = useTranslation("user-federation");
const helpText = useTranslation("user-federation-help").t;
const adminClient = useAdminClient();
const [isEditModeDropdownOpen, setIsEditModeDropdownOpen] = useState(false);
const { register, control } = useForm<ComponentRepresentation>();
const { register, control, setValue } = useForm<ComponentRepresentation>();
const { id } = useParams<{ id: string }>();
const setupForm = (component: ComponentRepresentation) => {
Object.entries(component).map((entry) => {
if (entry[0] === "config") {
convertToFormValues(entry[1], "config", setValue);
} else {
setValue(entry[0], entry[1]);
}
});
};
useEffect(() => {
(async () => {
const fetchedComponent = await adminClient.components.findOne({ id });
if (fetchedComponent) {
setupForm(fetchedComponent);
}
})();
}, []);
return (
<>
@ -40,7 +63,7 @@ export const KerberosSettingsRequired = () => {
isRequired
type="text"
id="kc-console-display-name"
name="consoleDisplayName"
name="name"
ref={register}
/>
</FormGroup>
@ -61,7 +84,7 @@ export const KerberosSettingsRequired = () => {
isRequired
type="text"
id="kc-kerberos-realm"
name="kerberosRealm"
name="config.kerberosRealm"
ref={register}
/>
</FormGroup>
@ -82,7 +105,7 @@ export const KerberosSettingsRequired = () => {
isRequired
type="text"
id="kc-server-principal"
name="serverPrincipal"
name="config.serverPrincipal"
ref={register}
/>
</FormGroup>
@ -103,7 +126,7 @@ export const KerberosSettingsRequired = () => {
isRequired
type="text"
id="kc-key-tab"
name="keyTab"
name="config.keyTab"
ref={register}
/>
</FormGroup>
@ -122,7 +145,7 @@ export const KerberosSettingsRequired = () => {
>
{" "}
<Controller
name="debug"
name="config.debug"
defaultValue={false}
control={control}
render={({ onChange, value }) => (
@ -151,7 +174,7 @@ export const KerberosSettingsRequired = () => {
hasNoPaddingTop
>
<Controller
name="allowPasswordAuthentication"
name="config.allowPasswordAuthentication"
defaultValue={false}
control={control}
render={({ onChange, value }) => (
@ -181,8 +204,8 @@ export const KerberosSettingsRequired = () => {
>
{" "}
<Controller
name="editMode"
defaultValue=""
name="config.editMode"
defaultValue={t("common:selectOne")}
control={control}
render={({ onChange, value }) => (
<Select
@ -204,7 +227,8 @@ export const KerberosSettingsRequired = () => {
value={t("common:selectOne")}
isPlaceholder
/>
<SelectOption key={1} value="UNSYNCED" />
<SelectOption key={1} value="READ_ONLY" />
<SelectOption key={2} value="UNSYNCED" />
</Select>
)}
></Controller>
@ -223,7 +247,7 @@ export const KerberosSettingsRequired = () => {
hasNoPaddingTop
>
<Controller
name="updateFirstLogin"
name="config.updateProfileFirstLogin"
defaultValue={false}
control={control}
render={({ onChange, value }) => (