Fix realm intialization (#990)

This commit is contained in:
Jon Koops 2021-08-11 13:23:59 +02:00 committed by GitHub
parent 15a87b7d2e
commit a6d38096b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 92 deletions

View file

@ -1,11 +1,6 @@
import React, { FunctionComponent, useEffect } from "react"; import React, { FunctionComponent } from "react";
import { Page } from "@patternfly/react-core"; import { Page } from "@patternfly/react-core";
import { import { HashRouter as Router, Route, Switch } from "react-router-dom";
HashRouter as Router,
Route,
Switch,
useParams,
} from "react-router-dom";
import { ErrorBoundary } from "react-error-boundary"; import { ErrorBoundary } from "react-error-boundary";
import { Header } from "./PageHeader"; import { Header } from "./PageHeader";
@ -20,34 +15,41 @@ import { routes, RouteDef } from "./route-config";
import { PageBreadCrumbs } from "./components/bread-crumb/PageBreadCrumbs"; import { PageBreadCrumbs } from "./components/bread-crumb/PageBreadCrumbs";
import { ForbiddenSection } from "./ForbiddenSection"; import { ForbiddenSection } from "./ForbiddenSection";
import { SubGroups } from "./groups/SubGroupsContext"; import { SubGroups } from "./groups/SubGroupsContext";
import { useRealm } from "./context/realm-context/RealmContext"; import { RealmContextProvider } from "./context/realm-context/RealmContext";
import { ErrorRenderer } from "./components/error/ErrorRenderer"; import { ErrorRenderer } from "./components/error/ErrorRenderer";
import { AdminClient } from "./context/auth/AdminClient";
import { WhoAmIContextProvider } from "./context/whoami/WhoAmI";
import type KeycloakAdminClient from "keycloak-admin";
export const mainPageContentId = "kc-main-content-page-container"; export const mainPageContentId = "kc-main-content-page-container";
const AppContexts: FunctionComponent = ({ children }) => ( export type AdminClientProps = {
<AccessContextProvider> adminClient: KeycloakAdminClient;
<Help>
<AlertProvider>
<ServerInfoProvider>
<SubGroups>{children}</SubGroups>
</ServerInfoProvider>
</AlertProvider>
</Help>
</AccessContextProvider>
);
// set the realm form the path
const RealmPathSelector: FunctionComponent = ({ children }) => {
const { setRealm } = useRealm();
const { realm } = useParams<{ realm: string }>();
useEffect(() => {
if (realm) setRealm(realm);
}, []);
return <>{children}</>;
}; };
const AppContexts: FunctionComponent<AdminClientProps> = ({
children,
adminClient,
}) => (
<Router>
<AdminClient.Provider value={adminClient}>
<WhoAmIContextProvider>
<RealmContextProvider>
<AccessContextProvider>
<Help>
<AlertProvider>
<ServerInfoProvider>
<SubGroups>{children}</SubGroups>
</ServerInfoProvider>
</AlertProvider>
</Help>
</AccessContextProvider>
</RealmContextProvider>
</WhoAmIContextProvider>
</AdminClient.Provider>
</Router>
);
// If someone tries to go directly to a route they don't // If someone tries to go directly to a route they don't
// have access to, show forbidden page. // have access to, show forbidden page.
type SecuredRouteProps = { route: RouteDef }; type SecuredRouteProps = { route: RouteDef };
@ -63,38 +65,32 @@ const SecuredRoute = ({ route }: SecuredRouteProps) => {
return <ForbiddenSection />; return <ForbiddenSection />;
}; };
export const App = () => { export const App = ({ adminClient }: AdminClientProps) => {
return ( return (
<AppContexts> <AppContexts adminClient={adminClient}>
<Router> <Page
<Page header={<Header />}
header={<Header />} isManagedSidebar
isManagedSidebar sidebar={<PageNav />}
sidebar={<PageNav />} breadcrumb={<PageBreadCrumbs />}
breadcrumb={<PageBreadCrumbs />} mainContainerId={mainPageContentId}
mainContainerId={mainPageContentId} >
<ErrorBoundary
FallbackComponent={ErrorRenderer}
onReset={() => window.location.reload()}
> >
<ErrorBoundary <Switch>
FallbackComponent={ErrorRenderer} {routes.map((route, i) => (
onReset={() => window.location.reload()} <Route
> exact={route.matchOptions?.exact ?? true}
<Switch> key={i}
{routes.map((route, i) => ( path={route.path}
<Route component={() => <SecuredRoute route={route} />}
exact={route.matchOptions?.exact ?? true} />
key={i} ))}
path={route.path} </Switch>
component={() => ( </ErrorBoundary>
<RealmPathSelector> </Page>
<SecuredRoute route={route} />
</RealmPathSelector>
)}
/>
))}
</Switch>
</ErrorBoundary>
</Page>
</Router>
</AppContexts> </AppContexts>
); );
}; };

View file

@ -1,25 +0,0 @@
import React from "react";
import type KeycloakAdminClient from "keycloak-admin";
import { AdminClient } from "./context/auth/AdminClient";
import { WhoAmIContextProvider } from "./context/whoami/WhoAmI";
import { RealmContextProvider } from "./context/realm-context/RealmContext";
import { App } from "./App";
export type KeycloakAdminConsoleProps = {
adminClient: KeycloakAdminClient;
};
export const KeycloakAdminConsole = ({
adminClient,
}: KeycloakAdminConsoleProps) => {
return (
<AdminClient.Provider value={adminClient}>
<WhoAmIContextProvider>
<RealmContextProvider>
<App />
</RealmContextProvider>
</WhoAmIContextProvider>
</AdminClient.Provider>
);
};

View file

@ -1,7 +1,12 @@
import type RealmRepresentation from "keycloak-admin/lib/defs/realmRepresentation"; import type RealmRepresentation from "keycloak-admin/lib/defs/realmRepresentation";
import _ from "lodash"; import _ from "lodash";
import React, { FunctionComponent, useState } from "react"; import React, { FunctionComponent, useEffect, useState } from "react";
import { useRouteMatch } from "react-router-dom";
import { RecentUsed } from "../../components/realm-selector/recent-used"; import { RecentUsed } from "../../components/realm-selector/recent-used";
import {
DashboardParams,
DashboardRoute,
} from "../../dashboard/routes/Dashboard";
import environment from "../../environment"; import environment from "../../environment";
import useRequiredContext from "../../utils/useRequiredContext"; import useRequiredContext from "../../utils/useRequiredContext";
import { useAdminClient, useFetch } from "../auth/AdminClient"; import { useAdminClient, useFetch } from "../auth/AdminClient";
@ -18,7 +23,10 @@ export const RealmContext = React.createContext<RealmContextType | undefined>(
); );
export const RealmContextProvider: FunctionComponent = ({ children }) => { export const RealmContextProvider: FunctionComponent = ({ children }) => {
const [realm, setRealm] = useState(environment.loginRealm); const routeMatch = useRouteMatch<DashboardParams>(DashboardRoute.path);
const [realm, setRealm] = useState(
routeMatch?.params.realm ?? environment.loginRealm
);
const [realms, setRealms] = useState<RealmRepresentation[]>([]); const [realms, setRealms] = useState<RealmRepresentation[]>([]);
const adminClient = useAdminClient(); const adminClient = useAdminClient();
const recentUsed = new RecentUsed(); const recentUsed = new RecentUsed();
@ -34,6 +42,8 @@ export const RealmContextProvider: FunctionComponent = ({ children }) => {
[] []
); );
useEffect(() => adminClient.setConfig({ realmName: realm }), [realm]);
const set = (realm: string) => { const set = (realm: string) => {
if ( if (
realms.length === 0 || realms.length === 0 ||
@ -41,9 +51,6 @@ export const RealmContextProvider: FunctionComponent = ({ children }) => {
) { ) {
recentUsed.setRecentUsed(realm); recentUsed.setRecentUsed(realm);
setRealm(realm); setRealm(realm);
adminClient.setConfig({
realmName: realm,
});
} }
}; };
return ( return (

View file

@ -1,17 +1,17 @@
import "./index.css"; import "./index.css";
import React, { StrictMode } from "react"; import React, { StrictMode } from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import i18n from "./i18n";
import { App } from "./App";
import i18n from "./i18n";
import init from "./context/auth/keycloak"; import init from "./context/auth/keycloak";
import { KeycloakAdminConsole } from "./KeycloakAdminConsole";
console.info("supported languages", ...i18n.languages); console.info("supported languages", ...i18n.languages);
init().then((adminClient) => { init().then((adminClient) => {
ReactDOM.render( ReactDOM.render(
<StrictMode> <StrictMode>
<KeycloakAdminConsole adminClient={adminClient} /> <App adminClient={adminClient} />
</StrictMode>, </StrictMode>,
document.getElementById("app") document.getElementById("app")
); );