Merge pull request #4132 from SDA-SE/feat/security-hotspots

Add support for Security Hotspots that are provided by SonarQube and SonarCloud
This commit is contained in:
Dominik Henneke
2021-01-21 10:17:10 +01:00
committed by GitHub
9 changed files with 61 additions and 2 deletions
+9
View File
@@ -59,6 +59,8 @@ createDevApp()
projectUrl: `/#${componentKey}`,
getIssuesUrl: i => `/#${componentKey}/issues/${i}`,
getComponentMeasuresUrl: i => `/#${componentKey}/measures/${i}`,
getSecurityHotspotsUrl: () =>
`#${componentKey}/security_hotspots`,
} as FindingSummary;
case 'failed':
@@ -70,6 +72,7 @@ createDevApp()
reliability_rating: '2.0',
vulnerabilities: '18',
security_rating: '3.0',
security_review_rating: '3.0',
code_smells: '22',
sqale_rating: '5.0',
coverage: '15.7',
@@ -78,6 +81,8 @@ createDevApp()
projectUrl: `/#${componentKey}`,
getIssuesUrl: i => `/#${componentKey}/issues/${i}`,
getComponentMeasuresUrl: i => `/#${componentKey}/measures/${i}`,
getSecurityHotspotsUrl: () =>
`#${componentKey}/security_hotspots`,
} as FindingSummary;
case 'passed':
@@ -89,6 +94,8 @@ createDevApp()
reliability_rating: '1.0',
vulnerabilities: '0',
security_rating: '1.0',
security_hotspots_reviewed: '100.0',
security_review_rating: '1.0',
code_smells: '0',
sqale_rating: '1.0',
coverage: '100.0',
@@ -97,6 +104,8 @@ createDevApp()
projectUrl: `/#${componentKey}`,
getIssuesUrl: i => `/#${componentKey}/issues/${i}`,
getComponentMeasuresUrl: i => `/#${componentKey}/measures/${i}`,
getSecurityHotspotsUrl: () =>
`#${componentKey}/security_hotspots`,
} as FindingSummary;
default:
@@ -30,6 +30,7 @@ export interface FindingSummary {
projectUrl: string;
getIssuesUrl: SonarUrlProcessorFunc;
getComponentMeasuresUrl: SonarUrlProcessorFunc;
getSecurityHotspotsUrl: () => string;
}
export const sonarQubeApiRef = createApiRef<SonarQubeApi>({
@@ -46,7 +46,7 @@ describe('SonarQubeClient', () => {
server.use(
rest.get(`${mockBaseUrl}/sonarqube/measures/search`, (req, res, ctx) => {
expect(req.url.searchParams.toString()).toBe(
'projectKeys=our-service&metricKeys=alert_status%2Cbugs%2Creliability_rating%2Cvulnerabilities%2Csecurity_rating%2Ccode_smells%2Csqale_rating%2Ccoverage%2Cduplicated_lines_density',
'projectKeys=our-service&metricKeys=alert_status%2Cbugs%2Creliability_rating%2Cvulnerabilities%2Csecurity_rating%2Csecurity_hotspots_reviewed%2Csecurity_review_rating%2Ccode_smells%2Csqale_rating%2Ccoverage%2Cduplicated_lines_density',
);
return res(
ctx.json({
@@ -81,6 +81,16 @@ describe('SonarQubeClient', () => {
value: '1.0',
component: 'our-service',
},
{
metric: 'security_hotspots_reviewed',
value: '100',
component: 'our-service',
},
{
metric: 'security_review_rating',
value: '1.0',
component: 'our-service',
},
{
metric: 'code_smells',
value: '100',
@@ -123,6 +133,8 @@ describe('SonarQubeClient', () => {
reliability_rating: '3.0',
vulnerabilities: '4',
security_rating: '1.0',
security_hotspots_reviewed: '100',
security_review_rating: '1.0',
code_smells: '100',
sqale_rating: '2.0',
coverage: '55.5',
@@ -158,6 +170,8 @@ describe('SonarQubeClient', () => {
reliability_rating: '3.0',
vulnerabilities: '4',
security_rating: '1.0',
security_hotspots_reviewed: '100',
security_review_rating: '1.0',
code_smells: '100',
sqale_rating: '2.0',
coverage: '55.5',
+5 -1
View File
@@ -63,6 +63,8 @@ export class SonarQubeClient implements SonarQubeApi {
reliability_rating: undefined,
vulnerabilities: undefined,
security_rating: undefined,
security_hotspots_reviewed: undefined,
security_review_rating: undefined,
code_smells: undefined,
sqale_rating: undefined,
coverage: undefined,
@@ -92,10 +94,12 @@ export class SonarQubeClient implements SonarQubeApi {
`${
this.baseUrl
}project/issues?id=${componentKey}&types=${identifier.toUpperCase()}&resolved=false`,
getComponentMeasuresUrl: (identifier: string) =>
getComponentMeasuresUrl: identifier =>
`${
this.baseUrl
}component_measures?id=${componentKey}&metric=${identifier.toLowerCase()}&resolved=false&view=list`,
getSecurityHotspotsUrl: () =>
`${this.baseUrl}project/security_hotspots?id=${componentKey}`,
};
}
}
+4
View File
@@ -42,6 +42,10 @@ export type MetricKey =
| 'code_smells'
| 'sqale_rating'
// security hotspots
| 'security_hotspots_reviewed'
| 'security_review_rating'
// coverage
| 'coverage'
@@ -22,6 +22,7 @@ const useStyles = makeStyles(theme => {
return {
root: {
margin: theme.spacing(1, 0),
minWidth: '140px',
},
upper: {
display: 'flex',
@@ -26,6 +26,7 @@ import { Chip, Grid } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import BugReport from '@material-ui/icons/BugReport';
import LockOpen from '@material-ui/icons/LockOpen';
import Security from '@material-ui/icons/Security';
import SentimentVeryDissatisfied from '@material-ui/icons/SentimentVeryDissatisfied';
import React, { useMemo } from 'react';
import { useAsync } from 'react-use';
@@ -205,6 +206,25 @@ export const SonarQubeCard = ({
leftSlot={<Value value={value.metrics.code_smells} />}
rightSlot={<Rating rating={value.metrics.sqale_rating} />}
/>
{value.metrics.security_review_rating && (
<RatingCard
titleIcon={<Security />}
title="Hotspots Reviewed"
link={value.getSecurityHotspotsUrl()}
leftSlot={
<Value
value={
value.metrics.security_hotspots_reviewed
? `${value.metrics.security_hotspots_reviewed}%`
: '—'
}
/>
}
rightSlot={
<Rating rating={value.metrics.security_review_rating} />
}
/>
)}
<div style={{ width: '100%' }} />
<RatingCard
link={value.getComponentMeasuresUrl('COVERAGE')}