Skip to content

Commit

Permalink
ISPN-15284 Refactor Select: SecuredCacheConfigurator
Browse files Browse the repository at this point in the history
  • Loading branch information
karesti committed Nov 6, 2023
1 parent 000c610 commit b846b19
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 52 deletions.
1 change: 1 addition & 0 deletions cypress/e2e/1_acess_management.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe('Global stats', () => {
cy.get("[aria-label=role-description-input]").type("aRole description");
cy.get("[data-cy=dropdown-button-permissions").click();
cy.get("#select-multi-typeahead-ALL").click();
cy.get("[data-cy=dropdown-button-permissions").click();
cy.get("[aria-label=Create]").click();
cy.contains('Role aRole has been created');
cy.contains('aRole description');
Expand Down
37 changes: 21 additions & 16 deletions cypress/e2e/3_cache-crud-wizard.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ describe('Cache Creation Wizard', () => {
cy.get('[data-cy=wizardNextButton]').click();

//Filling bounded cache properties
cy.get('#featuresSelect-select-multi-typeahead-typeahead').click().type('boun');
cy.get('#BOUNDED > button').click();
cy.get('[data-cy=featuresSelect]').click();
cy.get('#select-multi-typeahead-Bounded').click();
cy.get('[data-cy=featuresSelect]').click();

cy.get('#size').click();
cy.get('[data-cy=memorySizeInput]').clear().type('1');
cy.get('#memorySizeUnit').click();
Expand All @@ -24,8 +26,9 @@ describe('Cache Creation Wizard', () => {
cy.get('#REMOVE').click();

//Filling indexed cache properties
cy.get('#featuresSelect-select-multi-typeahead-typeahead').click().type('ind');
cy.get('#INDEXED > button').click();
cy.get('[data-cy=featuresSelect]').click();
cy.get('#select-multi-typeahead-Indexed').click();
cy.get('[data-cy=featuresSelect]').click();
cy.get('#persistent').click();
cy.get('#auto').click();
cy.get('#volatile').click();
Expand All @@ -37,18 +40,18 @@ describe('Cache Creation Wizard', () => {
cy.get('[id$="org.infinispan.Car"]').click();

//Filling auth cache properties
cy.get('#featuresSelect-select-multi-typeahead-typeahead').click().type('auth');
cy.get('#SECURED > button').click();
cy.get('#roleSelector-select-multi-typeahead-typeahead').click().type('admin');
cy.get('#admin > button').click();
cy.get('#roleSelector-select-multi-typeahead-typeahead').click().type('application');
cy.get('#application > button').click();
cy.get('#roleSelector-select-multi-typeahead-typeahead').click().type('deployer');
cy.get('#deployer > button').click();
cy.get('[data-cy=featuresSelect]').click();
cy.get('#select-multi-typeahead-Authorization').click();
cy.get('[data-cy=roleSelector]').click();
cy.get("#select-multi-typeahead-admin").click();
cy.get("#select-multi-typeahead-application").click();
cy.get("#select-multi-typeahead-deployer").click();
cy.get('[data-cy=roleSelector]').click();

//Filling persistant cache properties
cy.get('#featuresSelect-select-multi-typeahead-typeahead').click().type('pers');
cy.get('#PERSISTENCE > button').click();
cy.get('[data-cy=featuresSelect]').click();
cy.get('#select-multi-typeahead-Persistence').click();
cy.get('[data-cy=featuresSelect]').click();
cy.get('[data-cy=passivationSwitch]').next().click();
cy.get('[data-cy=connectionAttempts]').type(5);
cy.get('[data-cy=connectionInterval]').type(60);
Expand All @@ -57,9 +60,11 @@ describe('Cache Creation Wizard', () => {
cy.get('#FileStore').click();

//Filling transactional cache properties
cy.get('#featuresSelect-select-multi-typeahead-typeahead').click().type('trans');
cy.get('#TRANSACTIONAL > button').click();
cy.get('[data-cy=featuresSelect]').click();
cy.get('#select-multi-typeahead-Transactional').click();
cy.get('[data-cy=featuresSelect]').click();
cy.get('#non_xa').click();

cy.get('#pessimistic').click();
cy.get('[data-cy=wizardNextButton]').click();

Expand Down
17 changes: 9 additions & 8 deletions src/app/CacheManagers/CacheTableDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ import { onSearch } from '@app/utils/searchFilter';
import { DeleteCache } from '@app/Caches/DeleteCache';
import { IgnoreCache } from '@app/Caches/IgnoreCache';
import { SetAvailableCache } from '@app/Caches/SetAvailableCache';
import { nil } from 'ajv';
interface CacheAction {
cacheName: string;
action: '' | 'ignore' | 'undo' | 'delete' | 'available';
Expand Down Expand Up @@ -91,6 +90,7 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb
const isAdmin = ConsoleServices.security().hasConsoleACL(ConsoleACL.ADMIN, connectedUser);
const isCreator = ConsoleServices.security().hasConsoleACL(ConsoleACL.CREATE, connectedUser);
const canCreateCache = ConsoleServices.security().hasConsoleACL(ConsoleACL.CREATE, connectedUser);
const [rowsLoading, setRowsLoading] = useState<boolean>(true);

const [cachesPagination, setCachesPagination] = useState({
page: 1,
Expand Down Expand Up @@ -120,7 +120,7 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb
};

useEffect(() => {
if (caches) {
if (!loadingCaches) {
const failedCaches = caches.reduce((failedCaches: string, cacheInfo: CacheInfo) => {
if (
(cacheInfo.health as ComponentHealth) == ComponentHealth.FAILED ||
Expand Down Expand Up @@ -152,10 +152,10 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb
}, [cachesPagination, filteredCaches]);

useEffect(() => {
if (loadingCaches) {
setRows(null);
if (rows !=null) {
setRowsLoading(false);
}
}, [loadingCaches]);
}, [rows]);

useEffect(() => {
setFilteredCaches(caches.filter((cache) => onSearch(searchValue, cache.name)).filter(onFilter));
Expand Down Expand Up @@ -732,7 +732,7 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb
}

const displayEmptyState = () => {
if (loadingCaches) {
if (rowsLoading) {
return (
<Bullseye>
<EmptyState variant={EmptyStateVariant.sm}>
Expand All @@ -759,9 +759,10 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb
</Bullseye>
);
};

return (
<React.Fragment>
{caches.length == 0 ? (
{!loadingCaches && !rowsLoading && caches.length == 0 ? (
emptyPage
) : (
<Card>
Expand All @@ -778,7 +779,7 @@ const CacheTableDisplay = (props: { cmName: string; setCachesCount: (count: numb
</Tr>
</Thead>
<Tbody>
{filteredCaches.length == 0 || rows == null || loadingCaches ? (
{rowsLoading || rows == null ? (
<Tr>
<Td colSpan={6}>{displayEmptyState()}</Td>
</Tr>
Expand Down
65 changes: 37 additions & 28 deletions src/app/Caches/Create/Features/SecuredCacheConfigurator.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,29 @@
import React, { useEffect, useState } from 'react';
import { FormGroup, FormHelperText, HelperText, HelperTextItem, SelectOptionProps } from '@patternfly/react-core';
import {
Bullseye,
FormGroup,
FormHelperText,
HelperText,
HelperTextItem,
SelectOptionProps, Spinner,
Text,
TextContent
} from '@patternfly/react-core';
import { useTranslation } from 'react-i18next';
import { ConsoleServices } from '@services/ConsoleServices';
import { useCreateCache } from '@app/services/createCacheHook';
import { FeatureCard } from '@app/Caches/Create/Features/FeatureCard';
import { CacheFeature } from '@services/infinispanRefData';
import { FeatureAlert } from '@app/Caches/Create/Features/FeatureAlert';
import { ExclamationCircleIcon } from '@patternfly/react-icons';
import { SelectMultiWithChips } from '@app/Common/SelectMultiWithChips';
import { useFetchAvailableRolesNames } from '@app/services/rolesHook';

const SecuredCacheConfigurator = (props: { isEnabled: boolean }) => {
const { configuration, setConfiguration } = useCreateCache();
const { t } = useTranslation();
const brandname = t('brandname.brandname');
const [roles, setRoles] = useState<string[]>(configuration.feature.securedCache.roles);
const [loading, setLoading] = useState(true);
const [availableRoles, setAvailableRoles] = useState<string[]>([]);
const [error, setError] = useState<'success' | 'error' | 'default'>('default');

useEffect(() => {
if (loading) {
ConsoleServices.security()
.getSecurityRolesNames()
.then((r) => {
if (r.isRight()) {
setAvailableRoles(r.value);
setError('success');
} else {
setError('error');
}
})
.then(() => setLoading(false));
}
}, [loading]);
const { availableRoleNames, loading, error } = useFetchAvailableRolesNames();

useEffect(() => {
setConfiguration((prevState) => {
Expand Down Expand Up @@ -62,7 +53,7 @@ const SecuredCacheConfigurator = (props: { isEnabled: boolean }) => {

const rolesOptions = () : SelectOptionProps[] => {
const selectOptions: SelectOptionProps[] = [];
availableRoles.forEach((role) => selectOptions.push({value: role, children: role}));
availableRoleNames.forEach((role) => selectOptions.push({value: role, children: role}));
return selectOptions;
};

Expand All @@ -71,15 +62,25 @@ const SecuredCacheConfigurator = (props: { isEnabled: boolean }) => {
else setRoles([...roles, selection]);
};

if (!props.isEnabled) {
if (!props.isEnabled || error != '') {
return <FeatureAlert feature={CacheFeature.SECURED} />;
}

return (
<FeatureCard
title="caches.create.configurations.feature.secured"
description="caches.create.configurations.feature.secured-description"
>
const buildContent = () => {
if (loading) {
return (
<Bullseye>
<Spinner size={'md'} isInline />
<TextContent>
<Text>
{t('caches.create.configurations.feature.roles-loading')}
</Text>
</TextContent>
</Bullseye>
)
}

return (
<FormGroup fieldId="select-roles" isRequired label={'Roles'}>
<SelectMultiWithChips id="roleSelector"
placeholder={t('caches.create.configurations.feature.select-roles')}
Expand All @@ -98,6 +99,14 @@ const SecuredCacheConfigurator = (props: { isEnabled: boolean }) => {
</FormHelperText>
)}
</FormGroup>
);
}
return (
<FeatureCard
title="caches.create.configurations.feature.secured"
description="caches.create.configurations.feature.secured-description"
>
{buildContent()}
</FeatureCard>
);
};
Expand Down
1 change: 1 addition & 0 deletions src/app/assets/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@
"index-sharding-tooltip": "Divide the index data into multiple smaller indexes called shards. Enabling sharding distributes data across multiple shards, optimizing system resources and enhancing search capabilities.",
"secured": "Security authorization",
"secured-description": "To protect data, restrict user access to the cache. When a user does not have one of the roles selected from the menu below, {{brandname}} denies cache operations.",
"roles-loading": "Loading available roles...",
"select-roles": "Select roles",
"select-roles-helper": "You must select at least one role.",
"backups": "Backups for {{local_site_name}}",
Expand Down
26 changes: 26 additions & 0 deletions src/app/services/rolesHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,32 @@ import { ConsoleServices } from '@services/ConsoleServices';
import { useApiAlert } from '@utils/useApiAlert';
import { useTranslation } from 'react-i18next';

export function useFetchAvailableRolesNames() {
const [availableRoleNames, setAvailableRoleNames] = useState<string[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
if (loading) {
ConsoleServices.security()
.getSecurityRolesNames()
.then((either) => {
if (either.isRight()) {
setAvailableRoleNames(either.value);
} else {
setError(either.value.message);
}
})
.then(() => setLoading(false));
}
}, [loading]);

return {
availableRoleNames,
loading,
error
};
}

export function useFetchAvailableRoles() {
const [roles, setRoles] = useState<Role[]>([]);
const [loading, setLoading] = useState(true);
Expand Down

0 comments on commit b846b19

Please sign in to comment.