-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[backend/frontend] Introduce TAXII push endpoints (#8932)
- Loading branch information
1 parent
8a66e8b
commit 3497aa7
Showing
28 changed files
with
1,563 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
opencti-platform/opencti-front/src/private/components/data/IngestionTaxiiCollections.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import React from 'react'; | ||
import makeStyles from '@mui/styles/makeStyles'; | ||
import { QueryRenderer } from '../../../relay/environment'; | ||
import ListLines from '../../../components/list_lines/ListLines'; | ||
import IngestionTaxiiCollectionLines, { IngestionTaxiiCollectionLinesQuery } from './ingestionTaxiiCollection/IngestionTaxiiCollectionLines'; | ||
import IngestionTaxiiCollectionCreation from './ingestionTaxiiCollection/IngestionTaxiiCollectionCreation'; | ||
import { usePaginationLocalStorage } from '../../../utils/hooks/useLocalStorage'; | ||
import { useFormatter } from '../../../components/i18n'; | ||
import IngestionMenu from './IngestionMenu'; | ||
import Breadcrumbs from '../../../components/Breadcrumbs'; | ||
import Security from '../../../utils/Security'; | ||
import { INGESTION_SETINGESTIONS } from '../../../utils/hooks/useGranted'; | ||
|
||
const LOCAL_STORAGE_KEY = 'ingestionTaxii'; | ||
|
||
// Deprecated - https://mui.com/system/styles/basics/ | ||
// Do not use it for new code. | ||
const useStyles = makeStyles(() => ({ | ||
container: { | ||
margin: 0, | ||
padding: '0 200px 50px 0', | ||
}, | ||
})); | ||
|
||
const IngestionTaxiiCollections = () => { | ||
const classes = useStyles(); | ||
const { t_i18n } = useFormatter(); | ||
const { | ||
viewStorage, | ||
paginationOptions, | ||
helpers: storageHelpers, | ||
} = usePaginationLocalStorage(LOCAL_STORAGE_KEY, { | ||
sortBy: 'name', | ||
orderAsc: false, | ||
searchTerm: '', | ||
}); | ||
const dataColumns = { | ||
name: { | ||
label: 'Name', | ||
width: '15%', | ||
isSortable: true, | ||
}, | ||
id: { | ||
label: 'Push Collection URI', | ||
width: '65%', | ||
isSortable: false, | ||
}, | ||
ingestion_running: { | ||
label: 'Status', | ||
width: '10%', | ||
isSortable: false, | ||
}, | ||
}; | ||
return ( | ||
<div className={classes.container}> | ||
<Breadcrumbs elements={[{ label: t_i18n('Data') }, { label: t_i18n('Ingestion') }, { label: t_i18n('TAXII push'), current: true }]} /> | ||
<IngestionMenu/> | ||
<ListLines | ||
helpers={storageHelpers} | ||
sortBy={viewStorage.sortBy} | ||
orderAsc={viewStorage.orderAsc} | ||
dataColumns={dataColumns} | ||
handleSort={storageHelpers.handleSort} | ||
handleSearch={storageHelpers.handleSearch} | ||
displayImport={false} | ||
secondaryAction={true} | ||
keyword={viewStorage.searchTerm} | ||
> | ||
<QueryRenderer | ||
query={IngestionTaxiiCollectionLinesQuery} | ||
variables={{ count: 200, ...paginationOptions }} | ||
render={({ props }) => ( | ||
<IngestionTaxiiCollectionLines | ||
data={props} | ||
paginationOptions={paginationOptions} | ||
refetchPaginationOptions={{ count: 200, ...paginationOptions }} | ||
dataColumns={dataColumns} | ||
initialLoading={props === null} | ||
/> | ||
)} | ||
/> | ||
</ListLines> | ||
<Security needs={[INGESTION_SETINGESTIONS]}> | ||
<IngestionTaxiiCollectionCreation paginationOptions={paginationOptions} /> | ||
</Security> | ||
</div> | ||
); | ||
}; | ||
|
||
export default IngestionTaxiiCollections; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
154 changes: 154 additions & 0 deletions
154
...src/private/components/data/ingestionTaxiiCollection/IngestionTaxiiCollectionCreation.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import React from 'react'; | ||
import * as PropTypes from 'prop-types'; | ||
import { Field, Form, Formik } from 'formik'; | ||
import withStyles from '@mui/styles/withStyles'; | ||
import Button from '@mui/material/Button'; | ||
import * as Yup from 'yup'; | ||
import { graphql } from 'react-relay'; | ||
import * as R from 'ramda'; | ||
import Drawer, { DrawerVariant } from '../../common/drawer/Drawer'; | ||
import inject18n from '../../../../components/i18n'; | ||
import { commitMutation } from '../../../../relay/environment'; | ||
import TextField from '../../../../components/TextField'; | ||
import CreatorField from '../../common/form/CreatorField'; | ||
import { fieldSpacingContainerStyle } from '../../../../utils/field'; | ||
import { insertNode } from '../../../../utils/store'; | ||
import SwitchField from '../../../../components/fields/SwitchField'; | ||
|
||
const styles = (theme) => ({ | ||
buttons: { | ||
marginTop: 20, | ||
textAlign: 'right', | ||
}, | ||
button: { | ||
marginLeft: theme.spacing(2), | ||
}, | ||
}); | ||
|
||
const IngestionTaxiiCollectionCreationMutation = graphql` | ||
mutation IngestionTaxiiCollectionCreationMutation($input: IngestionTaxiiCollectionAddInput!) { | ||
ingestionTaxiiCollectionAdd(input: $input) { | ||
...IngestionTaxiiCollectionLine_node | ||
} | ||
} | ||
`; | ||
|
||
const ingestionTaxiiCollectionCreationValidation = (t) => Yup.object().shape({ | ||
name: Yup.string().required(t('This field is required')), | ||
description: Yup.string().nullable(), | ||
user_id: Yup.object().nullable(), | ||
confidence_to_score: Yup.bool().nullable(), | ||
}); | ||
|
||
const IngestionTaxiiCollectionCreation = (props) => { | ||
const { t, classes } = props; | ||
const onSubmit = (values, { setSubmitting, resetForm }) => { | ||
const input = { | ||
name: values.name, | ||
description: values.description, | ||
confidence_to_score: values.confidence_to_score, | ||
user_id: values.user_id?.value, | ||
}; | ||
commitMutation({ | ||
mutation: IngestionTaxiiCollectionCreationMutation, | ||
variables: { | ||
input, | ||
}, | ||
updater: (store) => { | ||
insertNode( | ||
store, | ||
'Pagination_ingestionTaxiiCollections', | ||
props.paginationOptions, | ||
'ingestionTaxiiCollectionAdd', | ||
); | ||
}, | ||
setSubmitting, | ||
onCompleted: () => { | ||
setSubmitting(false); | ||
resetForm(); | ||
}, | ||
}); | ||
}; | ||
|
||
return ( | ||
<Drawer title={t('Create a TAXII Push ingester')} variant={DrawerVariant.createWithPanel}> | ||
{({ onClose }) => ( | ||
<Formik | ||
initialValues={{ | ||
name: '', | ||
description: '', | ||
user_id: '', | ||
confidence_to_score: false, | ||
}} | ||
validationSchema={ingestionTaxiiCollectionCreationValidation(t)} | ||
onSubmit={onSubmit} | ||
onReset={onClose} | ||
> | ||
{({ submitForm, handleReset, isSubmitting }) => ( | ||
<Form> | ||
<Field | ||
component={TextField} | ||
variant="standard" | ||
name="name" | ||
label={t('Name')} | ||
fullWidth={true} | ||
/> | ||
<Field | ||
component={TextField} | ||
variant="standard" | ||
name="description" | ||
label={t('Description')} | ||
fullWidth={true} | ||
style={fieldSpacingContainerStyle} | ||
/> | ||
<CreatorField | ||
name="user_id" | ||
label={t('User responsible for data creation (empty = System)')} | ||
containerStyle={fieldSpacingContainerStyle} | ||
showConfidence | ||
/> | ||
<Field | ||
component={SwitchField} | ||
type="checkbox" | ||
name="confidence_to_score" | ||
label={t('Copy confidence level to OpenCTI scores for indicators')} | ||
containerstyle={fieldSpacingContainerStyle} | ||
/> | ||
<div className={classes.buttons}> | ||
<Button | ||
variant="contained" | ||
onClick={handleReset} | ||
disabled={isSubmitting} | ||
classes={{ root: classes.button }} | ||
> | ||
{t('Cancel')} | ||
</Button> | ||
<Button | ||
variant="contained" | ||
color="secondary" | ||
onClick={submitForm} | ||
disabled={isSubmitting} | ||
classes={{ root: classes.button }} | ||
> | ||
{t('Create')} | ||
</Button> | ||
</div> | ||
</Form> | ||
)} | ||
</Formik> | ||
)} | ||
</Drawer> | ||
); | ||
}; | ||
|
||
IngestionTaxiiCollectionCreation.propTypes = { | ||
paginationOptions: PropTypes.object, | ||
classes: PropTypes.object, | ||
theme: PropTypes.object, | ||
t: PropTypes.func, | ||
}; | ||
|
||
export default R.compose( | ||
inject18n, | ||
withStyles(styles, { withTheme: true }), | ||
)(IngestionTaxiiCollectionCreation); |
Oops, something went wrong.