Skip to content

Commit 8e87ad4

Browse files
committed
frontend: components: redux: Add oidc autologin and config
1 parent a572b5f commit 8e87ad4

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

frontend/src/components/App/Layout.tsx

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import { useQuery } from '@tanstack/react-query';
2626
import { useEffect } from 'react';
2727
import { Trans, useTranslation } from 'react-i18next';
2828
import { useDispatch } from 'react-redux';
29+
import { useLocation } from 'react-router';
30+
import { getAppUrl } from '../../helpers/getAppUrl';
2931
import { getCluster } from '../../lib/cluster';
3032
import { getSelectedClusters } from '../../lib/cluster';
3133
import { useCluster, useClustersConf } from '../../lib/k8s';
@@ -146,7 +148,11 @@ const fetchConfig = (dispatch: Dispatch<UnknownAction>) => {
146148
clustersToConfig[cluster.name] = cluster;
147149
});
148150

149-
const configToStore = { ...config, clusters: clustersToConfig };
151+
const configToStore = {
152+
...config,
153+
clusters: clustersToConfig,
154+
oidcAutoLogin: config.oidcAutoLogin,
155+
};
150156

151157
if (clusters === null) {
152158
dispatch(setConfig(configToStore));
@@ -191,6 +197,7 @@ export default function Layout({}: LayoutProps) {
191197
const isFullWidth = useTypedSelector(state => state.ui.isFullWidth);
192198
const { t } = useTranslation();
193199
const allClusters = useClustersConf();
200+
const location = useLocation();
194201

195202
/** This fetches the cluster config from the backend and updates the redux store on an interval.
196203
* When stateless clusters are enabled, it also fetches the stateless cluster config from the
@@ -235,6 +242,36 @@ export default function Layout({}: LayoutProps) {
235242

236243
const panels = useUIPanelsGroupedBySide();
237244

245+
const oidcAutoLogin = useTypedSelector(state => state.config.oidcAutoLogin);
246+
247+
useEffect(() => {
248+
if (!oidcAutoLogin || !clusters) {
249+
return;
250+
}
251+
const urlParams = new URLSearchParams(window.location.search);
252+
const isLoggingOut = urlParams.get('logout') === 'true';
253+
if (isLoggingOut || !!error) {
254+
return;
255+
}
256+
const isCallbackPath =
257+
window.location.pathname.includes('oidc-callback') ||
258+
urlParams.has('code') ||
259+
urlParams.has('state');
260+
if (isCallbackPath) {
261+
return;
262+
}
263+
const currentClusterName = getCluster();
264+
const currentCluster = currentClusterName ? clusters[currentClusterName] : null;
265+
const isOIDC = currentCluster?.auth_type === 'oidc';
266+
if (!isOIDC) {
267+
return;
268+
}
269+
if (currentCluster.useToken === undefined) {
270+
const oauthUrl = `${getAppUrl()}oidc?dt=${Date.now()}&cluster=${getCluster()}`;
271+
window.location.href = oauthUrl;
272+
}
273+
}, [oidcAutoLogin, clusters, error, location.pathname]);
274+
238275
if (!disableBackendLoader) {
239276
if (error && !config) {
240277
return <ErrorPage message={<Trans>Failed to connect to the backend</Trans>} error={error} />;

frontend/src/redux/configSlice.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ export interface ConfigState {
5757
useEvict: boolean;
5858
[key: string]: any;
5959
};
60+
/**
61+
* Whether OIDC auto-login is enabled. Null indicates the value hasn't been loaded from the backend yet.
62+
*/
63+
oidcAutoLogin?: boolean | null;
6064
}
6165

6266
export const defaultTableRowsPerPageOptions = [15, 25, 50];
@@ -71,6 +75,7 @@ export const initialState: ConfigState = {
7175
clusters: null,
7276
statelessClusters: null,
7377
allClusters: null,
78+
oidcAutoLogin: null,
7479
settings: {
7580
tableRowsPerPageOptions:
7681
storedSettings.tableRowsPerPageOptions || defaultTableRowsPerPageOptions,
@@ -89,8 +94,15 @@ const configSlice = createSlice({
8994
* @param state - The current state.
9095
* @param action - The payload action containing the config.
9196
*/
92-
setConfig(state, action: PayloadAction<{ clusters: ConfigState['clusters'] }>) {
97+
setConfig(
98+
state,
99+
action: PayloadAction<{ clusters: ConfigState['clusters']; oidcAutoLogin?: boolean }>
100+
) {
93101
state.clusters = action.payload.clusters;
102+
103+
if (state.oidcAutoLogin !== undefined) {
104+
state.oidcAutoLogin = action.payload.oidcAutoLogin;
105+
}
94106
},
95107
/**
96108
* Save the config. To both the store, and localStorage.

0 commit comments

Comments
 (0)