Added missing groups claim field (#2170)

This commit is contained in:
Erik Jan de Wit 2022-03-07 18:08:46 +01:00 committed by GitHub
parent 01ab5b12e0
commit e3c0bb82a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 126 additions and 106 deletions

View file

@ -2,7 +2,7 @@ import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useFormContext, Controller } from "react-hook-form"; import { useFormContext, Controller } from "react-hook-form";
import { MinusCircleIcon } from "@patternfly/react-icons"; import { MinusCircleIcon } from "@patternfly/react-icons";
import { FormGroup, Button, Checkbox } from "@patternfly/react-core"; import { FormGroup, Button, Checkbox, TextInput } from "@patternfly/react-core";
import { import {
TableComposable, TableComposable,
Thead, Thead,
@ -24,7 +24,7 @@ export type GroupValue = {
export const Group = () => { export const Group = () => {
const { t } = useTranslation("clients"); const { t } = useTranslation("clients");
const { control, getValues, setValue, errors } = const { control, register, getValues, setValue, errors } =
useFormContext<{ groups?: GroupValue[] }>(); useFormContext<{ groups?: GroupValue[] }>();
const values = getValues("groups"); const values = getValues("groups");
@ -51,112 +51,129 @@ export const Group = () => {
); );
return ( return (
<FormGroup <>
label={t("groups")} <FormGroup
labelIcon={ label={t("groupsClaim")}
<HelpItem labelIcon={
helpText="clients-help:policyGroups" <HelpItem
fieldLabelId="clients:groups" helpText="clients-help:groupsClaim"
fieldLabelId="clients:groupsClaim"
/>
}
fieldId="groups"
>
<TextInput
type="text"
id="groupsClaim"
name="groupsClaim"
data-testid="groupsClaim"
ref={register}
/> />
} </FormGroup>
fieldId="groups" <FormGroup
helperTextInvalid={t("requiredGroups")} label={t("groups")}
validated={errors.groups ? "error" : "default"} labelIcon={
isRequired <HelpItem
> helpText="clients-help:policyGroups"
<Controller fieldLabelId="clients:groups"
name="groups" />
control={control} }
defaultValue={[]} fieldId="groups"
rules={{ helperTextInvalid={t("requiredGroups")}
validate: (value: GroupValue[]) => validated={errors.groups ? "error" : "default"}
value.filter((c) => c.id).length > 0, isRequired
}} >
render={({ onChange, value }) => ( <Controller
<> name="groups"
{open && ( control={control}
<GroupPickerDialog defaultValue={[]}
type="selectMany" rules={{
text={{ validate: (value: GroupValue[]) =>
title: "clients:addGroupsToGroupPolicy", value.filter(({ id }) => id).length > 0,
ok: "common:add", }}
render={({ onChange, value }) => (
<>
{open && (
<GroupPickerDialog
type="selectMany"
text={{
title: "clients:addGroupsToGroupPolicy",
ok: "common:add",
}}
onConfirm={(groups) => {
onChange([...value, ...groups.map(({ id }) => ({ id }))]);
setSelectedGroups([...selectedGroups, ...groups]);
setOpen(false);
}}
onClose={() => {
setOpen(false);
}}
filterGroups={selectedGroups.map(({ name }) => name!)}
/>
)}
<Button
data-testid="select-group-button"
variant="secondary"
onClick={() => {
setOpen(true);
}} }}
onConfirm={(groups) => { >
onChange([ {t("addGroups")}
...value, </Button>
...groups.map((group) => ({ id: group.id })), </>
]); )}
setSelectedGroups([...selectedGroups, ...groups]); />
setOpen(false); {selectedGroups.length > 0 && (
}} <TableComposable>
onClose={() => { <Thead>
setOpen(false); <Tr>
}} <Th>{t("groups")}</Th>
filterGroups={selectedGroups.map((g) => g.name!)} <Th>{t("extendToChildren")}</Th>
/> <Th />
)}
<Button
data-testid="select-group-button"
variant="secondary"
onClick={() => {
setOpen(true);
}}
>
{t("addGroups")}
</Button>
</>
)}
/>
{selectedGroups.length > 0 && (
<TableComposable>
<Thead>
<Tr>
<Th>{t("groups")}</Th>
<Th>{t("extendToChildren")}</Th>
<Th />
</Tr>
</Thead>
<Tbody>
{selectedGroups.map((group, index) => (
<Tr key={group.id}>
<Td>{group.path}</Td>
<Td>
<Controller
name={`groups[${index}].extendChildren`}
defaultValue={false}
control={control}
render={({ onChange, value }) => (
<Checkbox
id="extendChildren"
data-testid="standard"
name="extendChildren"
isChecked={value}
onChange={onChange}
isDisabled={group.subGroups?.length === 0}
/>
)}
/>
</Td>
<Td>
<Button
variant="link"
className="keycloak__client-authorization__policy-row-remove"
icon={<MinusCircleIcon />}
onClick={() => {
setValue("groups", [
...(values || []).filter((s) => s.id !== group.id),
]);
setSelectedGroups([
...selectedGroups.filter((s) => s.id !== group.id),
]);
}}
/>
</Td>
</Tr> </Tr>
))} </Thead>
</Tbody> <Tbody>
</TableComposable> {selectedGroups.map((group, index) => (
)} <Tr key={group.id}>
</FormGroup> <Td>{group.path}</Td>
<Td>
<Controller
name={`groups[${index}].extendChildren`}
defaultValue={false}
control={control}
render={({ onChange, value }) => (
<Checkbox
id="extendChildren"
data-testid="standard"
name="extendChildren"
isChecked={value}
onChange={onChange}
isDisabled={group.subGroups?.length === 0}
/>
)}
/>
</Td>
<Td>
<Button
variant="link"
className="keycloak__client-authorization__policy-row-remove"
icon={<MinusCircleIcon />}
onClick={() => {
setValue("groups", [
...(values || []).filter(({ id }) => id !== group.id),
]);
setSelectedGroups([
...selectedGroups.filter(({ id }) => id !== group.id),
]);
}}
/>
</Td>
</Tr>
))}
</Tbody>
</TableComposable>
)}
</FormGroup>
</>
); );
}; };

View file

@ -255,6 +255,8 @@ export default {
applyPolicy: applyPolicy:
"Specifies all the policies that must be applied to the scopes defined by this policy or permission.", "Specifies all the policies that must be applied to the scopes defined by this policy or permission.",
policyClient: "Specifies which client(s) are allowed by this policy.", policyClient: "Specifies which client(s) are allowed by this policy.",
groupsClaim:
"If defined, the policy will fetch user's groups from the given claim within an access token or ID token representing the identity asking permissions. If not defined, user's groups are obtained from your realm configuration.",
policyGroups: "Specifies which user(s) are allowed by this policy.", policyGroups: "Specifies which user(s) are allowed by this policy.",
targetClaim: "Specifies the target claim which the policy will fetch.", targetClaim: "Specifies the target claim which the policy will fetch.",
regexPattern: "Specifies the regex pattern.", regexPattern: "Specifies the regex pattern.",

View file

@ -230,6 +230,7 @@ export default {
applyPolicy: "Apply policy", applyPolicy: "Apply policy",
addClientScopes: "Add client scopes", addClientScopes: "Add client scopes",
clientScope: "Client scope", clientScope: "Client scope",
groupsClaim: "Groups claim",
addGroups: "Add groups", addGroups: "Add groups",
groups: "Groups", groups: "Groups",
users: "Users", users: "Users",