Skip to content

Commit 54fffba

Browse files
stefan1anubySarahBocognano
authored andcommitted
[frontend] added 'vulnerabilities' view in the knowledge bar of a system (OpenCTI-Platform#8498)
1 parent 90418a9 commit 54fffba

File tree

2 files changed

+346
-0
lines changed

2 files changed

+346
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
import React, { Component } from 'react';
2+
import * as PropTypes from 'prop-types';
3+
import { Route, Routes, Link, Navigate } from 'react-router-dom';
4+
import { graphql } from 'react-relay';
5+
import { propOr } from 'ramda';
6+
import * as R from 'ramda';
7+
import Box from '@mui/material/Box';
8+
import Tabs from '@mui/material/Tabs';
9+
import Tab from '@mui/material/Tab';
10+
import StixCoreObjectContentRoot from '../../common/stix_core_objects/StixCoreObjectContentRoot';
11+
import withRouter from '../../../../utils/compat_router/withRouter';
12+
import { QueryRenderer, requestSubscription } from '../../../../relay/environment';
13+
import System from './System';
14+
import SystemKnowledge from './SystemKnowledge';
15+
import StixDomainObjectHeader from '../../common/stix_domain_objects/StixDomainObjectHeader';
16+
import FileManager from '../../common/files/FileManager';
17+
import SystemPopover from './SystemPopover';
18+
import Loader from '../../../../components/Loader';
19+
import StixCoreObjectHistory from '../../common/stix_core_objects/StixCoreObjectHistory';
20+
import SystemAnalysis from './SystemAnalysis';
21+
import ErrorNotFound from '../../../../components/ErrorNotFound';
22+
import { buildViewParamsFromUrlAndStorage, saveViewParameters } from '../../../../utils/ListParameters';
23+
import StixCoreObjectKnowledgeBar from '../../common/stix_core_objects/StixCoreObjectKnowledgeBar';
24+
import EntityStixSightingRelationships from '../../events/stix_sighting_relationships/EntityStixSightingRelationships';
25+
import inject18n from '../../../../components/i18n';
26+
import Breadcrumbs from '../../../../components/Breadcrumbs';
27+
import { getCurrentTab, getPaddingRight } from '../../../../utils/utils';
28+
import Security from '../../../../utils/Security';
29+
import { KNOWLEDGE_KNUPDATE } from '../../../../utils/hooks/useGranted';
30+
import SystemEdition from './SystemEdition';
31+
32+
const subscription = graphql`
33+
subscription RootSystemsSubscription($id: ID!) {
34+
stixDomainObject(id: $id) {
35+
... on System {
36+
...System_system
37+
...SystemEditionContainer_system
38+
}
39+
...FileImportViewer_entity
40+
...FileExportViewer_entity
41+
...FileExternalReferencesViewer_entity
42+
...WorkbenchFileViewer_entity
43+
}
44+
}
45+
`;
46+
47+
const systemQuery = graphql`
48+
query RootSystemQuery($id: String!) {
49+
system(id: $id) {
50+
id
51+
entity_type
52+
name
53+
x_opencti_aliases
54+
stixCoreObjectsDistribution(field: "entity_type", operation: count) {
55+
label
56+
value
57+
}
58+
...System_system
59+
...SystemKnowledge_system
60+
...FileImportViewer_entity
61+
...FileExportViewer_entity
62+
...FileExternalReferencesViewer_entity
63+
...WorkbenchFileViewer_entity
64+
...StixCoreObjectContent_stixCoreObject
65+
}
66+
connectorsForImport {
67+
...FileManager_connectorsImport
68+
}
69+
connectorsForExport {
70+
...FileManager_connectorsExport
71+
}
72+
}
73+
`;
74+
75+
class RootSystem extends Component {
76+
constructor(props) {
77+
super(props);
78+
const {
79+
params: { systemId },
80+
} = props;
81+
const LOCAL_STORAGE_KEY = `system-${systemId}`;
82+
const params = buildViewParamsFromUrlAndStorage(
83+
props.navigate,
84+
props.location,
85+
LOCAL_STORAGE_KEY,
86+
);
87+
this.state = {
88+
viewAs: propOr('knowledge', 'viewAs', params),
89+
};
90+
this.sub = requestSubscription({
91+
subscription,
92+
variables: { id: systemId },
93+
});
94+
}
95+
96+
componentWillUnmount() {
97+
this.sub.dispose();
98+
}
99+
100+
saveView() {
101+
const {
102+
params: { systemId },
103+
} = this.props;
104+
const LOCAL_STORAGE_KEY = `system-${systemId}`;
105+
saveViewParameters(
106+
this.props.navigate,
107+
this.props.location,
108+
LOCAL_STORAGE_KEY,
109+
this.state,
110+
true,
111+
);
112+
}
113+
114+
handleChangeViewAs(event) {
115+
this.setState({ viewAs: event.target.value }, () => this.saveView());
116+
}
117+
118+
render() {
119+
const {
120+
t,
121+
location,
122+
params: { systemId },
123+
} = this.props;
124+
const { viewAs } = this.state;
125+
const link = `/dashboard/entities/systems/${systemId}/knowledge`;
126+
127+
return (
128+
<>
129+
<QueryRenderer
130+
query={systemQuery}
131+
variables={{ id: systemId }}
132+
render={({ props }) => {
133+
if (props) {
134+
if (props.system) {
135+
const { system } = props;
136+
const paddingRight = getPaddingRight(location.pathname, system.id, '/dashboard/entities/systems');
137+
return (
138+
<>
139+
<Routes>
140+
<Route
141+
path="/knowledge/*"
142+
element={viewAs === 'knowledge' && (
143+
<StixCoreObjectKnowledgeBar
144+
stixCoreObjectLink={link}
145+
availableSections={[
146+
'systems',
147+
'systems',
148+
'threats',
149+
'threat_actors',
150+
'intrusion_sets',
151+
'campaigns',
152+
'incidents',
153+
'malwares',
154+
'attack_patterns',
155+
'tools',
156+
'observables',
157+
'vulnerabilities',
158+
]}
159+
stixCoreObjectsDistribution={system.stixCoreObjectsDistribution}
160+
/>
161+
)}
162+
/>
163+
</Routes>
164+
<div style={{ paddingRight }}>
165+
<Breadcrumbs variant="object" elements={[
166+
{ label: t('Entities') },
167+
{ label: t('Systems'), link: '/dashboard/entities/systems' },
168+
{ label: system.name, current: true },
169+
]}
170+
/>
171+
<StixDomainObjectHeader
172+
entityType="System"
173+
stixDomainObject={system}
174+
isOpenctiAlias={true}
175+
enableQuickSubscription={true}
176+
PopoverComponent={<SystemPopover />}
177+
EditComponent={(
178+
<Security needs={[KNOWLEDGE_KNUPDATE]}>
179+
<SystemEdition systemId={system.id} />
180+
</Security>
181+
)}
182+
onViewAs={this.handleChangeViewAs.bind(this)}
183+
viewAs={viewAs}
184+
/>
185+
<Box
186+
sx={{
187+
borderBottom: 1,
188+
borderColor: 'divider',
189+
marginBottom: 3,
190+
}}
191+
>
192+
<Tabs
193+
value={getCurrentTab(location.pathname, system.id, '/dashboard/entities/systems')}
194+
>
195+
<Tab
196+
component={Link}
197+
to={`/dashboard/entities/systems/${system.id}`}
198+
value={`/dashboard/entities/systems/${system.id}`}
199+
label={t('Overview')}
200+
/>
201+
<Tab
202+
component={Link}
203+
to={`/dashboard/entities/systems/${system.id}/knowledge/overview`}
204+
value={`/dashboard/entities/systems/${system.id}/knowledge`}
205+
label={t('Knowledge')}
206+
/>
207+
<Tab
208+
component={Link}
209+
to={`/dashboard/entities/systems/${system.id}/content`}
210+
value={`/dashboard/entities/systems/${system.id}/content`}
211+
label={t('Content')}
212+
/>
213+
<Tab
214+
component={Link}
215+
to={`/dashboard/entities/systems/${system.id}/analyses`}
216+
value={`/dashboard/entities/systems/${system.id}/analyses`}
217+
label={t('Analyses')}
218+
/>
219+
<Tab
220+
component={Link}
221+
to={`/dashboard/entities/systems/${system.id}/sightings`}
222+
value={`/dashboard/entities/systems/${system.id}/sightings`}
223+
label={t('Sightings')}
224+
/>
225+
<Tab
226+
component={Link}
227+
to={`/dashboard/entities/systems/${system.id}/files`}
228+
value={`/dashboard/entities/systems/${system.id}/files`}
229+
label={t('Data')}
230+
/>
231+
<Tab
232+
component={Link}
233+
to={`/dashboard/entities/systems/${system.id}/history`}
234+
value={`/dashboard/entities/systems/${system.id}/history`}
235+
label={t('History')}
236+
/>
237+
</Tabs>
238+
</Box>
239+
<Routes>
240+
<Route
241+
path="/"
242+
element={
243+
<System
244+
systemData={system}
245+
viewAs={viewAs}
246+
/>
247+
}
248+
/>
249+
<Route
250+
path="/knowledge"
251+
element={
252+
<Navigate
253+
replace={true}
254+
to={`/dashboard/entities/systems/${systemId}/knowledge/overview`}
255+
/>
256+
}
257+
/>
258+
<Route
259+
path="/knowledge/*"
260+
element={
261+
<SystemKnowledge
262+
system={system}
263+
viewAs={viewAs}
264+
/>
265+
}
266+
/>
267+
<Route
268+
path="/content/*"
269+
element={
270+
<StixCoreObjectContentRoot
271+
stixCoreObject={system}
272+
/>
273+
}
274+
/>
275+
<Route
276+
path="/analyses/*"
277+
element={
278+
<SystemAnalysis
279+
system={system}
280+
viewAs={viewAs}
281+
/>
282+
}
283+
/>
284+
<Route
285+
path="/sightings"
286+
element={
287+
<EntityStixSightingRelationships
288+
entityId={system.id}
289+
entityLink={link}
290+
noPadding={true}
291+
isTo={true}
292+
/>
293+
}
294+
/>
295+
<Route
296+
path="/files"
297+
element={
298+
<FileManager
299+
id={systemId}
300+
connectorsImport={props.connectorsForImport}
301+
connectorsExport={props.connectorsForExport}
302+
entity={system}
303+
/>
304+
}
305+
/>
306+
<Route
307+
path="/history"
308+
element={
309+
<StixCoreObjectHistory
310+
stixCoreObjectId={systemId}
311+
/>
312+
}
313+
/>
314+
</Routes>
315+
</div>
316+
</>
317+
);
318+
}
319+
return <ErrorNotFound />;
320+
}
321+
return <Loader />;
322+
}}
323+
/>
324+
</>
325+
);
326+
}
327+
}
328+
329+
RootSystem.propTypes = {
330+
children: PropTypes.node,
331+
params: PropTypes.object,
332+
};
333+
334+
export default R.compose(inject18n, withRouter)(RootSystem);

opencti-platform/opencti-front/src/private/components/entities/systems/SystemKnowledge.jsx

+12
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,18 @@ class SystemKnowledgeComponent extends Component {
210210
/>
211211
}
212212
/>
213+
<Route
214+
path="/vulnerabilities"
215+
element={
216+
<EntityStixCoreRelationships
217+
entityId={system.id}
218+
relationshipTypes={['has']}
219+
stixCoreObjectTypes={['Vulnerability']}
220+
entityLink={link}
221+
isRelationReversed={false}
222+
/>
223+
}
224+
/>
213225
</Routes>
214226
</>
215227
);

0 commit comments

Comments
 (0)