Change the way clients are stored in the form (#2184)
This commit is contained in:
parent
2cb4fcc29d
commit
7d2abf0a9b
2 changed files with 49 additions and 83 deletions
|
@ -59,8 +59,6 @@ import { AuthorizationScopes } from "./authorization/Scopes";
|
||||||
import { AuthorizationPolicies } from "./authorization/Policies";
|
import { AuthorizationPolicies } from "./authorization/Policies";
|
||||||
import { AuthorizationPermissions } from "./authorization/Permissions";
|
import { AuthorizationPermissions } from "./authorization/Permissions";
|
||||||
import { AuthorizationEvaluate } from "./authorization/AuthorizationEvaluate";
|
import { AuthorizationEvaluate } from "./authorization/AuthorizationEvaluate";
|
||||||
import type UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation";
|
|
||||||
import type RoleRepresentation from "@keycloak/keycloak-admin-client/lib/defs/roleRepresentation";
|
|
||||||
import {
|
import {
|
||||||
routableTab,
|
routableTab,
|
||||||
RoutableTabs,
|
RoutableTabs,
|
||||||
|
@ -205,24 +203,6 @@ export default function ClientDetails() {
|
||||||
});
|
});
|
||||||
|
|
||||||
const [client, setClient] = useState<ClientRepresentation>();
|
const [client, setClient] = useState<ClientRepresentation>();
|
||||||
const [clients, setClients] = useState<ClientRepresentation[]>([]);
|
|
||||||
const [clientRoles, setClientRoles] = useState<RoleRepresentation[]>([]);
|
|
||||||
const [users, setUsers] = useState<UserRepresentation[]>([]);
|
|
||||||
|
|
||||||
useFetch(
|
|
||||||
() =>
|
|
||||||
Promise.all([
|
|
||||||
adminClient.clients.find(),
|
|
||||||
adminClient.roles.find(),
|
|
||||||
adminClient.users.find(),
|
|
||||||
]),
|
|
||||||
([clients, roles, users]) => {
|
|
||||||
setClients(clients);
|
|
||||||
setClientRoles(roles);
|
|
||||||
setUsers(users);
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
const loader = async () => {
|
const loader = async () => {
|
||||||
const roles = await adminClient.clients.listRoles({ id: clientId });
|
const roles = await adminClient.clients.listRoles({ id: clientId });
|
||||||
|
@ -543,13 +523,7 @@ export default function ClientDetails() {
|
||||||
title={<TabTitleText>{t("evaluate")}</TabTitleText>}
|
title={<TabTitleText>{t("evaluate")}</TabTitleText>}
|
||||||
{...authenticationRoute("evaluate")}
|
{...authenticationRoute("evaluate")}
|
||||||
>
|
>
|
||||||
<AuthorizationEvaluate
|
<AuthorizationEvaluate client={client} save={save} />
|
||||||
clients={clients}
|
|
||||||
clientName={client.clientId}
|
|
||||||
clientRoles={clientRoles}
|
|
||||||
users={users}
|
|
||||||
save={save}
|
|
||||||
/>
|
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab
|
<Tab
|
||||||
id="export"
|
id="export"
|
||||||
|
|
|
@ -32,7 +32,6 @@ import { AttributeInput } from "../../components/attribute-input/AttributeInput"
|
||||||
import { defaultContextAttributes } from "../utils";
|
import { defaultContextAttributes } from "../utils";
|
||||||
import type EvaluationResultRepresentation from "@keycloak/keycloak-admin-client/lib/defs/evaluationResultRepresentation";
|
import type EvaluationResultRepresentation from "@keycloak/keycloak-admin-client/lib/defs/evaluationResultRepresentation";
|
||||||
import type ResourceRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceRepresentation";
|
import type ResourceRepresentation from "@keycloak/keycloak-admin-client/lib/defs/resourceRepresentation";
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
|
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
|
||||||
import type { KeyValueType } from "../../components/attribute-form/attribute-convert";
|
import type { KeyValueType } from "../../components/attribute-form/attribute-convert";
|
||||||
import { TableComposable, Th, Thead, Tr } from "@patternfly/react-table";
|
import { TableComposable, Th, Thead, Tr } from "@patternfly/react-table";
|
||||||
|
@ -43,13 +42,14 @@ import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState
|
||||||
|
|
||||||
interface EvaluateFormInputs
|
interface EvaluateFormInputs
|
||||||
extends Omit<ResourceEvaluation, "context" | "resources"> {
|
extends Omit<ResourceEvaluation, "context" | "resources"> {
|
||||||
applyToResource: boolean;
|
|
||||||
alias: string;
|
alias: string;
|
||||||
authScopes: string[];
|
authScopes: string[];
|
||||||
context: {
|
context: {
|
||||||
attributes: Record<string, string>[];
|
attributes: Record<string, string>[];
|
||||||
};
|
};
|
||||||
resources: Record<string, string>[];
|
resources: Record<string, string>[];
|
||||||
|
client: ClientRepresentation;
|
||||||
|
user: UserRepresentation;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AttributeType = {
|
export type AttributeType = {
|
||||||
|
@ -62,11 +62,8 @@ export type AttributeType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
type ClientSettingsProps = {
|
type ClientSettingsProps = {
|
||||||
clients: ClientRepresentation[];
|
client: ClientRepresentation;
|
||||||
clientName?: string;
|
|
||||||
save: () => void;
|
save: () => void;
|
||||||
users: UserRepresentation[];
|
|
||||||
clientRoles: RoleRepresentation[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AttributeForm = Omit<
|
export type AttributeForm = Omit<
|
||||||
|
@ -81,18 +78,12 @@ export type AttributeForm = Omit<
|
||||||
|
|
||||||
type Props = ClientSettingsProps & EvaluationResultRepresentation;
|
type Props = ClientSettingsProps & EvaluationResultRepresentation;
|
||||||
|
|
||||||
export const AuthorizationEvaluate = ({
|
export const AuthorizationEvaluate = ({ client }: Props) => {
|
||||||
clients,
|
|
||||||
clientRoles,
|
|
||||||
clientName,
|
|
||||||
users,
|
|
||||||
}: Props) => {
|
|
||||||
const form = useFormContext<EvaluateFormInputs>();
|
const form = useFormContext<EvaluateFormInputs>();
|
||||||
const { control, reset, trigger } = form;
|
const { control, reset, trigger } = form;
|
||||||
const { t } = useTranslation("clients");
|
const { t } = useTranslation("clients");
|
||||||
const adminClient = useAdminClient();
|
const adminClient = useAdminClient();
|
||||||
const realm = useRealm();
|
const realm = useRealm();
|
||||||
const { clientId } = useParams<{ clientId: string }>();
|
|
||||||
|
|
||||||
const [clientsDropdownOpen, setClientsDropdownOpen] = useState(false);
|
const [clientsDropdownOpen, setClientsDropdownOpen] = useState(false);
|
||||||
const [scopesDropdownOpen, setScopesDropdownOpen] = useState(false);
|
const [scopesDropdownOpen, setScopesDropdownOpen] = useState(false);
|
||||||
|
@ -103,8 +94,6 @@ export const AuthorizationEvaluate = ({
|
||||||
const [applyToResourceType, setApplyToResourceType] = useState(false);
|
const [applyToResourceType, setApplyToResourceType] = useState(false);
|
||||||
const [resources, setResources] = useState<ResourceRepresentation[]>([]);
|
const [resources, setResources] = useState<ResourceRepresentation[]>([]);
|
||||||
const [scopes, setScopes] = useState<ScopeRepresentation[]>([]);
|
const [scopes, setScopes] = useState<ScopeRepresentation[]>([]);
|
||||||
const [selectedClient, setSelectedClient] = useState<ClientRepresentation>();
|
|
||||||
const [selectedUser, setSelectedUser] = useState<UserRepresentation>();
|
|
||||||
const [evaluateResults, setEvaluateResults] = useState<
|
const [evaluateResults, setEvaluateResults] = useState<
|
||||||
EvaluationResultRepresentation[]
|
EvaluationResultRepresentation[]
|
||||||
>([]);
|
>([]);
|
||||||
|
@ -117,7 +106,7 @@ export const AuthorizationEvaluate = ({
|
||||||
const [key, setKey] = useState(0);
|
const [key, setKey] = useState(0);
|
||||||
|
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
setKey(new Date().getTime());
|
setKey(key + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const FilterType = {
|
const FilterType = {
|
||||||
|
@ -128,14 +117,33 @@ export const AuthorizationEvaluate = ({
|
||||||
|
|
||||||
const [filterType, setFilterType] = useState(FilterType.allResults);
|
const [filterType, setFilterType] = useState(FilterType.allResults);
|
||||||
|
|
||||||
|
const [clients, setClients] = useState<ClientRepresentation[]>([]);
|
||||||
|
const [clientRoles, setClientRoles] = useState<RoleRepresentation[]>([]);
|
||||||
|
const [users, setUsers] = useState<UserRepresentation[]>([]);
|
||||||
|
|
||||||
|
useFetch(
|
||||||
|
() =>
|
||||||
|
Promise.all([
|
||||||
|
adminClient.clients.find(),
|
||||||
|
adminClient.roles.find(),
|
||||||
|
adminClient.users.find(),
|
||||||
|
]),
|
||||||
|
([clients, roles, users]) => {
|
||||||
|
setClients(clients);
|
||||||
|
setClientRoles(roles);
|
||||||
|
setUsers(users);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
async () =>
|
async () =>
|
||||||
Promise.all([
|
Promise.all([
|
||||||
adminClient.clients.listResources({
|
adminClient.clients.listResources({
|
||||||
id: clientId,
|
id: client.id!,
|
||||||
}),
|
}),
|
||||||
adminClient.clients.listAllScopes({
|
adminClient.clients.listAllScopes({
|
||||||
id: clientId,
|
id: client.id!,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
([resources, scopes]) => {
|
([resources, scopes]) => {
|
||||||
|
@ -153,8 +161,8 @@ export const AuthorizationEvaluate = ({
|
||||||
const keys = formValues.resources.map(({ key }) => key);
|
const keys = formValues.resources.map(({ key }) => key);
|
||||||
const resEval: ResourceEvaluation = {
|
const resEval: ResourceEvaluation = {
|
||||||
roleIds: formValues.roleIds ?? [],
|
roleIds: formValues.roleIds ?? [],
|
||||||
clientId: selectedClient ? selectedClient.id! : clientId,
|
clientId: formValues.client.id!,
|
||||||
userId: selectedUser?.id!,
|
userId: formValues.user.id!,
|
||||||
resources: resources.filter((resource) => keys.includes(resource.name!)),
|
resources: resources.filter((resource) => keys.includes(resource.name!)),
|
||||||
entitlements: false,
|
entitlements: false,
|
||||||
context: {
|
context: {
|
||||||
|
@ -167,7 +175,7 @@ export const AuthorizationEvaluate = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const evaluation = await adminClient.clients.evaluateResource(
|
const evaluation = await adminClient.clients.evaluateResource(
|
||||||
{ id: clientId!, realm: realm.realm },
|
{ id: client.id!, realm: realm.realm },
|
||||||
resEval
|
resEval
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -357,29 +365,25 @@ export const AuthorizationEvaluate = ({
|
||||||
fieldId="client"
|
fieldId="client"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="clientId"
|
name="client"
|
||||||
rules={{
|
defaultValue={client}
|
||||||
validate: (value) => value.length > 0,
|
|
||||||
}}
|
|
||||||
defaultValue={clientName}
|
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="client"
|
toggleId="client"
|
||||||
onToggle={setClientsDropdownOpen}
|
onToggle={setClientsDropdownOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
setSelectedClient(value as ClientRepresentation);
|
onChange(value);
|
||||||
onChange((value as ClientRepresentation).clientId);
|
|
||||||
setClientsDropdownOpen(false);
|
setClientsDropdownOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={selectedClient === value ? value : clientName}
|
selections={value.clientId}
|
||||||
variant={SelectVariant.typeahead}
|
variant={SelectVariant.typeahead}
|
||||||
aria-label={t("client")}
|
aria-label={t("client")}
|
||||||
isOpen={clientsDropdownOpen}
|
isOpen={clientsDropdownOpen}
|
||||||
>
|
>
|
||||||
{clients.map((client) => (
|
{clients.map((client) => (
|
||||||
<SelectOption
|
<SelectOption
|
||||||
selected={client === value}
|
selected={client.id === value.id}
|
||||||
key={client.clientId}
|
key={client.clientId}
|
||||||
value={client}
|
value={client}
|
||||||
>
|
>
|
||||||
|
@ -399,12 +403,12 @@ export const AuthorizationEvaluate = ({
|
||||||
fieldLabelId="clients:userSelect"
|
fieldLabelId="clients:userSelect"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
fieldId="loginTheme"
|
fieldId="user"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="userId"
|
name="user"
|
||||||
rules={{
|
rules={{
|
||||||
validate: (value) => value.length > 0,
|
required: true,
|
||||||
}}
|
}}
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
control={control}
|
control={control}
|
||||||
|
@ -414,18 +418,17 @@ export const AuthorizationEvaluate = ({
|
||||||
placeholderText={t("selectAUser")}
|
placeholderText={t("selectAUser")}
|
||||||
onToggle={setUserDropdownOpen}
|
onToggle={setUserDropdownOpen}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
setSelectedUser(value as UserRepresentation);
|
onChange(value);
|
||||||
onChange((value as UserRepresentation).username);
|
|
||||||
setUserDropdownOpen(false);
|
setUserDropdownOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={value}
|
selections={value.username}
|
||||||
variant={SelectVariant.typeahead}
|
variant={SelectVariant.typeahead}
|
||||||
aria-label={t("user")}
|
aria-label={t("user")}
|
||||||
isOpen={userDropdownOpen}
|
isOpen={userDropdownOpen}
|
||||||
>
|
>
|
||||||
{users.map((user) => (
|
{users.map((user) => (
|
||||||
<SelectOption
|
<SelectOption
|
||||||
selected={user.username === value}
|
selected={user.username === value.username}
|
||||||
key={user.username}
|
key={user.username}
|
||||||
value={user}
|
value={user}
|
||||||
>
|
>
|
||||||
|
@ -498,26 +501,16 @@ export const AuthorizationEvaluate = ({
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
|
||||||
name="applyToResource"
|
|
||||||
defaultValue=""
|
|
||||||
control={control}
|
|
||||||
render={({ onChange, value }) => (
|
|
||||||
<Switch
|
<Switch
|
||||||
id="applyToResource-switch"
|
id="applyToResource-switch"
|
||||||
label={t("common:on")}
|
label={t("common:on")}
|
||||||
labelOff={t("common:off")}
|
labelOff={t("common:off")}
|
||||||
isChecked={value === "true"}
|
isChecked={applyToResourceType}
|
||||||
onChange={(value) => {
|
onChange={setApplyToResourceType}
|
||||||
onChange(value.toString());
|
|
||||||
setApplyToResourceType(value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
{!applyToResourceType && (
|
{!applyToResourceType ? (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={t("resourcesAndAuthScopes")}
|
label={t("resourcesAndAuthScopes")}
|
||||||
id="resourcesAndAuthScopes"
|
id="resourcesAndAuthScopes"
|
||||||
|
@ -541,8 +534,7 @@ export const AuthorizationEvaluate = ({
|
||||||
name="resources"
|
name="resources"
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
) : (
|
||||||
{applyToResourceType && (
|
|
||||||
<>
|
<>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={t("resourceType")}
|
label={t("resourceType")}
|
||||||
|
|
Loading…
Reference in a new issue