From d2244cf10e72ac1f1d37f70e3ad71d28b7584aa4 Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Wed, 27 Sep 2023 18:19:49 +0200 Subject: [PATCH] WIP --- .../Elasticsearch/AssetDataTemplateSearch.php | 11 ++++-- databox/api/src/Security/Voter/AssetVoter.php | 5 --- .../src/Security/Voter/CollectionVoter.php | 3 -- .../client/src/components/Routing/router.tsx | 19 +++------ expose/client/config-compiler.js | 2 +- expose/client/src/component/App.js | 8 ++-- expose/client/src/component/ConfigWrapper.js | 3 +- expose/client/src/component/Layout.js | 4 +- expose/client/src/component/Logo.js | 6 +-- expose/client/src/component/Publication.js | 2 +- .../layouts/gallery/GalleryLayout.js | 2 +- .../component/layouts/mapbox/MapboxLayout.js | 2 +- .../shared-components/PublicationHeader.js | 4 +- .../security/AuthenticationMethod.tsx | 2 +- .../security/PublicationSecurityProxy.tsx | 1 - .../src/component/themes/ThemeEditorProxy.js | 2 +- expose/client/src/lib/config.ts | 39 +++++++------------ 17 files changed, 46 insertions(+), 69 deletions(-) diff --git a/databox/api/src/Elasticsearch/AssetDataTemplateSearch.php b/databox/api/src/Elasticsearch/AssetDataTemplateSearch.php index f262d1e48..03792d5b0 100644 --- a/databox/api/src/Elasticsearch/AssetDataTemplateSearch.php +++ b/databox/api/src/Elasticsearch/AssetDataTemplateSearch.php @@ -115,14 +115,19 @@ protected function createACLBoolQuery(array $filters, ?string $userId, array $gr throw new BadRequestHttpException('Collection is not in the same workspace'); } - if (!$this->security->isGranted(AbstractVoter::READ, $workspace)) { - throw new AccessDeniedHttpException('Cannot read workspace'); + $aclBoolQuery = new Query\BoolQuery(); + + if (null !== $collection) { + if (!$this->security->isGranted(AbstractVoter::EDIT, $collection)) { + $aclBoolQuery->addMust(new Query\Term(['collectionId' => 'NONE'])); + } + } elseif (!$this->security->isGranted(AbstractVoter::READ, $workspace)) { + $aclBoolQuery->addMust(new Query\Term(['workspaceId' => 'NONE'])); } $rootQuery = new Query\BoolQuery(); $rootQuery->addMust(new Query\Term(['workspaceId' => $workspace->getId()])); - $aclBoolQuery = new Query\BoolQuery(); $rootQuery->addMust($aclBoolQuery); $shoulds = []; diff --git a/databox/api/src/Security/Voter/AssetVoter.php b/databox/api/src/Security/Voter/AssetVoter.php index 23bb9d2b8..ec9f39197 100644 --- a/databox/api/src/Security/Voter/AssetVoter.php +++ b/databox/api/src/Security/Voter/AssetVoter.php @@ -36,11 +36,6 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $ $userId = $user instanceof JwtUser ? $user->getId() : false; $isOwner = fn (): bool => $userId && $subject->getOwnerId() === $userId; - $workspace = $subject->getWorkspace(); - if (!$this->security->isGranted(AbstractVoter::READ, $workspace)) { - return false; - } - switch ($attribute) { case self::CREATE: if (null !== $collection = $subject->getReferenceCollection()) { diff --git a/databox/api/src/Security/Voter/CollectionVoter.php b/databox/api/src/Security/Voter/CollectionVoter.php index b35d52f4e..0faba9ffd 100644 --- a/databox/api/src/Security/Voter/CollectionVoter.php +++ b/databox/api/src/Security/Voter/CollectionVoter.php @@ -41,9 +41,6 @@ private function doVote(string $attribute, Collection $subject, TokenInterface $ $isOwner = fn (): bool => $userId && $subject->getOwnerId() === $userId; $workspace = $subject->getWorkspace(); - if (!$this->security->isGranted(AbstractVoter::READ, $workspace)) { - return false; - } return match ($attribute) { self::CREATE => $subject->getParent() ? $this->security->isGranted(AbstractVoter::EDIT, $subject->getParent()) diff --git a/databox/client/src/components/Routing/router.tsx b/databox/client/src/components/Routing/router.tsx index 68bedb635..6709d3a39 100644 --- a/databox/client/src/components/Routing/router.tsx +++ b/databox/client/src/components/Routing/router.tsx @@ -1,7 +1,8 @@ import React, {Component, FunctionComponent, useContext} from 'react'; -import {Navigate, Route} from 'react-router-dom'; -import {getPath, RouteDefinition} from "../../routes"; +import {Route} from 'react-router-dom'; +import {RouteDefinition} from "../../routes"; import {UserContext} from "../Security/UserContext"; +import {useKeycloakUrls} from "../../lib/keycloak"; type WrapperProps = { component: FunctionComponent @@ -12,16 +13,12 @@ function RouteProxy({ public: isPublic, }: WrapperProps) { const {user} = useContext(UserContext); + const {getLoginUrl} = useKeycloakUrls(); if (!isPublic && !user) { - const currentPath = getCurrentPath(); + document.location.href = getLoginUrl(); - return + return <> } return @@ -67,7 +64,3 @@ export default function createRoute( />} /> }; - -function getCurrentPath(): string { - return window.location.href.replace(window.location.origin, ''); -} diff --git a/expose/client/config-compiler.js b/expose/client/config-compiler.js index 3df6c59dd..3883ea8d1 100644 --- a/expose/client/config-compiler.js +++ b/expose/client/config-compiler.js @@ -55,7 +55,7 @@ keycloakUrl: env.KEYCLOAK_URL, realmName: env.KEYCLOAK_REALM_NAME, clientId: env.CLIENT_ID, - requestSignatureTtl: env.S3_REQUEST_SIGNATURE_TTL, + requestSignatureTtl: env.S3_REQUEST_SIGNATURE_TTL ? parseInt(env.S3_REQUEST_SIGNATURE_TTL) : 86400, disableIndexPage: ['true', '1', 'on'].includes(env.DISABLE_INDEX_PAGE), }; }); diff --git a/expose/client/src/component/App.js b/expose/client/src/component/App.js index 83764ca41..92b71327e 100644 --- a/expose/client/src/component/App.js +++ b/expose/client/src/component/App.js @@ -41,18 +41,18 @@ class App extends PureComponent { } render() { - const css = config.get('globalCSS'); + const css = config.globalCSS; return {css && } - {config.get('displayServicesMenu') && } - {!config.get('disableIndexPage') && } + {!config.disableIndexPage && } }/> diff --git a/expose/client/src/component/ConfigWrapper.js b/expose/client/src/component/ConfigWrapper.js index c18ca3e5e..4bb2dd271 100644 --- a/expose/client/src/component/ConfigWrapper.js +++ b/expose/client/src/component/ConfigWrapper.js @@ -12,7 +12,8 @@ export default function ConfigWrapper() { .get(`/config`) .then((res) => { Object.keys(res).forEach(k => { - config.set(k, res[k]); + // @ts-ignore bypass readonly + config[k] = res[k]; }); setLoaded(true); diff --git a/expose/client/src/component/Layout.js b/expose/client/src/component/Layout.js index dc692b146..b4a787c1b 100644 --- a/expose/client/src/component/Layout.js +++ b/expose/client/src/component/Layout.js @@ -16,7 +16,7 @@ class Layout extends PureComponent { super(props); this.state = { - displayMenu: config.get('sidebarDefaultOpen'), + displayMenu: config.sidebarDefaultOpen, } } @@ -42,7 +42,7 @@ class Layout extends PureComponent { {this.renderAuthenticated()}

- {!config.get('disableIndexPage') ? + {!config.disableIndexPage ? : }

diff --git a/expose/client/src/component/Logo.js b/expose/client/src/component/Logo.js index 63518dce5..660816097 100644 --- a/expose/client/src/component/Logo.js +++ b/expose/client/src/component/Logo.js @@ -2,12 +2,12 @@ import React from 'react'; import config from '../lib/config'; export function Logo() { - const title = config.get('clientLogoAlt') || 'Expose.'; + const title = config.clientLogoAlt || 'Expose.'; - if (config.get('clientLogoUrl')) { + if (config.clientLogoUrl) { return
{title}
diff --git a/expose/client/src/component/Publication.js b/expose/client/src/component/Publication.js index e2060d3ca..8b84b8660 100644 --- a/expose/client/src/component/Publication.js +++ b/expose/client/src/component/Publication.js @@ -84,7 +84,7 @@ class Publication extends PureComponent { this.timeout && clearTimeout(this.timeout); - const ttl = config.get('requestSignatureTtl'); + const ttl = config.requestSignatureTtl; if (!ttl) { throw new Error(`Missing requestSignatureTtl`); diff --git a/expose/client/src/component/layouts/gallery/GalleryLayout.js b/expose/client/src/component/layouts/gallery/GalleryLayout.js index c775c8c6e..d152ffaab 100644 --- a/expose/client/src/component/layouts/gallery/GalleryLayout.js +++ b/expose/client/src/component/layouts/gallery/GalleryLayout.js @@ -154,7 +154,7 @@ class GalleryLayout extends React.Component { }; render() { - const {assetId, data, options} = this.props; + const {data, options} = this.props; const {currentIndex} = this.state; const { assets, diff --git a/expose/client/src/component/layouts/mapbox/MapboxLayout.js b/expose/client/src/component/layouts/mapbox/MapboxLayout.js index e3ff8ad84..9520210ec 100644 --- a/expose/client/src/component/layouts/mapbox/MapboxLayout.js +++ b/expose/client/src/component/layouts/mapbox/MapboxLayout.js @@ -12,7 +12,7 @@ import {logAssetView} from "../../../lib/log"; import {getThumbPlaceholder} from "../shared-components/placeholders"; export function initMapbox(mapContainer, {lng, lat, zoom}) { - mapboxgl.accessToken = config.get('mapBoxToken'); + mapboxgl.accessToken = config.mapBoxToken; let map = new mapboxgl.Map({ container: mapContainer, diff --git a/expose/client/src/component/layouts/shared-components/PublicationHeader.js b/expose/client/src/component/layouts/shared-components/PublicationHeader.js index 8de952727..2f22e49a4 100644 --- a/expose/client/src/component/layouts/shared-components/PublicationHeader.js +++ b/expose/client/src/component/layouts/shared-components/PublicationHeader.js @@ -23,7 +23,7 @@ export default class PublicationHeader extends PureComponent {
}

{title}

{date ? : ''} - {assets.length > 0 && config.get('zippyEnabled') &&
0 && config.zippyEnabled &&
} - {data.downloadEnabled && config.get('zippyEnabled') && assets.length > 0 &&
+ {data.downloadEnabled && config.zippyEnabled && assets.length > 0 &&
}
diff --git a/expose/client/src/component/security/AuthenticationMethod.tsx b/expose/client/src/component/security/AuthenticationMethod.tsx index e59d67daf..fee9b0a68 100644 --- a/expose/client/src/component/security/AuthenticationMethod.tsx +++ b/expose/client/src/component/security/AuthenticationMethod.tsx @@ -7,7 +7,7 @@ import {oauthClient} from "../../lib/api-client"; type Props = {}; function createLoginUrl(): string { - const autoConnectIdP = config.get('autoConnectIdP'); + const autoConnectIdP = config.autoConnectIdP; setAuthRedirect(document.location.pathname); diff --git a/expose/client/src/component/security/PublicationSecurityProxy.tsx b/expose/client/src/component/security/PublicationSecurityProxy.tsx index 270a812f1..fe54809ca 100644 --- a/expose/client/src/component/security/PublicationSecurityProxy.tsx +++ b/expose/client/src/component/security/PublicationSecurityProxy.tsx @@ -3,7 +3,6 @@ import {Publication} from "../../types"; import {securityMethods} from "./methods"; import FullPageLoader from "../FullPageLoader"; import {logPublicationView} from "../../lib/log"; -import config from "../../lib/config"; import {oauthClient} from "../../lib/api-client"; type Props = PropsWithChildren<{ diff --git a/expose/client/src/component/themes/ThemeEditorProxy.js b/expose/client/src/component/themes/ThemeEditorProxy.js index d40f8e3ef..402c8dc53 100644 --- a/expose/client/src/component/themes/ThemeEditorProxy.js +++ b/expose/client/src/component/themes/ThemeEditorProxy.js @@ -10,7 +10,7 @@ class ThemeEditorProxy extends Component { }; state = { - hidden: !config.get('devMode'), + hidden: !config.devMode, }; static getDerivedStateFromProps(props, state) { diff --git a/expose/client/src/lib/config.ts b/expose/client/src/lib/config.ts index fbf72f98a..9c359c9eb 100644 --- a/expose/client/src/lib/config.ts +++ b/expose/client/src/lib/config.ts @@ -1,34 +1,21 @@ declare global { interface Window { - config: Record; + config: { + locales: string[]; + autoConnectIdP: string | undefined | null; + baseUrl: string; + keycloakUrl: string; + realmName: string; + clientId: string; + requestSignatureTtl: string; + disableIndexPage: string; + dashboardBaseUrl: string; + globalCSS: string | undefined; + }; } } -const configData = window.config; - -class Config { - get(key: string): any { - return configData[key]; - } - - set(key: string, value: any): void { - configData[key] = value; - } - - getApiBaseUrl(): string { - return configData.baseUrl; - } - - getAuthBaseUrl(): string { - return configData.authBaseUrl; - } - - getClientId(): string { - return this.get('clientId'); - } -} - -const config = new Config(); +const config = window.config; export default config;