Skip to content

Commit 6acebea

Browse files
committed
frontend: components: redux: Add oidc autologin and config
1 parent 836eafc commit 6acebea

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

frontend/src/components/App/Layout.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@ import { styled } from '@mui/material/styles';
2424
import { Dispatch, UnknownAction } from '@reduxjs/toolkit';
2525
import { useQuery } from '@tanstack/react-query';
2626
import { useEffect } from 'react';
27+
import React from 'react';
2728
import { Trans, useTranslation } from 'react-i18next';
2829
import { useDispatch } from 'react-redux';
30+
import { useLocation } from 'react-router';
31+
import { getAppUrl } from '../../helpers/getAppUrl';
2932
import { getCluster } from '../../lib/cluster';
3033
import { getSelectedClusters } from '../../lib/cluster';
3134
import { useClustersConf } from '../../lib/k8s';
@@ -143,7 +146,11 @@ const fetchConfig = (dispatch: Dispatch<UnknownAction>) => {
143146
clustersToConfig[cluster.name] = cluster;
144147
});
145148

146-
const configToStore = { ...config, clusters: clustersToConfig };
149+
const configToStore = {
150+
...config,
151+
clusters: clustersToConfig,
152+
oidcAutoLogin: config.oidcAutoLogin,
153+
};
147154

148155
if (clusters === null) {
149156
dispatch(setConfig(configToStore));
@@ -188,6 +195,7 @@ export default function Layout({}: LayoutProps) {
188195
const isFullWidth = useTypedSelector(state => state.ui.isFullWidth);
189196
const { t } = useTranslation();
190197
const allClusters = useClustersConf();
198+
const location = useLocation();
191199

192200
/** This fetches the cluster config from the backend and updates the redux store on an interval.
193201
* When stateless clusters are enabled, it also fetches the stateless cluster config from the
@@ -224,6 +232,30 @@ export default function Layout({}: LayoutProps) {
224232

225233
const panels = useUIPanelsGroupedBySide();
226234

235+
const oauthUrl = `${getAppUrl()}oidc?dt=${Date()}&cluster=${getCluster()}`;
236+
const oidcAutoLogin = useTypedSelector(state => state.config.oidcAutoLogin);
237+
238+
React.useEffect(() => {
239+
if (oidcAutoLogin === undefined || !clusters) {
240+
return;
241+
}
242+
243+
const urlParams = new URLSearchParams(window.location.search);
244+
const isLoggingOut = urlParams.get('logout') === 'true';
245+
const isCallbackPath = window.location.pathname.includes('oidc-callback');
246+
247+
const currentClusterName = getCluster();
248+
const currentCluster = currentClusterName ? clusters[currentClusterName] : null;
249+
const isOIDC = currentCluster?.auth_type === 'oidc';
250+
251+
if (oidcAutoLogin && isOIDC && !isLoggingOut && !error && !isCallbackPath) {
252+
const hasToken = !!currentCluster?.useToken;
253+
if (!hasToken) {
254+
window.location.href = oauthUrl;
255+
}
256+
}
257+
}, [oidcAutoLogin, clusters, error, oauthUrl, location]);
258+
227259
if (!disableBackendLoader) {
228260
if (error && !config) {
229261
return <ErrorPage message={<Trans>Failed to connect to the backend</Trans>} error={error} />;

frontend/src/redux/configSlice.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export interface ConfigState {
5757
useEvict: boolean;
5858
[key: string]: any;
5959
};
60+
oidcAutoLogin?: boolean | null;
6061
}
6162

6263
export const defaultTableRowsPerPageOptions = [15, 25, 50];
@@ -71,6 +72,7 @@ export const initialState: ConfigState = {
7172
clusters: null,
7273
statelessClusters: null,
7374
allClusters: null,
75+
oidcAutoLogin: false,
7476
settings: {
7577
tableRowsPerPageOptions:
7678
storedSettings.tableRowsPerPageOptions || defaultTableRowsPerPageOptions,
@@ -89,8 +91,15 @@ const configSlice = createSlice({
8991
* @param state - The current state.
9092
* @param action - The payload action containing the config.
9193
*/
92-
setConfig(state, action: PayloadAction<{ clusters: ConfigState['clusters'] }>) {
94+
setConfig(
95+
state,
96+
action: PayloadAction<{ clusters: ConfigState['clusters']; oidcAutoLogin?: boolean }>
97+
) {
9398
state.clusters = action.payload.clusters;
99+
100+
if (state.oidcAutoLogin === undefined) {
101+
state.oidcAutoLogin = action.payload.oidcAutoLogin;
102+
}
94103
},
95104
/**
96105
* Save the config. To both the store, and localStorage.

0 commit comments

Comments
 (0)