Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds functionality to reduce repeated problems in the problems ui #145

Merged
merged 1 commit into from
Sep 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thumbs up for maps!


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;