Skip to content

Commit

Permalink
Adds functionality to reduce repeated problems in the problems ui
Browse files Browse the repository at this point in the history
  • Loading branch information
bomoko committed Aug 8, 2023
1 parent 8e339cf commit 958e17b
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 19 deletions.
5 changes: 3 additions & 2 deletions .storybook/mocks/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ export function createTask(): Task {
`::group::${eventName}\n` +
`::${status[Math.floor(faker.number.int({ min: 0, max: 1 }) * status.length)]}:: Job '${jobName}'\n` +
`::step-start::${stepName}\n` +
`::${
status[Math.floor(faker.number.int({ min: 0, max: 1 }) * status.length)]
`::${status[Math.floor(faker.number.int({ min: 0, max: 1 }) * status.length)]
}:: Job '${jobName}' step '${stepName}'\n` +
`::step-end::${stepName}::${duration}\n` +
`${generateLogMessage()}\n` +
Expand Down Expand Up @@ -143,12 +142,14 @@ export const Problem = (args: any) => {
const links = `https://security-tracker.debian.org/tracker/${vuln_id}`;
const severityScore = `0.${faker.number.int({ min: 1, max: 9 })}`;
const data = JSON.stringify({ id: `${faker.number.int({ min: 1, max: 100 })}` }, null, '\t');
const service = faker.helpers.arrayElement(['cli', 'service1']);
return {
identifier: vuln_id,
severity: args.hasOwnProperty('severity') ? args.severity : severity,
source: args.hasOwnProperty('source') ? args.source : source,
severityScore: severityScore,
associatedPackage: associatedPackage,
service: service,
description,
links,
data,
Expand Down
60 changes: 43 additions & 17 deletions src/components/Problems/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,32 @@ const getOptionsFromProblems = (problems, key) => {
return [...uniqueOptions];
};

// reduceProblemsDuplicatedByService will take a list of problems and remove duplicates
// Duplicates are any items with the same source and identifier (multiple sources could report the same cve, but perhaps with different data)
// it appends the duplicated service names.
const reduceProblemsDuplicatedByService = problems => {
let reduceProblemsByService = new Map();

for (const c of problems) {
const { identifier, source, service } = c;
const id = `${identifier}-${source}`;

if (reduceProblemsByService.has(id)) {
let prob = Object.assign({}, reduceProblemsByService.get(id));
prob.service = `${prob.service}, ${c.service}`;
reduceProblemsByService.set(id, prob);
} else {
reduceProblemsByService.set(id, c);
}
}
return Array.from(reduceProblemsByService.values());
}

const Problems = ({ problems }) => {
const { sortedItems, requestSort, getClassNamesFor } = useSortableProblemsData(problems);

const reducedProblems = reduceProblemsDuplicatedByService(problems);

const { sortedItems, requestSort, getClassNamesFor } = useSortableProblemsData(reducedProblems);
const [severitySelected, setSeverity] = useState([]);
const [sourceSelected, setSource] = useState([]);
const [servicesSelected, setService] = useState([]);
Expand All @@ -26,6 +50,7 @@ const Problems = ({ problems }) => {
const sources = getOptionsFromProblems(problems, 'source');
const services = getOptionsFromProblems(problems, 'service');


// Handlers
const handleSort = key => requestSort(key);

Expand Down Expand Up @@ -70,40 +95,40 @@ const Problems = ({ problems }) => {
const matchesSeveritySelector = item => {
return severitySelected.length > 0
? Object.keys(item).some(key => {
if (item[key] !== null) {
return severitySelected.indexOf(item['severity'].toString()) > -1;
}
})
if (item[key] !== null) {
return severitySelected.indexOf(item['severity'].toString()) > -1;
}
})
: true;
};

const matchesSourceSelector = item => {
return sourceSelected.length > 0
? Object.keys(item).some(key => {
if (item[key] !== null) {
return sourceSelected.indexOf(item['source'].toString()) > -1;
}
})
if (item[key] !== null) {
return sourceSelected.indexOf(item['source'].toString()) > -1;
}
})
: true;
};

const matchesServiceSelector = item => {
return servicesSelected.length > 0
? Object.keys(item).some(key => {
if (item[key] !== null) {
return servicesSelected.indexOf(item['service'].toString()) > -1;
}
})
if (item[key] !== null) {
return servicesSelected.indexOf(item['service'].toString()) > -1;
}
})
: true;
};

const matchesTextFilter = item => {
return problemTerm != null || problemTerm !== ''
? Object.keys(item).some(key => {
if (item[key] !== null) {
return item[key].toString().toLowerCase().includes(problemTerm.toLowerCase());
}
})
if (item[key] !== null) {
return item[key].toString().toLowerCase().includes(problemTerm.toLowerCase());
}
})
: true;
};

Expand All @@ -116,6 +141,7 @@ const Problems = ({ problems }) => {
);
};


useEffect(() => {
let stats = {
critical: sortedItems.filter(p => p.severity === 'CRITICAL').length,
Expand Down
36 changes: 36 additions & 0 deletions src/stories/problems.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,39 @@ export const Default: Story = {
},
};

const duplicateProblemsAcrossServices = [
{ ...problemData[0], service: "cli" },
{ ...problemData[0], service: "php-nginx" },
{ ...problemData[1], service: "cli" },
{ ...problemData[1], service: "node" },
{ ...problemData[1], service: "service" },
];

export const DuplicateData: Story = {
args: {
router: {
query: fakeQueryParams,
},
},
parameters: {
msw: {
handlers: [
graphql.query('getEnvironment', (_, res, ctx) => {
return res(
ctx.delay(),
ctx.data({
environment: {
...generateEnvironments(),
problems: duplicateProblemsAcrossServices,
},
})
);
}),
],
},
},
};

export const Loading: Story = {
parameters: {
msw: {
Expand All @@ -65,4 +98,7 @@ export const Loading: Story = {
},
},
};



export default meta;

0 comments on commit 958e17b

Please sign in to comment.