now checks if data could be loaded and throw error (#1265)

This commit is contained in:
Erik Jan de Wit 2021-09-30 10:58:48 +02:00 committed by GitHub
parent 5d8dce7143
commit bd8fc558d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 846 additions and 792 deletions

1405
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -24,7 +24,7 @@
"prepare": "husky install" "prepare": "husky install"
}, },
"dependencies": { "dependencies": {
"@keycloak/keycloak-admin-client": "^16.0.0-dev.25", "@keycloak/keycloak-admin-client": "^16.0.0-dev.26",
"@patternfly/patternfly": "^4.135.2", "@patternfly/patternfly": "^4.135.2",
"@patternfly/react-code-editor": "^4.3.61", "@patternfly/react-code-editor": "^4.3.61",
"@patternfly/react-core": "4.157.3", "@patternfly/react-core": "4.157.3",

View file

@ -77,7 +77,10 @@ export const App = ({ adminClient }: AdminClientProps) => {
> >
<ErrorBoundary <ErrorBoundary
FallbackComponent={ErrorRenderer} FallbackComponent={ErrorRenderer}
onReset={() => window.location.reload()} onReset={() =>
(window.location.href =
window.location.origin + window.location.pathname)
}
> >
<Switch> <Switch>
{routes.map((route, i) => ( {routes.map((route, i) => (

View file

@ -60,6 +60,10 @@ export const AuthenticationSection = () => {
const clients = await adminClient.clients.find(); const clients = await adminClient.clients.find();
const idps = await adminClient.identityProviders.find(); const idps = await adminClient.identityProviders.find();
const realmRep = await adminClient.realms.findOne({ realm }); const realmRep = await adminClient.realms.findOne({ realm });
if (!realmRep) {
throw new Error(t("common:notFound"));
}
const defaultFlows = Object.entries(realmRep) const defaultFlows = Object.entries(realmRep)
.filter((entry) => realmFlows.includes(entry[0])) .filter((entry) => realmFlows.includes(entry[0]))
.map((entry) => entry[1]); .map((entry) => entry[1]);

View file

@ -67,9 +67,13 @@ export const FlowDetails = () => {
async () => { async () => {
const flows = await adminClient.authenticationManagement.getFlows(); const flows = await adminClient.authenticationManagement.getFlows();
const flow = flows.find((f) => f.id === id); const flow = flows.find((f) => f.id === id);
if (!flow) {
throw new Error(t("common:notFound"));
}
const executions = const executions =
await adminClient.authenticationManagement.getExecutions({ await adminClient.authenticationManagement.getExecutions({
flow: flow?.alias!, flow: flow.alias!,
}); });
return { flow, executions }; return { flow, executions };
}, },

View file

@ -56,6 +56,10 @@ export const MappingDetails = () => {
id, id,
mapperId, mapperId,
}); });
if (!data) {
throw new Error(t("common:notFound"));
}
const mapperTypes = serverInfo.protocolMapperTypes![data!.protocol!]; const mapperTypes = serverInfo.protocolMapperTypes![data!.protocol!];
const mapping = mapperTypes.find( const mapping = mapperTypes.find(
(type) => type.id === data!.protocolMapper (type) => type.id === data!.protocolMapper
@ -71,11 +75,17 @@ export const MappingDetails = () => {
}; };
} else { } else {
const scope = await adminClient.clientScopes.findOne({ id }); const scope = await adminClient.clientScopes.findOne({ id });
if (!scope) {
throw new Error(t("common:notFound"));
}
const protocolMappers = const protocolMappers =
serverInfo.protocolMapperTypes![scope.protocol!]; serverInfo.protocolMapperTypes![scope.protocol!];
const mapping = protocolMappers.find( const mapping = protocolMappers.find(
(mapper) => mapper.id === mapperId (mapper) => mapper.id === mapperId
)!; );
if (!mapping) {
throw new Error(t("common:notFound"));
}
return { return {
mapping, mapping,
config: { config: {

View file

@ -51,10 +51,14 @@ export const ClientScopeForm = () => {
useFetch( useFetch(
async () => { async () => {
if (id) { if (id) {
const clientScope = await adminClient.clientScopes.findOne({ id });
if (!clientScope) {
throw new Error(t("common:notFound"));
}
return { return {
...(await adminClient.clientScopes.findOne({ id })), ...clientScope,
type, type,
} as ClientScopeDefaultOptionalType; };
} }
}, },
(clientScope) => { (clientScope) => {
@ -113,6 +117,10 @@ export const ClientScopeForm = () => {
const scope = await adminClient.clientScopes.findOneByName({ const scope = await adminClient.clientScopes.findOneByName({
name: clientScopes.name!, name: clientScopes.name!,
}); });
if (!scope) {
throw new Error(t("common:notFound"));
}
changeScope( changeScope(
adminClient, adminClient,
{ ...clientScopes, id: scope.id }, { ...clientScopes, id: scope.id },

View file

@ -222,6 +222,9 @@ export const ClientDetails = () => {
useFetch( useFetch(
() => adminClient.clients.findOne({ id: clientId }), () => adminClient.clients.findOne({ id: clientId }),
(fetchedClient) => { (fetchedClient) => {
if (!fetchedClient) {
throw new Error(t("common:notFound"));
}
setClient(fetchedClient); setClient(fetchedClient);
setupForm(fetchedClient); setupForm(fetchedClient);
}, },

View file

@ -56,7 +56,7 @@ export default {
category: "Category", category: "Category",
priority: "Priority", priority: "Priority",
unexpectedError: "An unexpected error occurred: '{{error}}'", unexpectedError: "An unexpected error occurred: '{{error}}'",
retry: "Retry", retry: "Press here to refresh and continue",
plus: "Plus", plus: "Plus",
minus: "Minus", minus: "Minus",
@ -145,5 +145,7 @@ export default {
onDragMove: "Dragging item {{item}}", onDragMove: "Dragging item {{item}}",
onDragCancel: "Dragging cancelled. List is unchanged.", onDragCancel: "Dragging cancelled. List is unchanged.",
onDragFinish: "Dragging finished {{list}}", onDragFinish: "Dragging finished {{list}}",
notFound: "Could not find the resource that you are looking for",
}, },
}; };

View file

@ -71,6 +71,9 @@ export const GroupPickerDialog = ({
}); });
} else { } else {
group = await adminClient.groups.findOne({ id: groupId }); group = await adminClient.groups.findOne({ id: groupId });
if (!group) {
throw new Error(t("common:notFound"));
}
groups = group.subGroups!; groups = group.subGroups!;
} }

View file

@ -45,11 +45,19 @@ export const GroupTable = () => {
const id = getLastId(location.pathname); const id = getLastId(location.pathname);
const loader = async () => { const loader = async () => {
const groupsData = id let groupsData = undefined;
? (await adminClient.groups.findOne({ id })).subGroups if (id) {
: await adminClient.groups.find({ const group = await adminClient.groups.findOne({ id });
briefRepresentation: false, if (!group) {
} as unknown as any); throw new Error(t("common:notFound"));
}
groupsData = group.subGroups;
} else {
groupsData = await adminClient.groups.find({
briefRepresentation: false,
});
}
if (!groupsData) { if (!groupsData) {
history.push(`/${realm}/groups`); history.push(`/${realm}/groups`);

View file

@ -62,7 +62,11 @@ export const GroupsSection = () => {
const groups: GroupRepresentation[] = []; const groups: GroupRepresentation[] = [];
for (const i of ids!) { for (const i of ids!) {
const group = await adminClient.groups.findOne({ id: i }); const group = await adminClient.groups.findOne({ id: i });
if (group) groups.push(group); if (group) {
groups.push(group);
} else {
throw new Error(t("common:notFound"));
}
} }
return groups; return groups;
} }
@ -97,7 +101,7 @@ export const GroupsSection = () => {
/> />
)} )}
<ViewHeader <ViewHeader
titleKey={!id ? "groups:groups" : currentGroup()?.name!} titleKey={!id ? "groups:groups" : currentGroup().name!}
subKey={!id ? "groups:groupsDescription" : ""} subKey={!id ? "groups:groupsDescription" : ""}
divider={!id} divider={!id}
dropdownItems={ dropdownItems={

View file

@ -60,8 +60,13 @@ export const IdentityProvidersSection = () => {
const { addAlert, addError } = useAlerts(); const { addAlert, addError } = useAlerts();
useFetch( useFetch(
async () => async () => {
(await adminClient.realms.findOne({ realm })).identityProviders!, const provider = await adminClient.realms.findOne({ realm });
if (!provider) {
throw new Error(t("common:notFound"));
}
return provider.identityProviders!;
},
(providers) => { (providers) => {
setProviders(providers); setProviders(providers);
}, },

View file

@ -127,6 +127,10 @@ export const DetailSettings = () => {
useFetch( useFetch(
() => adminClient.identityProviders.findOne({ alias }), () => adminClient.identityProviders.findOne({ alias }),
(fetchedProvider) => { (fetchedProvider) => {
if (!fetchedProvider) {
throw new Error(t("common:notFound"));
}
reset(fetchedProvider); reset(fetchedProvider);
setProvider(fetchedProvider); setProvider(fetchedProvider);
}, },

View file

@ -1,48 +0,0 @@
import React, { useEffect, useState } from "react";
import type KeycloakAdminClient from "@keycloak/keycloak-admin-client";
import { Label } from "@patternfly/react-core";
export type AliasRendererComponentProps = {
name?: string;
containerId?: string;
filterType?: string;
adminClient: KeycloakAdminClient;
id: string;
};
export const AliasRendererComponent = ({
name,
containerId,
filterType,
adminClient,
id,
}: AliasRendererComponentProps) => {
const [containerName, setContainerName] = useState<string>("");
useEffect(() => {
if (filterType === "clients") {
adminClient.clients
.findOne({ id: containerId! })
.then((client) => setContainerName(client.clientId! as string));
}
}, [containerId]);
if (filterType === "roles" || !containerName) {
return name;
}
if (filterType === "clients" || containerName) {
return (
<>
{containerId && (
<Label color="blue" key={`label-${id}`}>
{containerName}
</Label>
)}{" "}
{name}
</>
);
}
return null;
};

View file

@ -82,6 +82,10 @@ export const RealmRoleTabs = () => {
useFetch( useFetch(
() => adminClient.realms.findOne({ realm: realmName }), () => adminClient.realms.findOne({ realm: realmName }),
(realm) => { (realm) => {
if (!realm) {
throw new Error(t("common:notFound"));
}
setRealm(realm); setRealm(realm);
}, },
@ -92,6 +96,10 @@ export const RealmRoleTabs = () => {
const update = async () => { const update = async () => {
if (id) { if (id) {
const fetchedRole = await adminClient.roles.findOneById({ id }); const fetchedRole = await adminClient.roles.findOneById({ id });
if (!fetchedRole) {
throw new Error(t("common:notFound"));
}
const allAdditionalRoles = await adminClient.roles.getCompositeRoles({ const allAdditionalRoles = await adminClient.roles.getCompositeRoles({
id, id,
}); });
@ -172,6 +180,10 @@ export const RealmRoleTabs = () => {
roleName: role.name!, roleName: role.name!,
}); });
} }
if (!createdRole) {
throw new Error(t("common:notFound"));
}
setRole(convert(createdRole)); setRole(convert(createdRole));
history.push( history.push(
url.substr(0, url.lastIndexOf("/") + 1) + createdRole.id + "/details" url.substr(0, url.lastIndexOf("/") + 1) + createdRole.id + "/details"

View file

@ -22,6 +22,9 @@ export const UsersInRoleTab = () => {
const loader = async (first?: number, max?: number) => { const loader = async (first?: number, max?: number) => {
const role = await adminClient.roles.findOneById({ id: id }); const role = await adminClient.roles.findOneById({ id: id });
if (!role) {
throw new Error(t("common:notFound"));
}
if (role.clientRole) { if (role.clientRole) {
return adminClient.clients.findUsersWithRole({ return adminClient.clients.findUsersWithRole({

View file

@ -87,7 +87,7 @@ export const RealmSettingsEmailTab = ({
testConnection(); testConnection();
} else { } else {
const user = await adminClient.users.findOne({ id: whoAmI.getUserId() }); const user = await adminClient.users.findOne({ id: whoAmI.getUserId() });
if (!user.email) { if (user && !user.email) {
handleModalToggle(); handleModalToggle();
} else { } else {
await save(getValues()); await save(getValues());

View file

@ -96,6 +96,8 @@ export const UserFederationKerberosSettings = () => {
const fetchedComponent = await adminClient.components.findOne({ id }); const fetchedComponent = await adminClient.components.findOne({ id });
if (fetchedComponent) { if (fetchedComponent) {
setupForm(fetchedComponent); setupForm(fetchedComponent);
} else {
throw new Error(t("common:notFound"));
} }
} }
})(); })();

View file

@ -192,6 +192,8 @@ export const UserFederationLdapSettings = () => {
(fetchedComponent) => { (fetchedComponent) => {
if (fetchedComponent) { if (fetchedComponent) {
setupForm(fetchedComponent); setupForm(fetchedComponent);
} else if (id) {
throw new Error(t("common:notFound"));
} }
}, },
[] []
@ -228,17 +230,17 @@ export const UserFederationLdapSettings = () => {
}; };
const save = async (component: ldapComponentRepresentation) => { const save = async (component: ldapComponentRepresentation) => {
if (component?.config?.periodicChangedUsersSync !== null) { if (component.config?.periodicChangedUsersSync !== null) {
if (component?.config?.periodicChangedUsersSync === false) { if (component.config?.periodicChangedUsersSync === false) {
component.config.changedSyncPeriod = ["-1"]; component.config.changedSyncPeriod = ["-1"];
} }
delete component?.config?.periodicChangedUsersSync; delete component.config?.periodicChangedUsersSync;
} }
if (component?.config?.periodicFullSync !== null) { if (component.config?.periodicFullSync !== null) {
if (component?.config?.periodicFullSync === false) { if (component.config?.periodicFullSync === false) {
component.config.fullSyncPeriod = ["-1"]; component.config.fullSyncPeriod = ["-1"];
} }
delete component?.config?.periodicFullSync; delete component.config?.periodicFullSync;
} }
try { try {
if (!id) { if (!id) {

View file

@ -43,7 +43,7 @@ export const UserFederationSection = () => {
async () => { async () => {
const realmModel = await adminClient.realms.findOne({ realm }); const realmModel = await adminClient.realms.findOne({ realm });
const testParams: { [name: string]: string | number } = { const testParams: { [name: string]: string | number } = {
parentId: realmModel.id!, parentId: realmModel!.id!,
type: "org.keycloak.storage.UserStorageProvider", type: "org.keycloak.storage.UserStorageProvider",
}; };
return adminClient.components.find(testParams); return adminClient.components.find(testParams);

View file

@ -44,7 +44,7 @@ export const KerberosSettingsRequired = ({
useFetch( useFetch(
() => adminClient.realms.findOne({ realm }), () => adminClient.realms.findOne({ realm }),
(result) => form.setValue("parentId", result.id), (result) => form.setValue("parentId", result!.id),
[] []
); );

View file

@ -34,7 +34,7 @@ export const LdapSettingsGeneral = ({
useFetch( useFetch(
() => adminClient.realms.findOne({ realm }), () => adminClient.realms.findOne({ realm }),
(result) => form.setValue("parentId", result.id), (result) => form.setValue("parentId", result!.id),
[] []
); );
const [isVendorDropdownOpen, setIsVendorDropdownOpen] = useState(false); const [isVendorDropdownOpen, setIsVendorDropdownOpen] = useState(false);

View file

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react"; import React, { useState } from "react";
import { import {
ActionGroup, ActionGroup,
AlertVariant, AlertVariant,
@ -14,7 +14,7 @@ import {
} from "@patternfly/react-core"; } from "@patternfly/react-core";
import { convertFormValuesToObject, convertToFormValues } from "../../../util"; import { convertFormValuesToObject, convertToFormValues } from "../../../util";
import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation"; import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
import { useAdminClient } from "../../../context/auth/AdminClient"; import { useAdminClient, useFetch } from "../../../context/auth/AdminClient";
import { ViewHeader } from "../../../components/view-header/ViewHeader"; import { ViewHeader } from "../../../components/view-header/ViewHeader";
import { useHistory, useParams } from "react-router-dom"; import { useHistory, useParams } from "react-router-dom";
import { Controller, useForm, useWatch } from "react-hook-form"; import { Controller, useForm, useWatch } from "react-hook-form";
@ -49,21 +49,26 @@ export const LdapMapperDetails = () => {
const [isMapperDropdownOpen, setIsMapperDropdownOpen] = useState(false); const [isMapperDropdownOpen, setIsMapperDropdownOpen] = useState(false);
useEffect(() => { useFetch(
(async () => { async () => {
if (mapperId !== "new") { if (mapperId && mapperId !== "new") {
if (mapperId) { const fetchedMapper = await adminClient.components.findOne({
const fetchedMapper = await adminClient.components.findOne({ id: mapperId,
id: mapperId, });
}); if (!fetchedMapper) {
if (fetchedMapper) { throw new Error(t("common:notFound"));
setMapping(fetchedMapper);
setupForm(fetchedMapper);
}
} }
return fetchedMapper;
} }
})(); },
}, []); (fetchedMapper) => {
setMapping(fetchedMapper);
if (fetchedMapper) {
setupForm(fetchedMapper);
}
},
[]
);
const setupForm = (mapper: ComponentRepresentation) => { const setupForm = (mapper: ComponentRepresentation) => {
Object.entries(mapper).map((entry) => { Object.entries(mapper).map((entry) => {
@ -270,7 +275,7 @@ export const LdapMapperDetails = () => {
mapping.providerId! === "user-attribute-ldap-mapper") && ( mapping.providerId! === "user-attribute-ldap-mapper") && (
<LdapMapperUserAttribute <LdapMapperUserAttribute
form={form} form={form}
mapperType={mapping?.providerId} mapperType={mapping.providerId}
/> />
) )
: ""} : ""}

View file

@ -64,7 +64,7 @@ export const UserIdentityProviderLinks = () => {
}; };
const getAvailableIdPs = async () => { const getAvailableIdPs = async () => {
return (await adminClient.realms.findOne({ realm })).identityProviders; return (await adminClient.realms.findOne({ realm }))!.identityProviders;
}; };
const linkedIdPsLoader = async () => { const linkedIdPsLoader = async () => {

View file

@ -44,13 +44,18 @@ export const UsersTabs = () => {
async () => { async () => {
if (id) { if (id) {
const user = await adminClient.users.findOne({ id }); const user = await adminClient.users.findOne({ id });
const isBruteForceProtected = ( if (!user) {
await adminClient.realms.findOne({ realm }) throw new Error(t("common:notFound"));
).bruteForceProtected; }
const isBruteForceProtected = (await adminClient.realms.findOne({
realm,
}))!.bruteForceProtected;
const bruteForce = await adminClient.attackDetection.findOne({
id: user.id!,
});
const isLocked: boolean = const isLocked: boolean =
isBruteForceProtected && isBruteForceProtected && bruteForce && bruteForce.disabled;
(await adminClient.attackDetection.findOne({ id: user.id! }))
?.disabled;
return { user, bruteForced: { isBruteForceProtected, isLocked } }; return { user, bruteForced: { isBruteForceProtected, isLocked } };
} }
return { user: undefined }; return { user: undefined };