Skip to content

Commit

Permalink
Fix geosolutions-it#10506 Adding possibility to fetch legends images …
Browse files Browse the repository at this point in the history
…using Bearer token (geosolutions-it#10507)
  • Loading branch information
MV88 authored Aug 19, 2024
1 parent b3c783e commit 7b1e9b4
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 35 deletions.
69 changes: 69 additions & 0 deletions web/client/components/misc/SecureImage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* Copyright 2024, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

import React, { useEffect, useState } from 'react';
import axios from 'axios';

import { getAuthenticationMethod } from '../../utils/SecurityUtils';


const SecureImage = ({
alt,
src,
...props
}) => {
const [imageSrc, setImageSrc] = useState('');

// Function to validate the image once it loads
const validateImg = (imgElement) => {
// Implement your validation logic here
// For example, check image dimensions, aspect ratio, etc.
if (imgElement.naturalWidth === 0 || imgElement.naturalHeight === 0) {
console.error('Image validation failed: Image is not valid.');
}
};

useEffect(() => {
const authMethod = getAuthenticationMethod(src);

if (authMethod === "bearer") {
axios.get(src, {
responseType: 'blob'
})
.then((response) => {
const imageUrl = URL.createObjectURL(response.data);
setImageSrc(imageUrl);
})
.catch((error) => {
console.error('Error fetching image:', error);
});
} else {
setImageSrc(src);
}

// Clean up the URL object when the component unmounts
return () => {
if (imageSrc) {
URL.revokeObjectURL(imageSrc);
}
};
}, [src]);

return (
<img
alt={alt}
onError={props.onImgError}
onLoad={(e) => validateImg(e.target)}
src={imageSrc}
style={props.style}
{...props}
/>
);
};

export default SecureImage;
50 changes: 31 additions & 19 deletions web/client/plugins/TOC/components/Legend.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import PropTypes from 'prop-types';
import React from 'react';

import {
addAuthenticationParameter,
addAuthenticationToSLD,
clearNilValuesForParams
} from '../../../utils/SecurityUtils';
import Message from '../../../components/I18N/Message';
import SecureImage from '../../../components/misc/SecureImage';

import { randomInt } from '../../../utils/RandomUtils';

/**
Expand Down Expand Up @@ -85,23 +86,26 @@ class Legend extends React.Component {

const cleanParams = clearNilValuesForParams(layer.params);
const scale = this.getScale(props);
let query = assign({}, {
service: "WMS",
request: "GetLegendGraphic",
format: "image/png",
height: props.legendHeight,
width: props.legendWidth,
layer: layer.name,
style: layer.style || null,
version: layer.version || "1.3.0",
SLD_VERSION: "1.1.0",
LEGEND_OPTIONS: props.legendOptions
}, layer.legendParams || {},
props.language && layer.localizedLayerStyles ? {LANGUAGE: props.language} : {},
addAuthenticationToSLD(cleanParams || {}, props.layer),
cleanParams && cleanParams.SLD_BODY ? {SLD_BODY: cleanParams.SLD_BODY} : {},
scale !== null ? { SCALE: scale } : {});
addAuthenticationParameter(url, query);
let query = assign(
{},
{
service: "WMS",
request: "GetLegendGraphic",
format: "image/png",
height: props.legendHeight,
width: props.legendWidth,
layer: layer.name,
style: layer.style || null,
version: layer.version || "1.3.0",
SLD_VERSION: "1.1.0",
LEGEND_OPTIONS: props.legendOptions
},
layer.legendParams || {},
props.language && layer.localizedLayerStyles ? {LANGUAGE: props.language} : {},
addAuthenticationToSLD(cleanParams || {}, props.layer),
cleanParams && cleanParams.SLD_BODY ? {SLD_BODY: cleanParams.SLD_BODY} : {},
scale !== null ? { SCALE: scale } : {}
);

return urlUtil.format({
host: urlObj.host,
Expand All @@ -114,7 +118,15 @@ class Legend extends React.Component {
}
render() {
if (!this.state.error && this.props.layer && this.props.layer.type === "wms" && this.props.layer.url) {
return <img onError={this.onImgError} onLoad={(e) => this.validateImg(e.target)} src={this.getUrl(this.props)} style={this.props.style}/>;
const url = this.getUrl(this.props);
return (
<SecureImage
onError={this.onImgError}
onLoad={(e) => this.validateImg(e.target)}
src={url}
style={this.props.style}
/>
);
}
return <Message msgId="layerProperties.legenderror" />;
}
Expand Down
35 changes: 19 additions & 16 deletions web/client/plugins/TOC/components/__tests__/Legend-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ import React from 'react';
import ReactDOM from 'react-dom';
import Rx from 'rxjs';
import url from 'url';
import * as TestUtils from 'react-dom/test-utils';

import Legend from '../Legend';

import * as TestUtils from 'react-dom/test-utils';

describe("test the Layer legend", () => {
beforeEach((done) => {
document.body.innerHTML = '<div id="container"></div>';
Expand Down Expand Up @@ -176,13 +175,15 @@ describe("test the Layer legend", () => {
"name": "layer3",
"format": "image/png"
};
ReactDOM.render(
<Legend
layer={layer}
currentZoomLvl={2.3456}
scales={[10000, 5000, 2000, 1000]}
/>,
document.getElementById("container"));
TestUtils.act(() => {
ReactDOM.render(
<Legend
layer={layer}
currentZoomLvl={2.3456}
scales={[10000, 5000, 2000, 1000]}
/>,
document.getElementById("container"));
});
const legendImage = document.querySelector("img");
expect(legendImage).toBeTruthy();
const { query } = url.parse(legendImage.getAttribute('src'), true);
Expand All @@ -197,13 +198,15 @@ describe("test the Layer legend", () => {
"name": "layer3",
"format": "image/png"
};
ReactDOM.render(
<Legend
layer={layer}
currentZoomLvl={10}
scales={[10000, 5000, 2000, 1000]}
/>,
document.getElementById("container"));
TestUtils.act(() => {
ReactDOM.render(
<Legend
layer={layer}
currentZoomLvl={10}
scales={[10000, 5000, 2000, 1000]}
/>,
document.getElementById("container"));
});
const legendImage = document.querySelector("img");
expect(legendImage).toBeTruthy();
const { query } = url.parse(legendImage.getAttribute('src'), true);
Expand Down

0 comments on commit 7b1e9b4

Please sign in to comment.