Commit 1ff5881c authored by Lukas Eipert's avatar Lukas Eipert

Remove outdated SAST frontend code

Since we now retrieve data from the Backend, we can remove the parsing
log from the Frontend. See:
https://gitlab.com/groups/gitlab-org/-/epics/1425
parent bd795ea2
...@@ -2,48 +2,10 @@ import axios from '~/lib/utils/axios_utils'; ...@@ -2,48 +2,10 @@ import axios from '~/lib/utils/axios_utils';
import pollUntilComplete from '~/lib/utils/poll_until_complete'; import pollUntilComplete from '~/lib/utils/poll_until_complete';
import * as types from './mutation_types'; import * as types from './mutation_types';
export const setHeadPath = ({ commit }, path) => commit(types.SET_HEAD_PATH, path);
export const setBasePath = ({ commit }, path) => commit(types.SET_BASE_PATH, path);
export const setDiffEndpoint = ({ commit }, path) => commit(types.SET_DIFF_ENDPOINT, path); export const setDiffEndpoint = ({ commit }, path) => commit(types.SET_DIFF_ENDPOINT, path);
export const requestReports = ({ commit }) => commit(types.REQUEST_REPORTS); export const requestReports = ({ commit }) => commit(types.REQUEST_REPORTS);
export const receiveReports = ({ commit }, response) => commit(types.RECEIVE_REPORTS, response);
export const receiveError = ({ commit }, error) => commit(types.RECEIVE_REPORTS_ERROR, error);
export const fetchReports = ({ state, rootState, dispatch }) => {
const { base, head } = state.paths;
const { blobPath, vulnerabilityFeedbackPath } = rootState;
dispatch('requestReports');
return Promise.all([
head ? axios.get(head) : Promise.resolve(),
base ? axios.get(base) : Promise.resolve(),
axios.get(vulnerabilityFeedbackPath, {
params: {
category: 'sast',
},
}),
])
.then(values => {
dispatch('receiveReports', {
reports: {
head: values && values[0] ? values[0].data : null,
base: values && values[1] ? values[1].data : null,
enrichData: values && values[2] ? values[2].data : [],
},
blobPath,
});
})
.catch(() => {
dispatch('receiveError');
});
};
export const updateVulnerability = ({ commit }, vulnerability) => export const updateVulnerability = ({ commit }, vulnerability) =>
commit(types.UPDATE_VULNERABILITY, vulnerability); commit(types.UPDATE_VULNERABILITY, vulnerability);
......
export const RECEIVE_DIFF_SUCCESS = 'RECEIVE_DIFF_SUCCESS'; export const RECEIVE_DIFF_SUCCESS = 'RECEIVE_DIFF_SUCCESS';
export const RECEIVE_DIFF_ERROR = 'RECEIVE_DIFF_ERROR'; export const RECEIVE_DIFF_ERROR = 'RECEIVE_DIFF_ERROR';
export const RECEIVE_REPORTS = 'RECEIVE_REPORTS';
export const RECEIVE_REPORTS_ERROR = 'RECEIVE_REPORTS_ERROR';
export const REQUEST_REPORTS = 'REQUEST_REPORTS'; export const REQUEST_REPORTS = 'REQUEST_REPORTS';
export const SET_BASE_PATH = 'SET_BASE_PATH';
export const SET_DIFF_ENDPOINT = 'SET_DIFF_ENDPOINT'; export const SET_DIFF_ENDPOINT = 'SET_DIFF_ENDPOINT';
export const SET_HEAD_PATH = 'SET_HEAD_PATH';
export const UPDATE_VULNERABILITY = 'UPDATE_VULNERABILITY'; export const UPDATE_VULNERABILITY = 'UPDATE_VULNERABILITY';
import Vue from 'vue'; import Vue from 'vue';
import * as types from './mutation_types'; import * as types from './mutation_types';
import { parseSastIssues, findIssueIndex, parseDiff } from '../../utils'; import { findIssueIndex, parseDiff } from '../../utils';
import filterByKey from '../../utils/filter_by_key';
export default { export default {
[types.SET_HEAD_PATH](state, path) {
Vue.set(state.paths, 'head', path);
},
[types.SET_BASE_PATH](state, path) {
Vue.set(state.paths, 'base', path);
},
[types.SET_DIFF_ENDPOINT](state, path) { [types.SET_DIFF_ENDPOINT](state, path) {
Vue.set(state.paths, 'diffEndpoint', path); Vue.set(state.paths, 'diffEndpoint', path);
}, },
...@@ -20,45 +11,6 @@ export default { ...@@ -20,45 +11,6 @@ export default {
state.isLoading = true; state.isLoading = true;
}, },
/**
* Compares sast results and returns the formatted report
*
* Sast has 3 types of issues: newIssues, resolvedIssues and allIssues.
*
* When we have both base and head:
* - newIssues = head - base
* - resolvedIssues = base - head
* - allIssues = head - newIssues - resolvedIssues
*
* When we only have head
* - newIssues = head
* - resolvedIssues = 0
* - allIssues = 0
*/
[types.RECEIVE_REPORTS](state, payload) {
const { reports, blobPath } = payload;
if (reports.base && reports.head) {
const filterKey = 'cve';
const parsedHead = parseSastIssues(reports.head, reports.enrichData, blobPath.head);
const parsedBase = parseSastIssues(reports.base, reports.enrichData, blobPath.base);
const newIssues = filterByKey(parsedHead, parsedBase, filterKey);
const resolvedIssues = filterByKey(parsedBase, parsedHead, filterKey);
const allIssues = filterByKey(parsedHead, newIssues.concat(resolvedIssues), filterKey);
state.newIssues = newIssues;
state.resolvedIssues = resolvedIssues;
state.allIssues = allIssues;
state.isLoading = false;
} else if (reports.head && !reports.base) {
const newIssues = parseSastIssues(reports.head, reports.enrichData, blobPath.head);
state.newIssues = newIssues;
state.isLoading = false;
}
},
[types.RECEIVE_DIFF_SUCCESS](state, { diff, enrichData }) { [types.RECEIVE_DIFF_SUCCESS](state, { diff, enrichData }) {
const { added, fixed, existing } = parseDiff(diff, enrichData); const { added, fixed, existing } = parseDiff(diff, enrichData);
const baseReportOutofDate = diff.base_report_out_of_date || false; const baseReportOutofDate = diff.base_report_out_of_date || false;
...@@ -77,11 +29,6 @@ export default { ...@@ -77,11 +29,6 @@ export default {
state.hasError = true; state.hasError = true;
}, },
[types.RECEIVE_REPORTS_ERROR](state) {
state.isLoading = false;
state.hasError = true;
},
[types.UPDATE_VULNERABILITY](state, issue) { [types.UPDATE_VULNERABILITY](state, issue) {
const newIssuesIndex = findIssueIndex(state.newIssues, issue); const newIssuesIndex = findIssueIndex(state.newIssues, issue);
if (newIssuesIndex !== -1) { if (newIssuesIndex !== -1) {
......
...@@ -138,31 +138,6 @@ function adaptDeprecatedReportFormat(report) { ...@@ -138,31 +138,6 @@ function adaptDeprecatedReportFormat(report) {
return report; return report;
} }
/**
* Parses SAST results into a common format to allow to use the same Vue component.
*
* @param {Array|Object} report
* @param {Array} feedback
* @param {String} path
* @returns {Array}
*/
export const parseSastIssues = (report = [], feedback = [], path = '') =>
adaptDeprecatedReportFormat(report).vulnerabilities.map(issue => {
const parsed = {
...adaptDeprecatedIssueFormat(issue),
category: 'sast',
project_fingerprint: sha1(issue.cve),
title: issue.message,
};
return {
...parsed,
path: parsed.location.file,
urlPath: fileUrl(parsed.location, path),
...enrichVulnerabilityWithFeedback(parsed, feedback),
};
});
/** /**
* Parses Dependency Scanning results into a common format to allow to use the same Vue component. * Parses Dependency Scanning results into a common format to allow to use the same Vue component.
* *
......
...@@ -86,23 +86,6 @@ export const sastIssues = [ ...@@ -86,23 +86,6 @@ export const sastIssues = [
}, },
]; ];
export const sastIssuesMajor2 = {
version: '2.0',
vulnerabilities: sastIssues,
};
export const oldSastIssues = [
{
tool: 'bundler_audit',
message: 'Arbitrary file existence disclosure in Action Pack',
url: 'https://groups.google.com/forum/#!topic/rubyonrails-security/rMTQy4oRCGk',
cve: 'CVE-2014-7829',
file: 'Gemfile.lock',
line: '5',
solution: 'upgrade to ~> 3.2.21, ~> 4.0.11.1, ~> 4.0.12, ~> 4.1.7.1, >= 4.1.8',
},
];
export const sastIssuesBase = [ export const sastIssuesBase = [
{ {
tool: 'bundler_audit', tool: 'bundler_audit',
......
...@@ -6,8 +6,6 @@ import * as types from 'ee/vue_shared/security_reports/store/modules/sast/mutati ...@@ -6,8 +6,6 @@ import * as types from 'ee/vue_shared/security_reports/store/modules/sast/mutati
import * as actions from 'ee/vue_shared/security_reports/store/modules/sast/actions'; import * as actions from 'ee/vue_shared/security_reports/store/modules/sast/actions';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
const headPath = 'head-path.json';
const basePath = 'base-path.json';
const diffEndpoint = 'diff-endpoint.json'; const diffEndpoint = 'diff-endpoint.json';
const blobPath = 'blob-path.json'; const blobPath = 'blob-path.json';
const reports = { const reports = {
...@@ -28,42 +26,6 @@ describe('sast report actions', () => { ...@@ -28,42 +26,6 @@ describe('sast report actions', () => {
state = createState(); state = createState();
}); });
describe('setHeadPath', () => {
it(`should commit ${types.SET_HEAD_PATH} with the correct path`, done => {
testAction(
actions.setHeadPath,
headPath,
state,
[
{
type: types.SET_HEAD_PATH,
payload: headPath,
},
],
[],
done,
);
});
});
describe('setBasePath', () => {
it(`should commit ${types.SET_BASE_PATH} with the correct path`, done => {
testAction(
actions.setBasePath,
basePath,
state,
[
{
type: types.SET_BASE_PATH,
payload: basePath,
},
],
[],
done,
);
});
});
describe('setDiffEndpoint', () => { describe('setDiffEndpoint', () => {
it(`should commit ${types.SET_DIFF_ENDPOINT} with the correct path`, done => { it(`should commit ${types.SET_DIFF_ENDPOINT} with the correct path`, done => {
testAction( testAction(
...@@ -88,113 +50,6 @@ describe('sast report actions', () => { ...@@ -88,113 +50,6 @@ describe('sast report actions', () => {
}); });
}); });
describe('receiveReports', () => {
it(`should commit ${types.RECEIVE_REPORTS} with the correct response`, done => {
testAction(
actions.receiveReports,
reports,
state,
[
{
type: types.RECEIVE_REPORTS,
payload: reports,
},
],
[],
done,
);
});
});
describe('receiveError', () => {
it(`should commit ${types.RECEIVE_REPORTS_ERROR} with the correct response`, done => {
testAction(
actions.receiveError,
error,
state,
[
{
type: types.RECEIVE_REPORTS_ERROR,
payload: error,
},
],
[],
done,
);
});
});
describe('fetchReports', () => {
let mock;
beforeEach(() => {
mock = new MockAdapter(axios);
state.paths.head = headPath;
state.paths.base = basePath;
});
afterEach(() => {
mock.restore();
});
describe('when everything goes according to plan', () => {
beforeEach(() => {
mock
.onGet(headPath)
.replyOnce(200, reports.head)
.onGet(basePath)
.replyOnce(200, reports.base)
.onGet(vulnerabilityFeedbackPath)
.replyOnce(200, reports.enrichData);
});
it('should dispatch the `receiveReports` action', done => {
const { head, base, enrichData } = reports;
testAction(
actions.fetchReports,
{},
{ ...rootState, ...state },
[],
[
{ type: 'requestReports' },
{
type: 'receiveReports',
payload: {
blobPath,
reports: { head, base, enrichData },
},
},
],
done,
);
});
});
describe('when the vulnerability feedback endpoint fails', () => {
beforeEach(() => {
mock
.onGet(headPath)
.replyOnce(200, reports.head)
.onGet(basePath)
.replyOnce(200, reports.base)
.onGet(vulnerabilityFeedbackPath)
.replyOnce(404);
});
it('should dispatch the `receiveError` action', done => {
testAction(
actions.fetchReports,
{},
{ ...rootState, ...state },
[],
[{ type: 'requestReports' }, { type: 'receiveError' }],
done,
);
});
});
});
describe('receiveDiffSuccess', () => { describe('receiveDiffSuccess', () => {
it(`should commit ${types.RECEIVE_DIFF_SUCCESS} with the correct response`, done => { it(`should commit ${types.RECEIVE_DIFF_SUCCESS} with the correct response`, done => {
testAction( testAction(
......
...@@ -12,22 +12,6 @@ describe('sast module mutations', () => { ...@@ -12,22 +12,6 @@ describe('sast module mutations', () => {
state = createState(); state = createState();
}); });
describe(types.SET_HEAD_PATH, () => {
it('should set the SAST head path', () => {
mutations[types.SET_HEAD_PATH](state, path);
expect(state.paths.head).toBe(path);
});
});
describe(types.SET_BASE_PATH, () => {
it('should set the SAST base path', () => {
mutations[types.SET_BASE_PATH](state, path);
expect(state.paths.base).toBe(path);
});
});
describe(types.SET_DIFF_ENDPOINT, () => { describe(types.SET_DIFF_ENDPOINT, () => {
it('should set the SAST diff endpoint', () => { it('should set the SAST diff endpoint', () => {
mutations[types.SET_DIFF_ENDPOINT](state, path); mutations[types.SET_DIFF_ENDPOINT](state, path);
...@@ -44,21 +28,6 @@ describe('sast module mutations', () => { ...@@ -44,21 +28,6 @@ describe('sast module mutations', () => {
}); });
}); });
describe(types.RECEIVE_REPORTS_ERROR, () => {
beforeEach(() => {
state.isLoading = true;
mutations[types.RECEIVE_REPORTS_ERROR](state);
});
it('should set the `isLoading` status to `false`', () => {
expect(state.isLoading).toBe(false);
});
it('should set the `hasError` status to `true`', () => {
expect(state.hasError).toBe(true);
});
});
describe(types.UPDATE_VULNERABILITY, () => { describe(types.UPDATE_VULNERABILITY, () => {
let newIssue; let newIssue;
let resolvedIssue; let resolvedIssue;
...@@ -120,72 +89,6 @@ describe('sast module mutations', () => { ...@@ -120,72 +89,6 @@ describe('sast module mutations', () => {
}); });
}); });
describe(types.RECEIVE_REPORTS, () => {
const head = [
createIssue({ cve: 'CVE-1' }),
createIssue({ cve: 'CVE-4' }),
createIssue({ cve: 'CVE-5' }),
createIssue({ cve: 'CVE-6' }),
];
const base = [
createIssue({ cve: 'CVE-1' }),
createIssue({ cve: 'CVE-2' }),
createIssue({ cve: 'CVE-3' }),
];
const enrichData = [];
const blobPath = 'blobPath';
beforeEach(() => {
state.isLoading = true;
});
describe('with only the head report', () => {
beforeEach(() => {
const reports = { head, enrichData };
mutations[types.RECEIVE_REPORTS](state, { reports, blobPath });
});
it('should set the `isLoading` status to `false`', () => {
expect(state.isLoading).toBe(false);
});
it('should have the relevant `new` issues', () => {
expect(state.newIssues.length).toBe(4);
});
it('should not have any `resolved` issues', () => {
expect(state.resolvedIssues.length).toBe(0);
});
it('should not have any `all` issues', () => {
expect(state.allIssues.length).toBe(0);
});
});
describe('with the base and head reports', () => {
beforeEach(() => {
const reports = { head, base, enrichData };
mutations[types.RECEIVE_REPORTS](state, { reports, blobPath });
});
it('should set the `isLoading` status to `false`', () => {
expect(state.isLoading).toBe(false);
});
it('should have the relevant `new` issues', () => {
expect(state.newIssues.length).toBe(3);
});
it('should have the relevant `resolved` issues', () => {
expect(state.resolvedIssues.length).toBe(2);
});
it('should have the relevant `all` issues', () => {
expect(state.allIssues.length).toBe(1);
});
});
});
describe(types.RECEIVE_DIFF_SUCCESS, () => { describe(types.RECEIVE_DIFF_SUCCESS, () => {
beforeEach(() => { beforeEach(() => {
const reports = { const reports = {
......
...@@ -2,7 +2,6 @@ import sha1 from 'sha1'; ...@@ -2,7 +2,6 @@ import sha1 from 'sha1';
import { import {
findIssueIndex, findIssueIndex,
findMatchingRemediations, findMatchingRemediations,
parseSastIssues,
parseDependencyScanningIssues, parseDependencyScanningIssues,
groupedTextBuilder, groupedTextBuilder,
statusIcon, statusIcon,
...@@ -12,10 +11,6 @@ import { ...@@ -12,10 +11,6 @@ import {
import filterByKey from 'ee/vue_shared/security_reports/store/utils/filter_by_key'; import filterByKey from 'ee/vue_shared/security_reports/store/utils/filter_by_key';
import getFileLocation from 'ee/vue_shared/security_reports/store/utils/get_file_location'; import getFileLocation from 'ee/vue_shared/security_reports/store/utils/get_file_location';
import { import {
oldSastIssues,
sastIssues,
sastIssuesMajor2,
sastFeedbacks,
dependencyScanningIssuesOld, dependencyScanningIssuesOld,
dependencyScanningIssues, dependencyScanningIssues,
dependencyScanningIssuesMajor2, dependencyScanningIssuesMajor2,
...@@ -102,57 +97,6 @@ describe('security reports utils', () => { ...@@ -102,57 +97,6 @@ describe('security reports utils', () => {
}); });
}); });
describe('parseSastIssues', () => {
it('should parse the received issues with old JSON format', () => {
const parsed = parseSastIssues(oldSastIssues, [], 'path')[0];
expect(parsed.title).toEqual(sastIssues[0].message);
expect(parsed.path).toEqual(sastIssues[0].location.file);
expect(parsed.location.start_line).toEqual(sastIssues[0].location.start_line);
expect(parsed.location.end_line).toBeUndefined();
expect(parsed.urlPath).toEqual('path/Gemfile.lock#L5');
expect(parsed.project_fingerprint).toEqual(sha1(sastIssues[0].cve));
});
it('should parse the received issues with new JSON format', () => {
const parsed = parseSastIssues(sastIssues, [], 'path')[0];
expect(parsed.title).toEqual(sastIssues[0].message);
expect(parsed.path).toEqual(sastIssues[0].location.file);
expect(parsed.location.start_line).toEqual(sastIssues[0].location.start_line);
expect(parsed.location.end_line).toEqual(sastIssues[0].location.end_line);
expect(parsed.urlPath).toEqual('path/Gemfile.lock#L5-10');
expect(parsed.project_fingerprint).toEqual(sha1(sastIssues[0].cve));
});
it('should parse the received issues with new JSON format (2.0)', () => {
const raw = sastIssues[0];
const parsed = parseSastIssues(sastIssuesMajor2, [], 'path')[0];
expect(parsed.title).toEqual(raw.message);
expect(parsed.path).toEqual(raw.location.file);
expect(parsed.location.start_line).toEqual(raw.location.start_line);
expect(parsed.location.end_line).toEqual(raw.location.end_line);
expect(parsed.urlPath).toEqual('path/Gemfile.lock#L5-10');
expect(parsed.project_fingerprint).toEqual(sha1(raw.cve));
});
it('generate correct path to file when there is no line', () => {
const parsed = parseSastIssues(sastIssues, [], 'path')[1];
expect(parsed.urlPath).toEqual('path/Gemfile.lock');
});
it('includes vulnerability feedbacks', () => {
const parsed = parseSastIssues(sastIssues, sastFeedbacks, 'path')[0];
expect(parsed.hasIssue).toEqual(true);
expect(parsed.isDismissed).toEqual(true);
expect(parsed.dismissalFeedback).toEqual(sastFeedbacks[0]);
expect(parsed.issue_feedback).toEqual(sastFeedbacks[1]);
});
});
describe('parseDependencyScanningIssues', () => { describe('parseDependencyScanningIssues', () => {
it('should parse the received issues', () => { it('should parse the received issues', () => {
const parsed = parseDependencyScanningIssues(dependencyScanningIssuesOld, [], 'path')[0]; const parsed = parseDependencyScanningIssues(dependencyScanningIssuesOld, [], 'path')[0];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment