Skip to content

Commit

Permalink
ISPN-15125 Error page is shown for non-admin user if accesses cache t…
Browse files Browse the repository at this point in the history
…o which has permission
  • Loading branch information
karesti committed Oct 4, 2023
1 parent f37cb89 commit c49c6b4
Show file tree
Hide file tree
Showing 13 changed files with 295 additions and 101 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/no-empty-function": "off",
"prettier/prettier": "off",
"import/no-unresolved": "off",
"import/extensions": "off",
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pull_requests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
docker exec $(docker ps -q -l) /opt/infinispan/bin/cli.sh install org.ow2.asm:asm-tree:9.4
docker exec $(docker ps -q -l) /opt/infinispan/bin/cli.sh install org.ow2.asm:asm-util:9.4
- name: Restarting Infnispan Server After Nashorn Installation
- name: Restarting Infinispan Server After Nashorn Installation
run: |
docker restart $(docker ps -q -l)
# Wait for server to startup
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/cache-metrics.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ describe('Cache Metrics Overview', () => {
cy.login(Cypress.env('username'), Cypress.env('password'), '/cache/people');
//Check for Labels
cy.contains('Metrics (Enabled)').click();
cy.contains('Approximate number of entries');
cy.contains('Approx. number of entries');
cy.contains('Minimum number of nodes');

// Check for data greater than -1
Expand Down
3 changes: 0 additions & 3 deletions cypress/e2e/data-container.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,10 @@ describe('Data Container Overview', () => {
cy.get('[data-cy=cacheFilterSelect]').click();
cy.get('[data-cy=cacheFilterSelectExpanded]').should('exist');
cy.get('[id$="Invalidated"]').click(); //Filtering invalidated caches
cy.get('[id$="Scattered"]').click(); //Filtering scattered caches
cy.get('[data-cy=cacheFilterSelect]').click(); //Closing filter selectbox

//Verifying that only replicated,invalidated and scattered caches are shown
cy.contains('jboss-cache');
cy.contains('invalidationCache');
cy.contains('scattered-cache');
cy.get('[data-cy=cachesTable] tr').should('have.length', 4); //4 including header row

//Clears all filters
Expand Down
27 changes: 19 additions & 8 deletions cypress/e2e/rbac_func.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe('RBAC Functionlity Tests', () => {
cy.get('[data-cy=cacheManagerStatus]').should('exist');
cy.get('[data-cy=navigationTabs]').should('exist');
cy.contains(/^\d+ Caches$/);

cy.contains('10 Counters');
if (isMonitor) {
cy.contains('1 Tasks').should('not.exist');
Expand Down Expand Up @@ -153,10 +153,15 @@ describe('RBAC Functionlity Tests', () => {
cy.get('[data-cy=queriesTab]').should('exist');
}

//Checking cache configuration page
cy.get('[data-cy=cacheConfigurationTab]').click();
cy.contains('authorization');
cy.contains(roleName);
if (isSuperAdmin) {
//Checking cache configuration page
cy.get('[data-cy=cacheConfigurationTab]').click();
cy.contains('authorization');
cy.contains(roleName);
} else {
cy.get('[data-cy=cacheConfigurationTab]').should('not.exist');
}

cy.get('[data-cy=manageIndexesLink]').click();
if (isSuperAdmin) {
cy.get('[data-cy=clearIndexButton]').should('exist');
Expand Down Expand Up @@ -247,9 +252,15 @@ describe('RBAC Functionlity Tests', () => {
cy.get('[data-cy=clearAllButton]').click();
cy.get('[data-cy=deleteButton]').click();
cy.wait(1500); //Waiting till the whole page is loaded
//Checking cache configuration page
cy.get('[data-cy=cacheConfigurationTab]').click();
cy.contains('authorization').should('not.exist');

if (isSuperAdmin) {
//Checking cache configuration page
cy.get('[data-cy=cacheConfigurationTab]').click();
cy.contains('authorization').should('not.exist');
} else {
cy.get('[data-cy=cacheConfigurationTab]').should('not.exist');
}

cy.get('[data-cy=manageIndexesLink]').click();
if (isSuperAdmin) {
cy.get('[data-cy=clearIndexButton]').should('exist');
Expand Down
144 changes: 144 additions & 0 deletions run-server-for-e2e-container.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#!/usr/bin/env bash

set -e

if [[ $1 = "--ci" ]]; then
echo "Launch script finished"
else
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
fi


#If running on the existing server please provide the Path with this property.
EXISTING_SERVER_PATH="${EXISTING_SERVER_PATH}"
#Base directory where the server should be downloaded
BASE_DIR="server"
#The version of the server is either set as an environment variable or is the latest dev version
SERVER_VERSION="${SERVER_VERSION:-"14.0.9.Final"}"
#Root path from there the infinispan server should be downloaded
ZIP_ROOT="http://downloads.jboss.org/infinispan"
#If this environment variable is provided then it is used for downloading the server;
SERVER_DOWNLOAD_URL="${SERVER_DOWNLOAD_URL}"
#The name of the zip file;
ZIP_NAME="${ZIP_NAME:-"infinispan-server-$SERVER_VERSION.zip"}"
#The name of directory where the server should be extracted;
SERVER_UNZIP_DIR="server-unzipped"
#Path to the extracted server;
SERVER_HOME=${BASE_DIR}/${SERVER_UNZIP_DIR}

CONF_DIR_TO_COPY_FROM="scripts/"
DATA_DIR="data/"
IS_SSL_PROCESSED=0
#The working directory - the server is copied to this directory and later changes are done to this dir;
SERVER_DIR="infinispan-server"
#CLI command for getting the cluster size
CLUSTER_SIZE_MAIN="$SERVER_HOME/bin/cli.sh -c localhost:11322 -f batch "

USER_NAME="admin"
PASSWORD="password"

MONITOR_USER_NAME="monitor"
OBSERVER_USER_NAME="observer"
APPLICATION_USER_NAME="application"
DEPLOYER_USER_NAME="deployer"

#Function prepares the server directory, i.e. downloads, extracts, copies to working directory and makes changes to configuration;
function prepareServerDir()
{
local isCi=$1
local confPath=$2
local dirName=${3}

cd ${BASE_DIR}
if [ -n "${EXISTING_SERVER_PATH}" ]; then
mkdir ${SERVER_UNZIP_DIR}
cp -r ${EXISTING_SERVER_PATH} $SERVER_UNZIP_DIR
else
if [ ! -f ${ZIP_NAME} ]; then
if [ -n "$SERVER_DOWNLOAD_URL" ]; then
wget "${SERVER_DOWNLOAD_URL}"
else
wget "$ZIP_ROOT/$SERVER_VERSION/$ZIP_NAME";
fi
fi

unzip -d $SERVER_UNZIP_DIR $ZIP_NAME
fi
cd ..

if [[ -z "${SERVER_TMP}" ]]; then
SERVER_TMP=server/${SERVER_DIR}
mkdir ${SERVER_TMP} 2>/dev/null
echo "Created temporary directory: $SERVER_TMP"

cp -r ${SERVER_HOME}/*/* $SERVER_TMP
echo "Server copied to temporary directory."
fi

cp -r ${SERVER_HOME}/*/server ${SERVER_TMP}/${dirName}

cp "${CONF_DIR_TO_COPY_FROM}/${confPath}" ${SERVER_TMP}/${dirName}/conf
echo "Infinispan configuration file ${confPath} copied to server ${dirName}."

export SERVER_TMP=${SERVER_TMP}
}

#Starts the server;
function startServer()
{
local isCi=$1
local confPath=$2
local port=${3}
local nodeName=${4}
local jvmParam=${5}

prepareServerDir "${isCi}" ${confPath} ${nodeName}

if [[ ! -z ${port} ]]; then
portStr="-p ${port}"
fi

$SERVER_TMP/bin/cli.sh user create ${USER_NAME} -p ${PASSWORD} -s ${nodeName}
$SERVER_TMP/bin/cli.sh user create ${MONITOR_USER_NAME} -p ${PASSWORD} -s ${nodeName}
$SERVER_TMP/bin/cli.sh user create ${OBSERVER_USER_NAME} -p ${PASSWORD} -s ${nodeName}
$SERVER_TMP/bin/cli.sh user create ${APPLICATION_USER_NAME} -p ${PASSWORD} -s ${nodeName}
$SERVER_TMP/bin/cli.sh user create ${DEPLOYER_USER_NAME} -p ${PASSWORD} -s ${nodeName}

#Installing nashorn engine before server startup
${SERVER_TMP}/bin/cli.sh install org.openjdk.nashorn:nashorn-core:15.4 --server-root=infinispan-4-e2e
${SERVER_TMP}/bin/cli.sh install org.ow2.asm:asm:9.4 --server-root=infinispan-4-e2e
${SERVER_TMP}/bin/cli.sh install org.ow2.asm:asm-commons:9.4 --server-root=infinispan-4-e2e
${SERVER_TMP}/bin/cli.sh install org.ow2.asm:asm-tree:9.4 --server-root=infinispan-4-e2e
${SERVER_TMP}/bin/cli.sh install org.ow2.asm:asm-util:9.4 --server-root=infinispan-4-e2e

if [[ ${isCi} = "--ci" ]]; then
nohup $SERVER_TMP/bin/server.sh -Djavax.net.debug -Dorg.infinispan.openssl=false -c ${confPath} -s ${SERVER_TMP}/${nodeName} ${portStr:-""} --node-name=${nodeName} ${jvmParam:-} &
else
${SERVER_TMP}/bin/server.sh -Djavax.net.debug -Dorg.infinispan.openssl=false -c ${confPath} -s ${SERVER_TMP}/${nodeName} ${portStr:-} --node-name=${nodeName} ${jvmParam:-} &
fi

#Creating data in the server
sleep 10
cd $DATA_DIR/
./create-data.sh ${USER_NAME} ${PASSWORD}
}

#deleting the testable server directory
rm -drf server/${SERVER_DIR}
rm -drf server/${SERVER_UNZIP_DIR}

export JAVA_OPTS="-Xms512m -Xmx1024m -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=512m"

startServer "$1" infinispan-basic-auth.xml 11222 infinispan-4-e2e
echo "Infinispan Server for E2E tests has started."


if [[ $1 = "--ci" ]]; then
echo "Launch script finished"
else
# Wait until script stopped
while :
do
sleep 5
done
fi
17 changes: 6 additions & 11 deletions src/app/CacheManagers/CacheTableDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb
setChipsCacheType([]);
} else {
// From the select, extract each category
let filterStatus = extract(selectedFilters, cacheStatus);
let filterFeatures = extract(selectedFilters, cacheFeatures);
let filterCacheType = extract(selectedFilters, cacheTypes);
const filterStatus = extract(selectedFilters, cacheStatus);
const filterFeatures = extract(selectedFilters, cacheFeatures);
const filterCacheType = extract(selectedFilters, cacheTypes);
// Update chips
setChipsCacheStatus(filterStatus);
setChipsCacheFeature(filterFeatures);
Expand Down Expand Up @@ -185,7 +185,7 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb

const actionResolver = (rowData: IRowData, extraData: IExtraData) => {
// @ts-ignore
let cacheName: string = rowData.cells[0].cacheName as string;
const cacheName: string = rowData.cells[0].cacheName as string;

if (!cacheName) {
return [];
Expand Down Expand Up @@ -213,7 +213,7 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb
];
}

let actions = [
const actions = [
{
'data-cy': 'deleteCacheAction',
title: t('cache-managers.delete'),
Expand Down Expand Up @@ -256,14 +256,10 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb
};

const closeIgnoreModal = (ignoreDone: boolean) => {
if (ignoreDone) {
}
setCacheAction({ cacheName: '', action: '' });
};

const closeAvailableModal = (ignoreDone: boolean) => {
if (ignoreDone) {
}
setCacheAction({ cacheName: '', action: '' });
};

Expand Down Expand Up @@ -485,7 +481,7 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb
};

const onDeleteChip = (chip) => {
let actualSelection = selectedFilters.filter((item) => item !== chip);
const actualSelection = selectedFilters.filter((item) => item !== chip);
setSelectedFilters(actualSelection);
};

Expand Down Expand Up @@ -569,7 +565,6 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb
<SelectOption key={1} value={t('cache-managers.mode-repl')} />
<SelectOption key={2} value={t('cache-managers.mode-dist')} />
<SelectOption key={3} value={t('cache-managers.mode-invalid')} />
<SelectOption key={4} value={t('cache-managers.mode-scattered')} />
</SelectGroup>
<SelectGroup label={t('cache-managers.cache-filter-feature-label')} key="group2">
<SelectOption key={5} value={t('cache-managers.cache-filter-feature-bounded')} />
Expand Down
46 changes: 28 additions & 18 deletions src/app/Caches/CacheMetrics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,36 +28,44 @@ import { useTranslation } from 'react-i18next';
import { StorageType } from '@services/infinispanRefData';
import { DataAccessChart } from './DataAccessChart';
import { useCacheDetail } from '@app/services/cachesHook';
import { ConsoleACL } from '@services/securityService';
import { ConsoleServices } from '@services/ConsoleServices';
import { useConnectedUser } from '@app/services/userManagementHook';

const CacheMetrics = (props: { cacheName: string; display: boolean }) => {
const { connectedUser } = useConnectedUser();
const { cache, error, loading } = useCacheDetail();
const [stats, setStats] = useState<CacheStats | undefined>(cache.stats);
const [displayQueryStats, setDisplayQueryStats] = useState<boolean>(false);
const [memory, setMemory] = useState<string | undefined>(undefined);
const { t } = useTranslation();
const brandname = t('brandname.brandname');
const [displayDataDistribution, setDisplayDataDistribution] = useState<boolean>(false);

useEffect(() => {
const loadMemory = JSON.parse(cache.configuration.config)[props.cacheName];
const cacheMode = Object.keys(loadMemory)[0];
if (loadMemory[cacheMode].memory) {
if (loadMemory[cacheMode].memory.storage === 'HEAP' && loadMemory[cacheMode].memory['max-size'])
setMemory(loadMemory[cacheMode].memory.storage);
else if (loadMemory[cacheMode].memory.storage === 'OFF_HEAP') setMemory(loadMemory[cacheMode].memory.storage);
} else {
setMemory('HEAP');
if (ConsoleServices.security().hasConsoleACL(ConsoleACL.ADMIN, connectedUser)) {
// Data distrib is for admin
setDisplayDataDistribution(true);
const loadMemory = cache.configuration ? JSON.parse(cache.configuration.config)[props.cacheName] : undefined;
if (loadMemory) {
const cacheMode = Object.keys(loadMemory)[0];
if (loadMemory[cacheMode].memory) {
if (loadMemory[cacheMode].memory.storage === 'HEAP' && loadMemory[cacheMode].memory['max-size'])
setMemory(loadMemory[cacheMode].memory.storage);
else if (loadMemory[cacheMode].memory.storage === 'OFF_HEAP') setMemory(loadMemory[cacheMode].memory.storage);
} else {
setMemory('HEAP');
}
} else {
setMemory('HEAP');
}
}

setStats(cache.stats);
let loadQueryStats = cache.stats != undefined && cache.stats.enabled && cache.features.indexed;
const loadQueryStats = cache.stats != undefined && cache.stats.enabled && cache.features.indexed;
setDisplayQueryStats(loadQueryStats);
}, [cache, error]);

useEffect(() => {
if (props.display) {
}
}, []);

const buildOperationsPerformanceCard = () => {
if (!stats) {
return '';
Expand Down Expand Up @@ -262,13 +270,15 @@ const CacheMetrics = (props: { cacheName: string; display: boolean }) => {
<GridItem span={4}>{buildEntriesCard()}</GridItem>
<GridItem span={4}>{buildMemoryCard()}</GridItem>
<GridItem span={4}>{buildOperationsPerformanceCard()}</GridItem>
<GridItem span={7}>
<DataDistributionChart cacheName={props.cacheName} />
</GridItem>
{displayDataDistribution &&
<GridItem span={7}>
<DataDistributionChart cacheName={props.cacheName} />
</GridItem>
}
<GridItem span={5}>
<DataAccessChart stats={stats} />
</GridItem>
<GridItem span={12}>{buildQueryStats()}</GridItem>
<GridItem span={displayDataDistribution ? 12 : 7}>{buildQueryStats()}</GridItem>
</Grid>
);
};
Expand Down
Loading

0 comments on commit c49c6b4

Please sign in to comment.