Skip to content

Commit

Permalink
[back/front] Improve mandatory and enforce reference management (#1850)
Browse files Browse the repository at this point in the history
Co-authored-by: Romuald Lemesle <[email protected]>
  • Loading branch information
richard-julien and RomuDeuxfois authored Mar 2, 2023
1 parent 22171bf commit 3be52c8
Show file tree
Hide file tree
Showing 108 changed files with 792 additions and 1,025 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Omit<ItemOpenVocabProps, 'type'>
: { marginTop: 7 };
return (
<span className={classes.container}>
<pre style={preStyle}>{value}</pre>
<pre style={preStyle}>{t(value)}</pre>
<Tooltip title={t(description)}>
<InformationOutline
className={small ? classes.smallIcon : classes.icon}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import OpenVocabField from '../../common/form/OpenVocabField';
import { useFormatter } from '../../../../components/i18n';
import { insertNode } from '../../../../utils/store';
import { fieldSpacingContainerStyle } from '../../../../utils/field';
import { useYupSchemaBuilder } from '../../../../utils/hooks/useEntitySettings';
import { useSchemaCreationValidation } from '../../../../utils/hooks/useEntitySettings';

const useStyles = makeStyles((theme) => ({
drawerPaper: {
Expand Down Expand Up @@ -98,12 +98,12 @@ const GroupingCreation = ({ paginationOptions }) => {
const [open, setOpen] = useState(false);

const basicShape = {
name: Yup.string().required(t('This field is required')),
confidence: Yup.number(),
name: Yup.string().min(2).required(t('This field is required')),
confidence: Yup.number().nullable(),
context: Yup.string().required(t('This field is required')),
description: Yup.string().nullable(),
};
const groupingValidator = useYupSchemaBuilder('Grouping', basicShape);
const groupingValidator = useSchemaCreationValidation('Grouping', basicShape);

const onSubmit = (values, { setSubmitting, setErrors, resetForm }) => {
const adaptedValues = R.evolve(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { adaptFieldValue } from '../../../../utils/String';
import { convertCreatedBy, convertMarkings, convertStatus } from '../../../../utils/edition';
import OpenVocabField from '../../common/form/OpenVocabField';
import { fieldSpacingContainerStyle } from '../../../../utils/field';
import { useYupSchemaBuilder } from '../../../../utils/hooks/useEntitySettings';
import { useSchemaEditionValidation } from '../../../../utils/hooks/useEntitySettings';
import useFormEditor from '../../../../utils/hooks/useFormEditor';

export const groupingMutationFieldPatch = graphql`
Expand Down Expand Up @@ -84,14 +84,14 @@ const GroupingEditionOverviewComponent = (props) => {
const { t } = useFormatter();

const basicShape = {
name: Yup.string().required(t('This field is required')),
confidence: Yup.number(),
name: Yup.string().min(2).required(t('This field is required')),
confidence: Yup.number().nullable(),
context: Yup.string().required(t('This field is required')),
description: Yup.string().nullable(),
references: Yup.array(),
x_opencti_workflow_id: Yup.object(),
};
const groupingValidator = useYupSchemaBuilder('Grouping', basicShape);
const groupingValidator = useSchemaEditionValidation('Grouping', basicShape);

const queries = {
fieldPatch: groupingMutationFieldPatch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,8 @@ class AddNotes extends Component {
classes,
stixCoreObjectOrStixCoreRelationshipId,
stixCoreObjectOrStixCoreRelationshipNotes,
paginationOptions,
} = this.props;
const paginationOptions = {
search: this.state.search,
};
return (
<div>
<IconButton
Expand Down Expand Up @@ -141,13 +139,10 @@ class AddNotes extends Component {
if (props) {
return (
<AddNotesLines
stixCoreObjectOrStixCoreRelationshipId={
stixCoreObjectOrStixCoreRelationshipId
}
stixCoreObjectOrStixCoreRelationshipNotes={
stixCoreObjectOrStixCoreRelationshipNotes
}
stixCoreObjectOrStixCoreRelationshipId={stixCoreObjectOrStixCoreRelationshipId}
stixCoreObjectOrStixCoreRelationshipNotes={stixCoreObjectOrStixCoreRelationshipNotes}
data={props}
paginationOptions={paginationOptions}
/>
);
}
Expand Down Expand Up @@ -194,8 +189,7 @@ class AddNotes extends Component {
display={this.state.open}
contextual={true}
inputValue={this.state.search}
paginationOptions={paginationOptions}
/>
paginationOptions={{ search: this.state.search }} />
</div>
);
}
Expand All @@ -204,6 +198,7 @@ class AddNotes extends Component {
AddNotes.propTypes = {
stixCoreObjectOrStixCoreRelationshipId: PropTypes.string,
stixCoreObjectOrStixCoreRelationshipNotes: PropTypes.array,
paginationOptions: PropTypes.object,
classes: PropTypes.object,
t: PropTypes.func,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import React, { Component } from 'react';
import * as PropTypes from 'prop-types';
import * as R from 'ramda';
import { graphql, createPaginationContainer } from 'react-relay';
import { createPaginationContainer, graphql } from 'react-relay';
import withStyles from '@mui/styles/withStyles';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import { CheckCircle, WorkOutline } from '@mui/icons-material';
import { ConnectionHandler } from 'relay-runtime';
import { truncate } from '../../../../utils/String';
import inject18n from '../../../../components/i18n';
import { commitMutation } from '../../../../relay/environment';
import ItemMarkings from '../../../../components/ItemMarkings';
import { deleteNode, insertNode } from '../../../../utils/store';

const styles = (theme) => ({
avatar: {
Expand Down Expand Up @@ -54,17 +54,12 @@ export const noteMutationRelationDelete = graphql`
}
`;

const sharedUpdater = (store, entityId, newEdge) => {
const entity = store.get(entityId);
const conn = ConnectionHandler.getConnection(entity, 'Pagination_notes');
ConnectionHandler.insertEdgeBefore(conn, newEdge);
};

class AddNotesLinesContainer extends Component {
toggleNote(note) {
const {
stixCoreObjectOrStixCoreRelationshipId,
stixCoreObjectOrStixCoreRelationshipNotes,
paginationOptions,
} = this.props;
const entityNotesIds = R.map(
(n) => n.node.id,
Expand All @@ -86,12 +81,12 @@ class AddNotesLinesContainer extends Component {
relationship_type: 'object',
},
updater: (store) => {
const entity = store.get(stixCoreObjectOrStixCoreRelationshipId);
const conn = ConnectionHandler.getConnection(
entity,
deleteNode(
store,
'Pagination_notes',
paginationOptions,
existingNote.node.id,
);
ConnectionHandler.deleteNode(conn, note.id);
},
});
} else {
Expand All @@ -106,15 +101,16 @@ class AddNotesLinesContainer extends Component {
input,
},
updater: (store) => {
const payload = store
.getRootField('noteEdit')
.getLinkedRecord('relationAdd', { input });
const relationId = payload.getValue('id');
const node = payload.getLinkedRecord('from');
const relation = store.get(relationId);
payload.setLinkedRecord(node, 'node');
payload.setLinkedRecord(relation, 'relation');
sharedUpdater(store, stixCoreObjectOrStixCoreRelationshipId, payload);
insertNode(
store,
'Pagination_notes',
paginationOptions,
'noteEdit',
null,
'relationAdd',
input,
'from',
);
},
});
}
Expand Down Expand Up @@ -171,6 +167,7 @@ class AddNotesLinesContainer extends Component {
AddNotesLinesContainer.propTypes = {
stixCoreObjectOrStixCoreRelationshipId: PropTypes.string,
stixCoreObjectOrStixCoreRelationshipNotes: PropTypes.array,
paginationOptions: PropTypes.object,
data: PropTypes.object,
limit: PropTypes.number,
classes: PropTypes.object,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import NoteDetails from './NoteDetails';
import NoteEdition from './NoteEdition';
import StixDomainObjectOverview from '../../common/stix_domain_objects/StixDomainObjectOverview';
import StixCoreObjectExternalReferences from '../external_references/StixCoreObjectExternalReferences';
import Security, { CollaborativeSecurity } from '../../../../utils/Security';
import { CollaborativeSecurity } from '../../../../utils/Security';
import {
KNOWLEDGE_KNPARTICIPATE,
KNOWLEDGE_KNPARTICIPATE, KNOWLEDGE_KNUPDATE,
KNOWLEDGE_KNUPDATE_KNDELETE,
} from '../../../../utils/hooks/useGranted';
import StixCoreObjectLatestHistory from '../../common/stix_core_objects/StixCoreObjectLatestHistory';
Expand Down Expand Up @@ -74,22 +74,20 @@ class NoteComponent extends Component {
/>
</Grid>
</Grid>
<Grid
container={true}
<Grid container={true}
spacing={3}
classes={{ container: classes.gridContainer }}
style={{ marginTop: 25 }}
>
style={{ marginTop: 25 }}>
<Grid item={true} xs={6}>
<StixCoreObjectExternalReferences stixCoreObjectId={note.id} />
</Grid>
<Grid item={true} xs={6}>
<StixCoreObjectLatestHistory stixCoreObjectId={note.id} />
</Grid>
</Grid>
<Security needs={[KNOWLEDGE_KNPARTICIPATE]}>
<CollaborativeSecurity data={note} needs={[KNOWLEDGE_KNUPDATE]}>
<NoteEdition noteId={note.id} />
</Security>
</CollaborativeSecurity>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { Option } from '../../common/form/ReferenceField';
import { NotesLinesPaginationQuery$variables } from './__generated__/NotesLinesPaginationQuery.graphql';
import SliderField from '../../../../components/SliderField';
import { ExternalReferencesField } from '../../common/form/ExternalReferencesField';
import { useYupSchemaBuilder } from '../../../../utils/hooks/useEntitySettings';
import { useSchemaCreationValidation } from '../../../../utils/hooks/useEntitySettings';

const useStyles = makeStyles<Theme>((theme) => ({
drawerPaper: {
Expand Down Expand Up @@ -140,12 +140,13 @@ const NoteCreation: FunctionComponent<NoteCreationProps> = ({
.typeError(t('The value must be a datetime (yyyy-MM-dd hh:mm (a|p)m)'))
.required(t('This field is required')),
attribute_abstract: Yup.string().nullable(),
content: Yup.string().required(t('This field is required')),
confidence: Yup.number(),
note_types: Yup.array(),
content: Yup.string().min(2).required(t('This field is required')),
confidence: Yup.number().nullable(),
note_types: Yup.array().nullable(),
likelihood: Yup.number().min(0).max(100),
};
const noteValidator = useYupSchemaBuilder('Note', basicShape);
// createdBy must be excluded from the validation if user is not an editor, it will be handled directly by the backend
const noteValidator = useSchemaCreationValidation('Note', basicShape, userIsKnowledgeEditor ? [] : ['createdBy']);

const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import NoteEditionContainer from './NoteEditionContainer';
import { QueryRenderer } from '../../../../relay/environment';
import { noteEditionOverviewFocus } from './NoteEditionOverview';
import Loader, { LoaderVariant } from '../../../../components/Loader';
import useGranted, { KNOWLEDGE_KNUPDATE } from '../../../../utils/hooks/useGranted';
import useAuth from '../../../../utils/hooks/useAuth';
import { KNOWLEDGE_KNUPDATE } from '../../../../utils/hooks/useGranted';
import { Theme } from '../../../../components/Theme';
import { NoteEditionContainerQuery$data } from './__generated__/NoteEditionContainerQuery.graphql';
import { CollaborativeSecurity } from '../../../../utils/Security';

const useStyles = makeStyles<Theme>((theme) => ({
editButton: {
Expand Down Expand Up @@ -47,8 +47,6 @@ const NoteEdition = ({ noteId }: { noteId: string }) => {
const classes = useStyles();

const [open, setOpen] = useState(false);
const userIsKnowledgeEditor = useGranted([KNOWLEDGE_KNUPDATE]);
const { me } = useAuth();
const handleOpen = () => setOpen(true);

const [commit] = useMutation(noteEditionOverviewFocus);
Expand All @@ -65,31 +63,24 @@ const NoteEdition = ({ noteId }: { noteId: string }) => {

return (
<div>
<QueryRenderer
query={noteEditionQuery}
<QueryRenderer query={noteEditionQuery}
variables={{ id: noteId }}
render={({ props }: { props: NoteEditionContainerQuery$data }) => {
if (props && props.note) {
// Check is user has edition rights
if (!userIsKnowledgeEditor && me.individual_id !== props.note.createdBy?.id) {
return <></>;
}
return (
<>
<Fab onClick={handleOpen}
color="secondary"
aria-label="Edit"
className={classes.editButton}>
<Edit />
</Fab>
<Drawer open={open}
anchor="right"
elevation={1}
sx={{ zIndex: 1202 }}
classes={{ paper: classes.drawerPaper }}
onClose={handleClose}>
<NoteEditionContainer note={props.note} handleClose={handleClose} />
</Drawer></>
<CollaborativeSecurity data={props.note} needs={[KNOWLEDGE_KNUPDATE]}>
<>
<Fab onClick={handleOpen} color="secondary"
aria-label="Edit" className={classes.editButton}>
<Edit />
</Fab>
<Drawer open={open} anchor="right" elevation={1}
sx={{ zIndex: 1202 }} classes={{ paper: classes.drawerPaper }}
onClose={handleClose}>
<NoteEditionContainer note={props.note} handleClose={handleClose} />
</Drawer>
</>
</CollaborativeSecurity>
);
}
return <Loader variant={LoaderVariant.inElement} />;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { SubscriptionAvatars } from '../../../../components/Subscription';
import NoteEditionOverview from './NoteEditionOverview';
import { Theme } from '../../../../components/Theme';
import { NoteEditionContainer_note$data } from './__generated__/NoteEditionContainer_note.graphql';
import { useIsEnforceReference } from '../../../../utils/hooks/useEntitySettings';

const useStyles = makeStyles<Theme>((theme) => ({
header: {
Expand Down Expand Up @@ -70,10 +69,7 @@ const NoteEditionContainer: FunctionComponent<NoteEditionContainerProps> = ({ no
<div className="clearfix" />
</div>
<div className={classes.container}>
<NoteEditionOverview note={note}
context={editContext}
enableReferences={useIsEnforceReference('Note')}
handleClose={handleClose} />
<NoteEditionOverview note={note} context={editContext} handleClose={handleClose} />
</div>
</div>
);
Expand Down
Loading

0 comments on commit 3be52c8

Please sign in to comment.