Skip to content

Commit 6bc68b5

Browse files
committed
Merge branch 'update-risk-monitoring'
2 parents 7030faa + fd81ea2 commit 6bc68b5

File tree

4 files changed

+172
-12
lines changed

4 files changed

+172
-12
lines changed

backend/services/risks_service.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,19 @@ def get_risks(user_id):
3333
for scan in scans:
3434
scan_result = scan.scan_result
3535
scan_type = scan.scan_type
36-
failed_checks = scan_result.get("results", {}).get("failed_checks", [])
37-
36+
if "failed_checks" in scan_result:
37+
failed_checks = scan_result["failed_checks"]
38+
elif "results" in scan_result and "failed_checks" in scan_result["results"]:
39+
failed_checks = scan_result["results"]["failed_checks"]
3840
for check in failed_checks:
39-
severity = check.get("severity", "INFO")
40-
severity_counts[severity] = severity_counts.get(severity, 0) + 1
41+
severity = check.get("severity") or "INFO" # Handles None explicitly
42+
# Normalize to uppercase for counting (in case Checkov uses "high" or "High")
43+
severity_upper = severity.upper() if severity else "INFO"
44+
# Only count if it's one of our expected keys (avoids errors if weird values)
45+
if severity_upper in severity_counts:
46+
severity_counts[severity_upper] += 1
47+
else:
48+
severity_counts["INFO"] += 1 # Fallback for unknown severities
4149
detailed_risks.append({
4250
"severity": severity,
4351
"check_id": check.get("check_id"),

frontend/src/components/VulnerabilityScanner/GitHubScanner.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ const GitHubScanner = ({ setResult, isLoading, setIsLoading }) => {
2323
formData.append("input_type", "repo");
2424
formData.append("repo_url", url);
2525

26-
console.log("Sending request to backend with URL:", url);
2726
const response = await fetch("http://localhost:5000/semgrep", {
2827
method: "POST",
2928
headers: {

frontend/src/pages/RiskDashboard/RiskDashboard.css

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,4 +499,87 @@
499499
.vulnerability-table__scroll::-webkit-scrollbar,
500500
.vulnerability-table__cards::-webkit-scrollbar {
501501
width: 8px;
502+
}
503+
/* Scan Type Filter Styles */
504+
.scan-type-filter {
505+
background: #fff;
506+
border-radius: 8px;
507+
padding: 1.5rem;
508+
margin-bottom: 1.5rem;
509+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
510+
}
511+
512+
.scan-type-filter__label {
513+
display: flex;
514+
align-items: center;
515+
gap: 0.5rem;
516+
font-weight: 600;
517+
font-size: 0.875rem;
518+
color: #374151;
519+
margin-bottom: 1rem;
520+
}
521+
522+
.scan-type-filter__icon {
523+
width: 1.25rem;
524+
height: 1.25rem;
525+
color: #6b7280;
526+
}
527+
528+
.scan-type-filter__buttons {
529+
display: flex;
530+
gap: 0.75rem;
531+
flex-wrap: wrap;
532+
}
533+
534+
.scan-type-filter__button {
535+
padding: 0.5rem 1rem;
536+
border: 2px solid #e5e7eb;
537+
border-radius: 6px;
538+
background: #fff;
539+
color: #6b7280;
540+
font-weight: 500;
541+
cursor: pointer;
542+
transition: all 0.2s;
543+
display: flex;
544+
align-items: center;
545+
gap: 0.5rem;
546+
}
547+
548+
.scan-type-filter__button:hover {
549+
border-color: #3b82f6;
550+
color: #3b82f6;
551+
background: #eff6ff;
552+
}
553+
554+
.scan-type-filter__button--active {
555+
border-color: #3b82f6;
556+
background: #3b82f6;
557+
color: #fff;
558+
}
559+
560+
.scan-type-filter__count {
561+
font-size: 0.75rem;
562+
opacity: 0.8;
563+
}
564+
565+
/* Update vulnerability table styles */
566+
.vulnerability-table__scan-type {
567+
display: inline-block;
568+
padding: 0.25rem 0.75rem;
569+
border-radius: 4px;
570+
background: #f3f4f6;
571+
color: #374151;
572+
font-size: 0.875rem;
573+
font-weight: 600;
574+
text-transform: uppercase;
575+
}
576+
577+
.vulnerability-card__scan-type {
578+
padding: 0.25rem 0.625rem;
579+
border-radius: 4px;
580+
background: #f3f4f6;
581+
color: #374151;
582+
font-size: 0.75rem;
583+
font-weight: 600;
584+
text-transform: uppercase;
502585
}

frontend/src/pages/RiskDashboard/RiskDashboard.jsx

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,43 @@
1-
import React from 'react';
2-
import { ChartBarIcon, ArrowPathIcon, ExclamationCircleIcon } from '@heroicons/react/24/outline';
1+
import React, { useState } from 'react';
2+
import { ChartBarIcon, ArrowPathIcon, ExclamationCircleIcon, FunnelIcon } from '@heroicons/react/24/outline';
33
import { Bar } from 'react-chartjs-2';
44
import { useRisks } from '../../hooks/UseRisk';
55
import { createChartData, createChartOptions, getSeverityColor } from '../../utils/chartConfig';
66
import './RiskDashboard.css';
77

88
const RiskDashboardPage = () => {
99
const { risks, details, loading, error, isRefreshing, refreshRisks } = useRisks();
10+
const [selectedScanType, setSelectedScanType] = useState('all');
11+
12+
// Get unique scan types from details
13+
const scanTypes = ['all', ...new Set(details.map(d => d.scan_type).filter(Boolean))];
14+
15+
// Filter details based on selected scan type
16+
const filteredDetails = selectedScanType === 'all'
17+
? details
18+
: details.filter(d => d.scan_type === selectedScanType);
19+
20+
// Aggregate risks by severity for filtered data
21+
const getFilteredRisks = () => {
22+
if (selectedScanType === 'all') return risks;
23+
24+
const severityCounts = { ERROR: 0, WARNING: 0, INFO: 0 };
25+
26+
filteredDetails.forEach(detail => {
27+
const severity = (detail.severity || 'INFO').toUpperCase();
28+
if (severity in severityCounts) {
29+
severityCounts[severity] += 1;
30+
} else {
31+
severityCounts.INFO += 1;
32+
}
33+
});
34+
35+
return [
36+
{ name: "Critical (ERROR)", level: severityCounts.ERROR * 10 },
37+
{ name: "High (WARNING)", level: severityCounts.WARNING * 5 },
38+
{ name: "Low (INFO)", level: severityCounts.INFO * 2 }
39+
];
40+
};
1041

1142
// Loading Spinner Component
1243
const LoadingSpinner = ({ message = 'Loading...' }) => (
@@ -34,10 +65,39 @@ const RiskDashboardPage = () => {
3465
</div>
3566
);
3667

68+
// Scan Type Filter Component
69+
const ScanTypeFilter = () => (
70+
<div className="scan-type-filter">
71+
<div className="scan-type-filter__label">
72+
<FunnelIcon className="scan-type-filter__icon" />
73+
<span>Filter by Scan Type:</span>
74+
</div>
75+
<div className="scan-type-filter__buttons">
76+
{scanTypes.map(type => (
77+
<button
78+
key={type}
79+
className={`scan-type-filter__button ${
80+
selectedScanType === type ? 'scan-type-filter__button--active' : ''
81+
}`}
82+
onClick={() => setSelectedScanType(type)}
83+
>
84+
{type === 'all' ? 'All Scans' : type.charAt(0).toUpperCase() + type.slice(1)}
85+
{type !== 'all' && (
86+
<span className="scan-type-filter__count">
87+
({details.filter(d => d.scan_type === type).length})
88+
</span>
89+
)}
90+
</button>
91+
))}
92+
</div>
93+
</div>
94+
);
95+
3796
// Risk Chart Section
3897
const RiskChart = ({ risks }) => {
39-
const chartData = createChartData(risks);
40-
const chartOptions = createChartOptions(risks);
98+
const filteredRisks = getFilteredRisks();
99+
const chartData = createChartData(filteredRisks);
100+
const chartOptions = createChartOptions(filteredRisks);
41101

42102
return (
43103
<div className="risk-chart">
@@ -58,7 +118,7 @@ const RiskDashboardPage = () => {
58118
<div className="vulnerability-table">
59119
<h3 className="vulnerability-table__title">Vulnerability Details</h3>
60120
<div className="vulnerability-table__empty">
61-
<p>No vulnerabilities found</p>
121+
<p>No vulnerabilities found{selectedScanType !== 'all' ? ` for ${selectedScanType}` : ''}</p>
62122
</div>
63123
</div>
64124
);
@@ -67,7 +127,7 @@ const RiskDashboardPage = () => {
67127
return (
68128
<div className="vulnerability-table">
69129
<h3 className="vulnerability-table__title">
70-
Vulnerability Details ({details.length})
130+
Vulnerabilities Details ({details.length})
71131
</h3>
72132

73133
{/* Desktop Table */}
@@ -76,6 +136,7 @@ const RiskDashboardPage = () => {
76136
<table className="vulnerability-table__table">
77137
<thead>
78138
<tr>
139+
<th>Scan Type</th>
79140
<th>Severity</th>
80141
<th>Problem</th>
81142
<th>Suggestion</th>
@@ -84,6 +145,11 @@ const RiskDashboardPage = () => {
84145
<tbody>
85146
{details.map((detail, index) => (
86147
<tr key={index}>
148+
<td>
149+
<span className="vulnerability-table__scan-type">
150+
{detail.scan_type || 'N/A'}
151+
</span>
152+
</td>
87153
<td>
88154
<span
89155
className="vulnerability-table__severity"
@@ -111,6 +177,9 @@ const RiskDashboardPage = () => {
111177
{details.map((detail, index) => (
112178
<div key={index} className="vulnerability-card">
113179
<div className="vulnerability-card__header">
180+
<span className="vulnerability-card__scan-type">
181+
{detail.scan_type || 'N/A'}
182+
</span>
114183
<span
115184
className="vulnerability-card__severity"
116185
style={{
@@ -150,8 +219,9 @@ const RiskDashboardPage = () => {
150219

151220
return (
152221
<>
222+
<ScanTypeFilter />
153223
<RiskChart risks={risks} />
154-
<VulnerabilityTable details={details} />
224+
<VulnerabilityTable details={filteredDetails} />
155225
</>
156226
);
157227
};

0 commit comments

Comments
 (0)