Skip to content

Feature/auth backend integration #389

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/src/components/AuthProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function AuthProvider({children}: AuthProviderProps) {
import.meta.env.VITE_OAUTH_REDIRECT_URL === undefined
? window.location.origin
: `${import.meta.env.VITE_OAUTH_REDIRECT_URL}`,
scope: 'openid profile email', // default scope without audience
scope: 'openid profile email loki-back-audience roles', // default scope without audience
autoLogin: false,
};
}
Expand Down
16 changes: 14 additions & 2 deletions frontend/src/components/TopBar/ApplicationMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import MenuItem from '@mui/material/MenuItem';
import Box from '@mui/system/Box';
import {useAppSelector} from 'store/hooks';
import {AuthContext, IAuthContext} from 'react-oauth2-code-pkce';
import ToyCreateProtectedScenarioMenuItem from './ToyCreateProtectedScenarioMenuItem';

const ChangelogDialog = React.lazy(() => import('./PopUps/ChangelogDialog'));
const ImprintDialog = React.lazy(() => import('./PopUps/ImprintDialog'));
Expand All @@ -27,7 +28,7 @@ export default function ApplicationMenu(): JSX.Element {
const {t} = useTranslation();

const realm = useAppSelector((state) => state.realm.name);
const {login, token, logOut} = useContext<IAuthContext>(AuthContext);
const {login, token, logOut, idToken} = useContext<IAuthContext>(AuthContext);

// user cannot login when realm is not selected
const loginDisabled = realm === '';
Expand Down Expand Up @@ -61,6 +62,7 @@ export default function ApplicationMenu(): JSX.Element {
const logoutClicked = () => {
closeMenu();
logOut();
keycloakLogout();
};

/** This method gets called, when the imprint menu entry was clicked. It opens a dialog showing the legal text. */
Expand Down Expand Up @@ -93,6 +95,13 @@ export default function ApplicationMenu(): JSX.Element {
setChangelogOpen(true);
};

/** Redirect user to logout from the IdP (Keycloak) */
const keycloakLogout = () => {
window.location.assign(
`${import.meta.env.VITE_OAUTH_API_URL}/realms/${realm}/protocol/openid-connect/logout?post_logout_redirect_uri=${encodeURI(`${import.meta.env.VITE_OAUTH_REDIRECT_URL}`)}&id_token_hint=${idToken}`
);
};

return (
<Box sx={{display: 'flex', alignItems: 'center', justifyContent: 'flex-end'}}>
<Button
Expand All @@ -106,7 +115,10 @@ export default function ApplicationMenu(): JSX.Element {
</Button>
<Menu id='application-menu' anchorEl={anchorElement} open={Boolean(anchorElement)} onClose={closeMenu}>
{isAuthenticated ? (
<MenuItem onClick={logoutClicked}>{t('topBar.menu.logout')}</MenuItem>
<Box>
<MenuItem onClick={logoutClicked}>{t('topBar.menu.logout')}</MenuItem>
<ToyCreateProtectedScenarioMenuItem />
</Box>
) : (
<MenuItem onClick={loginClicked} disabled={loginDisabled}>
{t('topBar.menu.login')}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: 2024 German Aerospace Center (DLR) and CISPA Helmholtz Center for Information Security
// SPDX-License-Identifier: Apache-2.0

import MenuItem from '@mui/material/MenuItem';
import React from 'react';
import {useContext} from 'react';
import {AuthContext, IAuthContext} from 'react-oauth2-code-pkce';
import {useCreateProtectedScenarioMutation} from 'store/services/scenarioApi';

export default function ToyCreateProtectedScenarioMenuItem() {
const {token} = useContext<IAuthContext>(AuthContext);

const [createProtectedScenario] = useCreateProtectedScenarioMutation();

const createProtectedScenarioClicked = () => {
createProtectedScenario(token)
.unwrap()
.then((res) => alert(JSON.stringify(res)))
.catch((err) => alert(JSON.stringify(err)));
};

return <MenuItem onClick={createProtectedScenarioClicked}>Create Protected Scenario</MenuItem>;
}
25 changes: 24 additions & 1 deletion frontend/src/store/services/scenarioApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
/* [CDtemp-begin] */
import cologneData from '../../../assets/stadtteile_cologne_list.json';
import {District} from 'types/cologneDistricts';
import {RootState} from 'store';

/** Checks if input node is a city district and returns the node to fetch data, and the city distrct suffix if there is one */
function validateDistrictNode(inNode: string): {node: string; cologneDistrict?: string} {
Expand Down Expand Up @@ -48,8 +49,29 @@ function modifyDistrictResults(cologneDistrict: string | undefined, data: Simula
export const scenarioApi = createApi({
reducerPath: 'scenarioApi',
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
baseQuery: fetchBaseQuery({baseUrl: `${import.meta.env.VITE_API_URL || ''}/api/v1/`}),
baseQuery: fetchBaseQuery({
baseUrl: `${import.meta.env.VITE_API_URL || ''}/`,
prepareHeaders: (headers, {getState}) => {
const realm = (getState() as RootState).realm.name;

if (realm !== '') {
// include realm in req header
headers.set('x-realm', realm);
}

return headers;
},
}),
endpoints: (builder) => ({
createProtectedScenario: builder.mutation<string, string>({
query: (token) => ({
url: 'scenarios/protected/',
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
},
}),
}),
getSimulationModels: builder.query<SimulationModels, void>({
query: () => {
return 'simulationmodels/';
Expand Down Expand Up @@ -397,4 +419,5 @@ export const {
useGetMultipleSimulationDataByNodeQuery,
useGetPercentileDataQuery,
useGetScenarioParametersQuery,
useCreateProtectedScenarioMutation,
} = scenarioApi;
Loading