Skip to content
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

Adding Test inject in scenario and simulations #1267

Merged
merged 5 commits into from
Aug 1, 2024
Merged
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
1,048 changes: 548 additions & 500 deletions openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.openbas.database.model.InjectorContract;
import io.openbas.helper.InjectModelHelper;
import io.openbas.injectors.email.EmailContract;
import io.openbas.injectors.ovh.OvhSmsContract;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
Expand Down Expand Up @@ -59,6 +61,11 @@ public class InjectOutput {
@JsonProperty("inject_content")
private ObjectNode content;

@JsonProperty("inject_testable")
public boolean canBeTested() {
return this.getInjectType().equals(EmailContract.TYPE) || this.getInjectType().equals(OvhSmsContract.TYPE);
}

public InjectOutput(
String id,
String title,
Expand Down
7 changes: 6 additions & 1 deletion openbas-front/src/actions/Inject.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as schema from './Schema';
import { bulkDeleteReferential, delReferential, getReferential, postReferential, putReferential } from '../utils/Action';
import { bulkDeleteReferential, delReferential, getReferential, postReferential, putReferential, simpleCall } from '../utils/Action';

// -- INJECTS --

Expand All @@ -13,6 +13,11 @@ export const tryInject = (injectId) => (dispatch) => {
return getReferential(null, uri, null)(dispatch);
};

export const testInject = (injectId) => {
const uri = `/api/injects/test/${injectId}`;
return simpleCall(uri);
};

// -- EXERCISES --

export const fetchExerciseInjects = (exerciseId) => (dispatch) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,23 @@ import Transition from '../../../../components/common/Transition';
import type { InjectStore } from '../../../../actions/injects/Inject';
import { InjectContext, PermissionsContext } from '../Context';
import type { Inject, InjectStatus, InjectStatusExecution, Tag } from '../../../../utils/api-types';
import { duplicateInjectForExercise, duplicateInjectForScenario, tryInject } from '../../../../actions/Inject';
import { duplicateInjectForExercise, duplicateInjectForScenario, tryInject, testInject } from '../../../../actions/Inject';
import { useAppDispatch } from '../../../../utils/hooks';
import DialogDuplicate from '../../../../components/common/DialogDuplicate';

interface Props {
inject: InjectStore;
inject: InjectStore & { inject_testable?: boolean }; // FIXME: Inject object coming from multiple endpoints with different properties
tagsMap: Record<string, Tag>;
johanah29 marked this conversation as resolved.
Show resolved Hide resolved
setSelectedInjectId: (injectId: Inject['inject_id']) => void;
isDisabled: boolean;
canBeTested?: boolean;
}

const InjectPopover: FunctionComponent<Props> = ({
inject,
setSelectedInjectId,
isDisabled,
canBeTested = false,
}) => {
// Standard hooks
const { t } = useFormatter();
Expand All @@ -36,12 +38,14 @@ const InjectPopover: FunctionComponent<Props> = ({
const [openDelete, setOpenDelete] = useState(false);
const [duplicate, setDuplicate] = useState(false);
const [openTry, setOpenTry] = useState(false);
const [openTest, setOpenTest] = useState(false);
const [openEnable, setOpenEnable] = useState(false);
const [openDisable, setOpenDisable] = useState(false);
const [openDone, setOpenDone] = useState(false);
const [openResult, setOpenResult] = useState(false);
const [openTrigger, setOpenTrigger] = useState(false);
const [injectResult, setInjectResult] = useState<InjectStatus | null>(null);
const [_injectTestResult, setInjectTestResult] = useState<InjectStatus | null>(null);
const [anchorEl, setAnchorEl] = useState<Element | null>(null);

const handlePopoverOpen = (event: React.MouseEvent<HTMLButtonElement>) => {
Expand Down Expand Up @@ -100,6 +104,23 @@ const InjectPopover: FunctionComponent<Props> = ({
handleCloseTry();
};

const handleOpenTest = () => {
setOpenTest(true);
handlePopoverClose();
};

const handleCloseTest = () => {
setOpenTest(false);
setInjectTestResult(null);
};

const submitTest = () => {
testInject(inject.inject_id).then((result: { data: InjectStatus }) => {
setInjectTestResult(result.data);
});
handleCloseTest();
};

const handleOpenEnable = () => {
setOpenEnable(true);
handlePopoverClose();
Expand Down Expand Up @@ -190,6 +211,14 @@ const InjectPopover: FunctionComponent<Props> = ({
{t('Mark as done')}
</MenuItem>
)}
{inject.inject_testable && canBeTested && (
<MenuItem
disabled={inject.inject_teams?.length === 0}
onClick={handleOpenTest}
>
{t('Test')}
</MenuItem>
)}
{inject.inject_type !== 'openbas_manual' && onUpdateInjectTrigger && (
<MenuItem
onClick={handleOpenTrigger}
Expand Down Expand Up @@ -295,6 +324,26 @@ const InjectPopover: FunctionComponent<Props> = ({
</Button>
</DialogActions>
</Dialog>
<Dialog
TransitionComponent={Transition}
open={openTest}
onClose={handleCloseTest}
PaperProps={{ elevation: 1 }}
>
<DialogContent>
<DialogContentText>
<p>{t(`Do you want to test this inject: ${inject.inject_title}?`)}</p>
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseTest}>
{t('Cancel')}
</Button>
<Button color="secondary" onClick={submitTest}>
{t('Test')}
</Button>
</DialogActions>
</Dialog>
<Dialog
TransitionComponent={Transition}
open={openEnable}
Expand Down
11 changes: 6 additions & 5 deletions openbas-front/src/admin/components/common/injects/Injects.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ const Injects = (props) => {
aria-label="Change view mode"
>
{injectContext.onImportInjectFromXls
&& <ImportUploaderInjectFromXls />}
&& <ImportUploaderInjectFromXls />}
{setViewMode
&& <Tooltip title={t('List view')}>
<ToggleButton
Expand All @@ -326,7 +326,7 @@ const Injects = (props) => {
>
<ReorderOutlined fontSize="small" color='inherit' />
</ToggleButton>
</Tooltip>
</Tooltip>
}
{setViewMode
&& <Tooltip title={t('Distribution view')}>
Expand All @@ -337,7 +337,7 @@ const Injects = (props) => {
>
<BarChartOutlined fontSize="small" color='primary' />
</ToggleButton>
</Tooltip>
</Tooltip>
}
</ToggleButtonGroup>
</div>
Expand Down Expand Up @@ -484,7 +484,7 @@ const Injects = (props) => {
<ListItemText
primary={
<div className={(!injectContract || !isContractExposed
|| !inject.inject_enabled) ? classes.disabled : ''}
|| !inject.inject_enabled) ? classes.disabled : ''}
>
<div
className={classes.bodyItem}
Expand All @@ -496,7 +496,7 @@ const Injects = (props) => {
config={injectContract?.config}
label={injectorContractName}
/>
) : <InjectorContract variant="list" label={t('Deleted')} deleted/>
) : <InjectorContract variant="list" label={t('Deleted')} deleted />
}
</div>
<div
Expand Down Expand Up @@ -555,6 +555,7 @@ const Injects = (props) => {
<ListItemSecondaryAction>
<InjectPopover
inject={inject}
canBeTested
tagsMap={tagsMap}
setSelectedInjectId={setSelectedInjectId}
isDisabled={!injectContract || !isContractExposed}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const TimelineOverview = () => {

return (
<div className={classes.root}>
<AnimationMenu exerciseId={exerciseId}/>
<AnimationMenu exerciseId={exerciseId} />
<div style={{ float: 'left', marginRight: 10 }}>
<SearchFilter
variant="small"
Expand All @@ -132,13 +132,13 @@ const TimelineOverview = () => {
currentTags={filtering.tags}
/>
</div>
<div className="clearfix"/>
<div className="clearfix" />
<Timeline
injects={filteredInjects}
teams={teams}
onSelectInject={(id: string) => setSelectedInjectId(id)}
></Timeline>
<div className="clearfix"/>
<div className="clearfix" />
<Grid container spacing={3} style={{ marginTop: 50, paddingBottom: 24 }}>
<Grid container item spacing={3}>
<Grid item xs={6} sx={{ display: 'flex', flexDirection: 'column' }}>
Expand All @@ -162,10 +162,10 @@ const TimelineOverview = () => {
<InjectIcon
isPayload={isNotEmptyField(inject.inject_injector_contract.injector_contract_payload)}
type={
inject.inject_injector_contract.injector_contract_payload
? inject.inject_injector_contract.injector_contract_payload?.payload_collector_type
|| inject.inject_injector_contract.injector_contract_payload?.payload_type
: inject.inject_type
inject.inject_injector_contract.injector_contract_payload
? inject.inject_injector_contract.injector_contract_payload?.payload_collector_type
|| inject.inject_injector_contract.injector_contract_payload?.payload_type
: inject.inject_type
}
variant="inline"
/>
Expand All @@ -186,9 +186,9 @@ const TimelineOverview = () => {
<ProgressBarCountdown
date={inject.inject_date}
paused={
exercise?.exercise_status === 'PAUSED'
|| exercise?.exercise_status === 'CANCELED'
}
exercise?.exercise_status === 'PAUSED'
|| exercise?.exercise_status === 'CANCELED'
}
/>
</div>
<div
Expand All @@ -201,7 +201,7 @@ const TimelineOverview = () => {
{fndt(inject.inject_date)}
</div>
</div>
}
}
/>
<ListItemSecondaryAction>
<InjectPopover
Expand All @@ -216,7 +216,7 @@ const TimelineOverview = () => {
})}
</List>
) : (
<Empty message={t('No pending injects in this simulation.')}/>
<Empty message={t('No pending injects in this simulation.')} />
)}
</Paper>
</Grid>
Expand All @@ -238,11 +238,11 @@ const TimelineOverview = () => {
<InjectIcon
isPayload={isNotEmptyField(inject.inject_injector_contract.injector_contract_payload)}
type={
inject.inject_injector_contract.injector_contract_payload
? inject.inject_injector_contract.injector_contract_payload?.payload_collector_type
|| inject.inject_injector_contract.injector_contract_payload?.payload_type
: inject.inject_type
}
inject.inject_injector_contract.injector_contract_payload
? inject.inject_injector_contract.injector_contract_payload?.payload_collector_type
|| inject.inject_injector_contract.injector_contract_payload?.payload_type
: inject.inject_type
}
variant="inline"
/>
</ListItemIcon>
Expand Down Expand Up @@ -278,16 +278,16 @@ const TimelineOverview = () => {
{t('s')})
</div>
</div>
}
}
/>
<ListItemSecondaryAction>
<PreviewOutlined/>
<PreviewOutlined />
</ListItemSecondaryAction>
</ListItemButton>
))}
</List>
) : (
<Empty message={t('No processed injects in this simulation.')}/>
<Empty message={t('No processed injects in this simulation.')} />
)}
</Paper>
</Grid>
Expand All @@ -299,15 +299,15 @@ const TimelineOverview = () => {
{t('Sent injects over time')}
</Typography>
<Paper variant="outlined" classes={{ root: classes.paperChart }}>
<InjectOverTimeArea exerciseId={exerciseId}/>
<InjectOverTimeArea exerciseId={exerciseId} />
</Paper>
</Grid>
<Grid item xs={6}>
<Typography variant="h4">
{t('Sent injects over time')}
</Typography>
<Paper variant="outlined" classes={{ root: classes.paperChart }}>
<InjectOverTimeLine exerciseId={exerciseId}/>
<InjectOverTimeLine exerciseId={exerciseId} />
</Paper>
</Grid>
</Grid>
Expand Down
Loading