Skip to content

Commit d4aa1e0

Browse files
committed
Fix "show in dependency graph" yielding a 403 error
This was a regression introduced via #658. Because the dependency graph is not rendered conditionally, depending on whether a project is a collection or not, there was now a race condition in the code that auto-selected the graph tab. Fixes #1160 Signed-off-by: nscuro <[email protected]>
1 parent 073af18 commit d4aa1e0

File tree

2 files changed

+131
-131
lines changed

2 files changed

+131
-131
lines changed

src/views/portfolio/projects/Project.vue

Lines changed: 52 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
</ol>
7373
{{ project.version }}
7474
<i
75-
v-if="isCollectionProject()"
75+
v-if="isCollectionProject"
7676
class="fa fa-calculator fa-fw collectionlogic-icon"
7777
v-b-tooltip.hover="{
7878
title: getCollectionLogicText(project),
@@ -233,7 +233,7 @@
233233
<b-tab
234234
ref="components"
235235
@click="routeTo('components')"
236-
v-if="isShowComponents()"
236+
v-if="isShowComponents"
237237
>
238238
<template v-slot:title
239239
><i class="fa fa-cubes"></i> {{ $t('message.components') }}
@@ -249,7 +249,7 @@
249249
<b-tab
250250
ref="collectionprojects"
251251
@click="routeTo('collectionprojects')"
252-
v-if="isShowCollectionProjects()"
252+
v-if="isShowCollectionProjects"
253253
lazy
254254
>
255255
<template v-slot:title
@@ -262,11 +262,7 @@
262262
:project="this.project"
263263
/>
264264
</b-tab>
265-
<b-tab
266-
ref="services"
267-
@click="routeTo('services')"
268-
v-if="isShowServices()"
269-
>
265+
<b-tab ref="services" @click="routeTo('services')" v-if="isShowServices">
270266
<template v-slot:title
271267
><i class="fa fa-exchange"></i> {{ $t('message.services') }}
272268
<b-badge variant="tab-total">{{ totalServices }}</b-badge></template
@@ -280,7 +276,7 @@
280276
<b-tab
281277
ref="dependencygraph"
282278
@click="routeTo('dependencyGraph')"
283-
v-if="isShowDependencyGraph()"
279+
v-if="isShowDependencyGraph"
284280
>
285281
<template v-slot:title
286282
><i class="fa fa-sitemap"></i> {{ $t('message.dependency_graph') }}
@@ -295,11 +291,7 @@
295291
v-on:total="totalDependencyGraphs = $event"
296292
/>
297293
</b-tab>
298-
<b-tab
299-
ref="findings"
300-
v-if="isShowFindings()"
301-
@click="routeTo('findings')"
302-
>
294+
<b-tab ref="findings" v-if="isShowFindings" @click="routeTo('findings')">
303295
<template v-slot:title>
304296
<i class="fa fa-tasks"></i> {{ $t('message.audit_vulnerabilities') }}
305297
<b-badge
@@ -321,7 +313,7 @@
321313
v-on:total="totalFindingsIncludingAliases = $event"
322314
/>
323315
</b-tab>
324-
<b-tab ref="epss" v-if="isShowFindings()" @click="routeTo('epss')">
316+
<b-tab ref="epss" v-if="isShowFindings" @click="routeTo('epss')">
325317
<template v-slot:title
326318
><i class="fa fa-tasks"></i> {{ $t('message.exploit_predictions') }}
327319
<b-badge variant="tab-total">{{ totalEpss }}</b-badge></template
@@ -334,7 +326,7 @@
334326
</b-tab>
335327
<b-tab
336328
ref="policyviolations"
337-
v-if="isShowPolicyViolations()"
329+
v-if="isShowPolicyViolations"
338330
@click="routeTo('policyViolations')"
339331
>
340332
<template v-slot:title
@@ -461,6 +453,33 @@ export default {
461453
inactiveProjectVersions() {
462454
return this.project.versions.filter((version) => !version.active);
463455
},
456+
isCollectionProject() {
457+
return this.project.collectionLogic !== 'NONE';
458+
},
459+
isShowComponents() {
460+
return !this.isCollectionProject;
461+
},
462+
isShowCollectionProjects() {
463+
return this.isCollectionProject;
464+
},
465+
isShowServices() {
466+
return !this.isCollectionProject;
467+
},
468+
isShowDependencyGraph() {
469+
return !this.isCollectionProject;
470+
},
471+
isShowFindings() {
472+
return (
473+
!this.isCollectionProject &&
474+
this.isPermitted(this.PERMISSIONS.VIEW_VULNERABILITY)
475+
);
476+
},
477+
isShowPolicyViolations() {
478+
return (
479+
!this.isCollectionProject &&
480+
this.isPermitted(this.PERMISSIONS.VIEW_POLICY_VIOLATION)
481+
);
482+
},
464483
},
465484
data() {
466485
return {
@@ -514,7 +533,7 @@ export default {
514533
},
515534
initialize: function () {
516535
let projectUrl = `${this.$api.BASE_URL}/${this.$api.URL_PROJECT}/${this.uuid}`;
517-
this.axios
536+
return this.axios
518537
.get(projectUrl)
519538
.catch((error) => {
520539
if (error.response.status === 403) {
@@ -642,50 +661,25 @@ export default {
642661
}
643662
return '';
644663
},
645-
isCollectionProject: function () {
646-
return this.project.collectionLogic !== 'NONE';
647-
},
648-
isShowComponents: function () {
649-
return !this.isCollectionProject();
650-
},
651-
isShowCollectionProjects: function () {
652-
return this.isCollectionProject();
653-
},
654-
isShowServices: function () {
655-
return !this.isCollectionProject();
656-
},
657-
isShowDependencyGraph: function () {
658-
return !this.isCollectionProject();
659-
},
660-
isShowFindings: function () {
661-
return (
662-
!this.isCollectionProject() &&
663-
this.isPermitted(this.PERMISSIONS.VIEW_VULNERABILITY)
664-
);
665-
},
666-
isShowPolicyViolations: function () {
667-
return (
668-
!this.isCollectionProject() &&
669-
this.isPermitted(this.PERMISSIONS.VIEW_POLICY_VIOLATION)
670-
);
671-
},
672664
},
673665
beforeMount() {
674666
this.uuid = this.$route.params.uuid;
675-
this.initialize();
676-
},
677-
mounted() {
678-
try {
679-
if (this.$route.params.componentUuids) {
680-
this.$refs.dependencygraph.active = true;
681-
} else {
682-
this.getTabFromRoute().active = true;
683-
}
684-
} catch (e) {
685-
this.$toastr.e(this.$t('condition.forbidden'));
686-
this.$router.replace({ path: '/projects/' + this.uuid });
687-
this.$refs.overview.active = true;
688-
}
667+
this.initialize()
668+
.then(() => {
669+
this.$nextTick(() => {
670+
if (this.$route.params.componentUuids) {
671+
this.$refs.dependencygraph.active = true;
672+
} else {
673+
this.getTabFromRoute().active = true;
674+
}
675+
});
676+
})
677+
.catch((e) => {
678+
console.error(e);
679+
this.$toastr.e(this.$t('condition.forbidden'));
680+
this.$router.replace({ path: '/projects/' + this.uuid });
681+
this.$refs.overview.active = true;
682+
});
689683
},
690684
watch: {
691685
$route(to, from) {

src/views/portfolio/projects/ProjectDependencyGraph.vue

Lines changed: 79 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ export default {
9090
'true'
9191
: false;
9292
},
93+
mounted() {
94+
this.computeData();
95+
},
9396
data() {
9497
return {
9598
data: {},
@@ -111,7 +114,82 @@ export default {
111114
};
112115
},
113116
watch: {
114-
project: async function (newVal, oldVal) {
117+
project: function () {
118+
this.computeData();
119+
},
120+
showCompleteGraph: function () {
121+
if (this.$route.params.componentUuids && localStorage) {
122+
localStorage.setItem(
123+
'ProjectDependencyGraphShowCompleteGraph',
124+
this.showCompleteGraph.toString(),
125+
);
126+
}
127+
if (this.showCompleteGraph) {
128+
this.data = {
129+
id: this.nodeId,
130+
label: this.createNodeLabel(this.project),
131+
objectType: 'PROJECT',
132+
children: this.transformDependenciesToOrgTreeWithSearchedDependency(
133+
this.response.data,
134+
{ gatheredKeys: [] },
135+
false,
136+
),
137+
fetchedChildren: true,
138+
expand: !!this.$route.params.componentUuids,
139+
};
140+
if (this.$route.params.componentUuids) {
141+
new Promise((resolve) => setTimeout(resolve, 50)).then(() => {
142+
document.getElementsByClassName('searched').item(0).scrollIntoView({
143+
behavior: 'smooth',
144+
inline: 'center',
145+
block: 'center',
146+
});
147+
});
148+
}
149+
} else {
150+
this.data = {
151+
id: this.nodeId,
152+
label: this.createNodeLabel(this.project),
153+
objectType: 'PROJECT',
154+
children: this.transformDependenciesToOrgTreeWithSearchedDependency(
155+
this.response.data,
156+
{ gatheredKeys: [] },
157+
true,
158+
),
159+
fetchedChildren: true,
160+
expand: true,
161+
};
162+
}
163+
},
164+
highlightOutdatedComponents: function () {
165+
if (localStorage) {
166+
localStorage.setItem(
167+
'ProjectDependencyGraphHighlightOutdatedComponents',
168+
this.highlightOutdatedComponents.toString(),
169+
);
170+
}
171+
},
172+
$route: function (to, from) {
173+
if (!to.params.componentUuids && from.params.componentUuids) {
174+
this.showCompleteGraph = true;
175+
this.collapse(this.data.children);
176+
this.data.expand = false;
177+
} else if (to.params.componentUuids && !from.params.componentUuids) {
178+
this.showCompleteGraph =
179+
localStorage &&
180+
localStorage.getItem('ProjectDependencyGraphShowCompleteGraph') !==
181+
null
182+
? localStorage.getItem(
183+
'ProjectDependencyGraphShowCompleteGraph',
184+
) === 'true'
185+
: false;
186+
}
187+
// build map of searched components for later fast lookup
188+
this.createSearchedComponentLookupTable(to.params.componentUuids);
189+
},
190+
},
191+
methods: {
192+
computeData: function () {
115193
// prepare base object
116194
const data = {
117195
id: this.nodeId,
@@ -198,78 +276,6 @@ export default {
198276
}
199277
});
200278
},
201-
showCompleteGraph: function () {
202-
if (this.$route.params.componentUuids && localStorage) {
203-
localStorage.setItem(
204-
'ProjectDependencyGraphShowCompleteGraph',
205-
this.showCompleteGraph.toString(),
206-
);
207-
}
208-
if (this.showCompleteGraph) {
209-
this.data = {
210-
id: this.nodeId,
211-
label: this.createNodeLabel(this.project),
212-
objectType: 'PROJECT',
213-
children: this.transformDependenciesToOrgTreeWithSearchedDependency(
214-
this.response.data,
215-
{ gatheredKeys: [] },
216-
false,
217-
),
218-
fetchedChildren: true,
219-
expand: !!this.$route.params.componentUuids,
220-
};
221-
if (this.$route.params.componentUuids) {
222-
new Promise((resolve) => setTimeout(resolve, 50)).then(() => {
223-
document.getElementsByClassName('searched').item(0).scrollIntoView({
224-
behavior: 'smooth',
225-
inline: 'center',
226-
block: 'center',
227-
});
228-
});
229-
}
230-
} else {
231-
this.data = {
232-
id: this.nodeId,
233-
label: this.createNodeLabel(this.project),
234-
objectType: 'PROJECT',
235-
children: this.transformDependenciesToOrgTreeWithSearchedDependency(
236-
this.response.data,
237-
{ gatheredKeys: [] },
238-
true,
239-
),
240-
fetchedChildren: true,
241-
expand: true,
242-
};
243-
}
244-
},
245-
highlightOutdatedComponents: function () {
246-
if (localStorage) {
247-
localStorage.setItem(
248-
'ProjectDependencyGraphHighlightOutdatedComponents',
249-
this.highlightOutdatedComponents.toString(),
250-
);
251-
}
252-
},
253-
$route: function (to, from) {
254-
if (!to.params.componentUuids && from.params.componentUuids) {
255-
this.showCompleteGraph = true;
256-
this.collapse(this.data.children);
257-
this.data.expand = false;
258-
} else if (to.params.componentUuids && !from.params.componentUuids) {
259-
this.showCompleteGraph =
260-
localStorage &&
261-
localStorage.getItem('ProjectDependencyGraphShowCompleteGraph') !==
262-
null
263-
? localStorage.getItem(
264-
'ProjectDependencyGraphShowCompleteGraph',
265-
) === 'true'
266-
: false;
267-
}
268-
// build map of searched components for later fast lookup
269-
this.createSearchedComponentLookupTable(to.params.componentUuids);
270-
},
271-
},
272-
methods: {
273279
mouseDownHandler: function (event) {
274280
if (
275281
event.button === 0 &&

0 commit comments

Comments
 (0)