Skip to content

Commit

Permalink
add technologies to advisories (#205)
Browse files Browse the repository at this point in the history
  • Loading branch information
blockisec authored Mar 27, 2024
1 parent 451beaf commit 4bfacca
Show file tree
Hide file tree
Showing 24 changed files with 319 additions and 137 deletions.
6 changes: 5 additions & 1 deletion frontend/src/components/advisories/TopProductsDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ export default {
.getTopProducts(this.$api)
.then((response) => {
response.data.forEach((item) => {
this.chartData.labels.push(item['product'] + ' (by ' + item['vendor_name'] + ')');
let name = item['technology__name'];
if (item['technology__vendor']) {
name = `${item['technology__name']} (by ${item['technology__vendor']})`;
}
this.chartData.labels.push(name);
this.chartData.datasets[0].data.push(item['count']);
});
for (let i = 0; i < this.chartColors.length; i++) {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/advisories/TopVendorsDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default {
.getTopVendors(this.$api)
.then((response) => {
response.data.forEach((item) => {
this.chartData.labels.push(item['vendor_name']);
this.chartData.labels.push(item['technology__vendor']);
this.chartData.datasets[0].data.push(item['count']);
});
const documentStyle = getComputedStyle(document.body);
Expand Down
26 changes: 7 additions & 19 deletions frontend/src/components/dialogs/FindingAsAdvisoryDialog.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script>
import FindingService from '@/service/FindingService';
import TechnologySelectField from "@/components/elements/forms/TechnologySelectField.vue";
export default {
name: 'FindingAsAdvisoryDialog',
Expand All @@ -11,10 +12,8 @@ export default {
findingId: this.$route.params.findingId,
loading: false,
model: {
product: null,
affected_versions: null,
vendor_name: null,
vendor_url: null
technology: null,
affected_versions: null
},
service: new FindingService()
};
Expand All @@ -29,11 +28,8 @@ export default {
create() {
this.loading = true;
let data = {
product: this.model.product,
affected_versions: this.model.affected_versions,
affected_product: this.model.affected_product,
vendor_name: this.model.vendor_name,
vendor_url: this.model.vendor_url
technology: this.model.technology,
affected_versions: this.model.affected_versions
};
this.service
.findingAsAdvisory(this.$api, this.projectId, this.findingId, data)
Expand All @@ -52,7 +48,7 @@ export default {
});
}
},
components: {}
components: { TechnologySelectField }
};
</script>

Expand All @@ -63,15 +59,7 @@ export default {
<div class="p-fluid formgrid grid">
<div class="field col-12">
<label for="product">Product</label>
<InputText id="product" v-model="model.product"></InputText>
</div>
<div class="field col-12 md:col-6">
<label for="vendor">Vendor</label>
<InputText id="vendor" v-model="model.vendor_name"></InputText>
</div>
<div class="field col-12 md:col-6">
<label for="vendor_url">Vendor-URL</label>
<InputText type="url" v-model="model.vendor_url"></InputText>
<TechnologySelectField v-model="model.technology"></TechnologySelectField>
</div>
<div class="field col-12">
<label for="versions">Affected Versions</label>
Expand Down
65 changes: 30 additions & 35 deletions frontend/src/components/elements/forms/AdvisoryLabelSelectField.vue
Original file line number Diff line number Diff line change
@@ -1,44 +1,39 @@
<script>
export default {
name: "AdvisoryLabelSelectField",
props: ["modelValue"],
emits: ["update:modelValue"],
mounted() {
this.loadData()
},
methods: {
change() {
this.$emit('update:modelValue', this.items)
name: 'AdvisoryLabelSelectField',
props: ['modelValue'],
emits: ['update:modelValue'],
mounted() {
this.loadData();
},
loadData() {
let url = "/advisory-management/labels/"
this.$api.get(url).then((response) => {
this.choices = response.data.results
this.items = []
this.modelValue.forEach((item) => {
// prefill with already selected items
this.items.push(item.pk)
})
})
}
},
data() {
return {
items: this.modelValue,
choices: []
methods: {
change() {
this.$emit('update:modelValue', this.items);
},
loadData() {
let url = '/advisory-management/labels/';
this.$api.get(url).then((response) => {
this.choices = response.data.results;
this.items = [];
this.modelValue.forEach((item) => {
// prefill with already selected items
this.items.push(item.pk);
});
});
}
},
data() {
return {
items: this.modelValue,
choices: []
};
}
}
}
};
</script>

<template>
<label for="labels">Labels</label>
<MultiSelect @change="change" id="labels" v-model="items"
:options="choices" optionLabel="name"
optionValue="pk">
</MultiSelect>
<label for="labels">Labels</label>
<MultiSelect @change="change" id="labels" v-model="items" :options="choices" optionLabel="name" optionValue="pk"> </MultiSelect>
</template>

<style scoped>
</style>
<style scoped></style>
75 changes: 75 additions & 0 deletions frontend/src/components/elements/forms/TechnologySelectField.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<script>
import TechnologyService from '@/service/TechnologyService';
export default {
name: 'TechnologySelectField',
props: ['modelValue'],
emits: ['update:modelValue', 'change'],
data() {
let model = this.modelValue;
if (this.modelValue && this.modelValue.pk) {
model = this.modelValue.pk;
}
return {
model: model,
choices: [],
loading: false,
loaded: false,
service: new TechnologyService()
};
},
methods: {
change() {
this.$emit('update:modelValue', this.model);
for (let i = 0; i < this.choices.length; i++) {
if (this.choices[i].pk === this.model) {
this.$emit('change', this.choices[i]);
break;
}
}
},
onFocus() {
if (this.loaded === false) {
this.loadData();
}
},
loadData() {
this.loading = true;
this.service
.getTechnologies(this.$api)
.then((response) => {
this.choices = response.data.results;
this.loaded = true;
})
.finally(() => {
this.loading = false;
});
},
onFilter(event) {
let params = {
search: event.value
};
this.service.getTechnologies(this.$api, params).then((response) => {
this.choices = response.data.results;
});
}
},
watch: {
modelValue: {
immediate: true,
deep: true,
handler(value) {
if (this.choices.length === 0) {
if (value && value.pk) {
this.choices = [value];
}
}
}
}
}
};
</script>

<template>
<Dropdown v-model="model" :options="choices" @focus="onFocus" optionLabel="name" optionValue="pk" @change="change" :loading="loading" :filter="true" @filter="onFilter"></Dropdown>
</template>
26 changes: 12 additions & 14 deletions frontend/src/views/pages/advisories/AdvisoryCreate.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import AdvisoryService from '@/service/AdvisoryService';
import VulnerabilityTemplateService from '@/service/VulnerabilityTemplateService';
import SeveritySelectField from '@/components/elements/forms/SeveritySelectField.vue';
import MarkdownEditor from '@/components/forms/MarkdownEditor.vue';
import TechnologySelectField from '@/components/elements/forms/TechnologySelectField.vue';
export default {
name: 'AdvisoryCreate',
Expand Down Expand Up @@ -41,11 +42,11 @@ export default {
affected_versions: null,
fixed_version: null,
severity: null,
vendor_name: null,
vendor_url: null,
technology: null,
researchers: null,
attachments: []
},
descriptionCustomized: false,
loading: false,
templateChoices: []
};
Expand All @@ -62,8 +63,7 @@ export default {
affected_versions: this.model.affected_versions,
fixed_version: this.model.fixed_version,
severity: this.model.severity,
vendor_name: this.model.vendor_name,
vendor_url: this.model.vendor_url,
technology: this.model.technology,
researchers: this.model.researchers
};
// create advisory first, so we can upload attachments afterward
Expand Down Expand Up @@ -97,6 +97,12 @@ export default {
}
});
},
setDescription(item) {
// set a default description based on the technology description
if (this.descriptionCustomized === false || (this.descriptionCustomized === true && this.description === '')) {
this.model.description = item.description;
}
},
onFocusTemplate() {
this.templateService.getTemplates(this.$api).then((response) => {
this.templateChoices = response.data.results;
Expand Down Expand Up @@ -125,7 +131,7 @@ export default {
}
},
mounted() {},
components: { SeveritySelectField, MarkdownEditor }
components: { TechnologySelectField, SeveritySelectField, MarkdownEditor }
};
</script>
<template>
Expand Down Expand Up @@ -153,20 +159,12 @@ export default {
</div>
<div class="field col-12 md:col-6">
<label for="product">Product</label>
<InputText id="product" v-model="model.product"></InputText>
<TechnologySelectField v-model="model.technology" @change="setDescription"></TechnologySelectField>
</div>
<div class="field col-12 md:col-6">
<label for="affected_versions">Affected Versions</label>
<InputText id="affected_versions" v-model="model.affected_versions"></InputText>
</div>
<div class="field col-12 md:col-6">
<label for="vendor_name">Vendor</label>
<InputText id="vendor_name" v-model="model.vendor_name"></InputText>
</div>
<div class="field col-12 md:col-6">
<label for="vendor_url">Vendor URL</label>
<InputText id="vendor_url" v-model="model.vendor_url"></InputText>
</div>
<div class="field col-12">
<label for="researchers">Researchers</label>
<InputText id="researchers" v-model="model.researchers"></InputText>
Expand Down
10 changes: 8 additions & 2 deletions frontend/src/views/pages/advisories/AdvisoryDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default {
service: new AdvisoryService(),
advisoryId: this.$route.params.advisoryId,
authStore: useAuthStore(),
advisory: { vulnerability: {} },
advisory: { vulnerability: {}, technology: {} },
exportTemplate: null,
downloadPending: false,
dataLoaded: false,
Expand Down Expand Up @@ -164,6 +164,12 @@ export default {
}
},
computed: {
productDisplay() {
if (this.advisory.technology && this.advisory.technology.vendor) {
return `${this.advisory.technology.name} (by ${this.advisory.technology.vendor})`;
}
return `${this.advisory.technology.name} (by Unknown)`;
},
containerCol() {
if (this.showPreview === true) {
return 'col-6';
Expand Down Expand Up @@ -210,7 +216,7 @@ export default {
<div class="card border-noround-top" v-if="dataLoaded">
<div class="grid">
<div class="col-12 md:col-3">
<DetailCardWithIcon title="Product" icon="fa fa-cart-shopping" class="surface-ground" :text="advisory.product + '(by ' + advisory.vendor_name + ')'"></DetailCardWithIcon>
<DetailCardWithIcon title="Product" icon="fa fa-cart-shopping" class="surface-ground" :text="productDisplay"></DetailCardWithIcon>
</div>
<div class="col-12 md:col-3">
<DetailCardWithIcon title="Affected Versions" icon="fa fa-circle-exclamation" class="surface-ground" :text="advisory.affected_versions"></DetailCardWithIcon>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/pages/advisories/AdvisoryInbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export default {
</template>
</Column>
<Column header="Product">
<template #body="slotProps"> {{ slotProps.data.product }} (by {{ slotProps.data.vendor_name }}) </template>
<template #body="slotProps">{{ slotProps.data.technology.name }} </template>
</Column>
<Column field="status" header="Status" :showFilterMatchModes="false">
<template #filter="{ filterModel }">
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/pages/advisories/AdvisoryList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export default {
</template>
</Column>
<Column header="Product">
<template #body="slotProps"> {{ slotProps.data.product }} (by {{ slotProps.data.vendor_name }}) </template>
<template #body="slotProps">{{ slotProps.data.technology.name }}</template>
</Column>
<Column field="status" header="Status" :showFilterMatchModes="false">
<template #filter="{ filterModel }">
Expand Down
Loading

0 comments on commit 4bfacca

Please sign in to comment.