Skip to content

Commit

Permalink
[api/frontend] Fix external reference files automatic import errors (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
SamuelHassine committed Sep 4, 2022
1 parent 844fa26 commit fa126c5
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ import DialogActions from '@mui/material/DialogActions';
import { ExpandMoreOutlined, ExpandLessOutlined } from '@mui/icons-material';
import Slide from '@mui/material/Slide';
import { interval } from 'rxjs';
import { Field, Form, Formik } from 'formik';
import DialogTitle from '@mui/material/DialogTitle';
import { includes } from 'ramda';
import MenuItem from '@mui/material/MenuItem';
import * as Yup from 'yup';
import inject18n from '../../../../components/i18n';
import { truncate } from '../../../../utils/String';
import { commitMutation } from '../../../../relay/environment';
import { commitMutation, MESSAGING$ } from '../../../../relay/environment';
import AddExternalReferences from './AddExternalReferences';
import { externalReferenceMutationRelationDelete } from './AddExternalReferencesLines';
import Security, {
Expand All @@ -35,6 +40,11 @@ import FileLine from '../../common/files/FileLine';
import { FIVE_SECONDS } from '../../../../utils/Time';
import FileUploader from '../../common/files/FileUploader';
import ExternalReferencePopover from './ExternalReferencePopover';
import SelectField from '../../../../components/SelectField';
import {
scopesConn,
stixCoreObjectFilesAndHistoryAskJobImportMutation,
} from '../../common/stix_core_objects/StixCoreObjectFilesAndHistory';

const interval$ = interval(FIVE_SECONDS);

Expand Down Expand Up @@ -88,6 +98,10 @@ const Transition = React.forwardRef((props, ref) => (
));
Transition.displayName = 'TransitionSlide';

const importValidation = (t) => Yup.object().shape({
connector_id: Yup.string().required(t('This field is required')),
});

class StixCoreObjectExternalReferencesLinesContainer extends Component {
constructor(props) {
super(props);
Expand All @@ -98,6 +112,7 @@ class StixCoreObjectExternalReferencesLinesContainer extends Component {
removeExternalReference: null,
removing: false,
expanded: false,
fileToImport: null,
};
}

Expand Down Expand Up @@ -172,13 +187,43 @@ class StixCoreObjectExternalReferencesLinesContainer extends Component {
});
}

handleOpenImport(file) {
this.setState({ fileToImport: file });
}

handleCloseImport() {
this.setState({ fileToImport: null });
}

onSubmitImport(values, { setSubmitting, resetForm }) {
const { stixCoreObjectId } = this.props;
const { fileToImport } = this.state;
commitMutation({
mutation: stixCoreObjectFilesAndHistoryAskJobImportMutation,
variables: {
fileName: fileToImport.id,
connectorId: values.connector_id,
bypassEntityId: stixCoreObjectId,
},
onCompleted: () => {
setSubmitting(false);
resetForm();
this.handleCloseImport();
MESSAGING$.notifySuccess('Import successfully asked');
},
});
}

render() {
const { t, classes, stixCoreObjectId, data } = this.props;
const { expanded } = this.state;
const { expanded, fileToImport } = this.state;
const externalReferencesEdges = data && data.stixCoreObject
? data.stixCoreObject.externalReferences.edges
: [];
const expandable = externalReferencesEdges.length > 7;
const importConnsPerFormat = data.connectorsForImport
? scopesConn(data.connectorsForImport || [])
: {};
return (
<div style={{ height: '100%' }}>
<Typography variant="h4" gutterBottom={true} style={{ float: 'left' }}>
Expand Down Expand Up @@ -272,9 +317,17 @@ class StixCoreObjectExternalReferencesLinesContainer extends Component {
<FileLine
key={file.node.id}
dense={true}
disableImport={true}
file={file.node}
nested={true}
workNested={true}
connectors={
importConnsPerFormat[
file.node.metaData.mimetype
]
}
handleOpenImport={this.handleOpenImport.bind(
this,
)}
/>
))}
</List>
Expand Down Expand Up @@ -425,6 +478,67 @@ class StixCoreObjectExternalReferencesLinesContainer extends Component {
</Button>
</DialogActions>
</Dialog>
<Formik
enableReinitialize={true}
initialValues={{ connector_id: '' }}
validationSchema={importValidation(t)}
onSubmit={this.onSubmitImport.bind(this)}
onReset={this.handleCloseImport.bind(this)}
>
{({ submitForm, handleReset, isSubmitting }) => (
<Form style={{ margin: '0 0 20px 0' }}>
<Dialog
PaperProps={{ elevation: 1 }}
open={fileToImport}
keepMounted={true}
onClose={this.handleCloseImport.bind(this)}
fullWidth={true}
>
<DialogTitle>{t('Launch an import')}</DialogTitle>
<DialogContent>
<Field
component={SelectField}
variant="standard"
name="connector_id"
label={t('Connector')}
fullWidth={true}
containerstyle={{ width: '100%' }}
>
{data.connectorsForImport.map((connector, i) => {
const disabled = !fileToImport
|| (connector.connector_scope.length > 0
&& !includes(
fileToImport.metaData.mimetype,
connector.connector_scope,
));
return (
<MenuItem
key={i}
value={connector.id}
disabled={disabled || !connector.active}
>
{connector.name}
</MenuItem>
);
})}
</Field>
</DialogContent>
<DialogActions>
<Button onClick={handleReset} disabled={isSubmitting}>
{t('Cancel')}
</Button>
<Button
color="secondary"
onClick={submitForm}
disabled={isSubmitting}
>
{t('Create')}
</Button>
</DialogActions>
</Dialog>
</Form>
)}
</Formik>
</div>
);
}
Expand Down Expand Up @@ -508,6 +622,13 @@ const StixCoreObjectExternalReferencesLines = createPaginationContainer(
}
}
}
connectorsForImport {
id
name
active
connector_scope
updated_at
}
}
`,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class FileLineComponent extends Component {
directDownload,
handleOpenImport,
nested,
workNested,
} = this.props;
const { lastModifiedSinceMin, uploadStatus, metaData } = file;
const { messages, errors } = metaData;
Expand Down Expand Up @@ -266,7 +267,7 @@ class FileLineComponent extends Component {
)}
</ListItemSecondaryAction>
</ListItem>
<FileWork file={file} />
<FileWork file={file} nested={workNested} />
<Dialog
open={this.state.displayDelete}
PaperProps={{ elevation: 1 }}
Expand Down Expand Up @@ -339,6 +340,7 @@ FileLineComponent.propTypes = {
directDownload: PropTypes.bool,
handleOpenImport: PropTypes.func,
nested: PropTypes.bool,
workNested: PropTypes.bool,
};

const FileLine = createFragmentContainer(FileLineComponent, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ const styles = (theme) => ({
nested: {
paddingLeft: theme.spacing(4),
},
nestedNested: {
paddingLeft: theme.spacing(8),
},
tooltip: {
maxWidth: 600,
},
Expand All @@ -55,6 +58,7 @@ const FileWorkComponent = (props) => {
nsdt,
classes,
file: { works },
nested,
} = props;
const [deleting, setDeleting] = useState(false);
const [displayDelete, setDisplayDelete] = useState(null);
Expand Down Expand Up @@ -129,7 +133,7 @@ const FileWorkComponent = (props) => {
dense={true}
button={true}
divider={true}
classes={{ root: classes.nested }}
classes={{ root: nested ? classes.nestedNested : classes.nested }}
disabled={work.status === 'deleting'}
>
<ListItemIcon>
Expand Down Expand Up @@ -208,6 +212,7 @@ FileWorkComponent.propTypes = {
classes: PropTypes.object,
file: PropTypes.object.isRequired,
nsdt: PropTypes.func,
nested: PropTypes.bool,
};

const FileWork = createFragmentContainer(FileWorkComponent, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,69 +245,67 @@ const StixCoreObjectFilesAndHistory = ({
withoutRelations={withoutRelations}
/>
</div>
<div>
<Formik
enableReinitialize={true}
initialValues={{ connector_id: '' }}
validationSchema={importValidation(t)}
onSubmit={onSubmitImport}
onReset={handleCloseImport}
>
{({ submitForm, handleReset, isSubmitting }) => (
<Form style={{ margin: '0 0 20px 0' }}>
<Dialog
PaperProps={{ elevation: 1 }}
open={fileToImport}
keepMounted={true}
onClose={handleCloseImport}
fullWidth={true}
>
<DialogTitle>{t('Launch an import')}</DialogTitle>
<DialogContent>
<Field
component={SelectField}
variant="standard"
name="connector_id"
label={t('Connector')}
fullWidth={true}
containerstyle={{ width: '100%' }}
>
{connectorsImport.map((connector, i) => {
const disabled = !fileToImport
|| (connector.connector_scope.length > 0
&& !includes(
fileToImport.metaData.mimetype,
connector.connector_scope,
));
return (
<MenuItem
key={i}
value={connector.id}
disabled={disabled || !connector.active}
>
{connector.name}
</MenuItem>
);
})}
</Field>
</DialogContent>
<DialogActions>
<Button onClick={handleReset} disabled={isSubmitting}>
{t('Cancel')}
</Button>
<Button
color="secondary"
onClick={submitForm}
disabled={isSubmitting}
>
{t('Create')}
</Button>
</DialogActions>
</Dialog>
</Form>
)}
</Formik>
</div>
<Formik
enableReinitialize={true}
initialValues={{ connector_id: '' }}
validationSchema={importValidation(t)}
onSubmit={onSubmitImport}
onReset={handleCloseImport}
>
{({ submitForm, handleReset, isSubmitting }) => (
<Form style={{ margin: '0 0 20px 0' }}>
<Dialog
PaperProps={{ elevation: 1 }}
open={fileToImport}
keepMounted={true}
onClose={handleCloseImport}
fullWidth={true}
>
<DialogTitle>{t('Launch an import')}</DialogTitle>
<DialogContent>
<Field
component={SelectField}
variant="standard"
name="connector_id"
label={t('Connector')}
fullWidth={true}
containerstyle={{ width: '100%' }}
>
{connectorsImport.map((connector, i) => {
const disabled = !fileToImport
|| (connector.connector_scope.length > 0
&& !includes(
fileToImport.metaData.mimetype,
connector.connector_scope,
));
return (
<MenuItem
key={i}
value={connector.id}
disabled={disabled || !connector.active}
>
{connector.name}
</MenuItem>
);
})}
</Field>
</DialogContent>
<DialogActions>
<Button onClick={handleReset} disabled={isSubmitting}>
{t('Cancel')}
</Button>
<Button
color="secondary"
onClick={submitForm}
disabled={isSubmitting}
>
{t('Create')}
</Button>
</DialogActions>
</Dialog>
</Form>
)}
</Formik>
<div>
<Formik
enableReinitialize={true}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ export const upload = async (user, path, fileUpload, meta = {}) => {
uploadStatus: 'complete'
};
// Trigger a enrich job for import file if needed
if (path.startsWith('import/') && !path.startsWith('import/pending')) {
if (path.startsWith('import/') && !path.startsWith('import/pending') && !path.startsWith('import/External-Reference')) {
await uploadJobImport(user, file.id, file.metaData.mimetype, file.metaData.entity_id);
}
return file;
Expand Down
Loading

0 comments on commit fa126c5

Please sign in to comment.