refactor: JSON data column for findings, code snippets captured and displayed
This commit is contained in:
@@ -21,9 +21,9 @@ async def list_findings(
|
||||
):
|
||||
q = select(Finding)
|
||||
if rule:
|
||||
q = q.where(Finding.rule == rule)
|
||||
q = q.where(func.json_extract(Finding.data, "$.rule") == rule)
|
||||
if severity:
|
||||
q = q.where(Finding.severity == severity)
|
||||
q = q.where(func.json_extract(Finding.data, "$.severity") == severity)
|
||||
if scan_id:
|
||||
q = q.where(Finding.scan_id == scan_id)
|
||||
|
||||
@@ -38,10 +38,7 @@ async def list_findings(
|
||||
{
|
||||
"id": f.id,
|
||||
"scan_id": f.scan_id,
|
||||
"rule": f.rule,
|
||||
"severity": f.severity,
|
||||
"message": f.message,
|
||||
"location": f.location,
|
||||
**f.data,
|
||||
"created_at": f.created_at.isoformat() if f.created_at else None,
|
||||
}
|
||||
for f in findings
|
||||
|
||||
@@ -84,12 +84,13 @@ async def get_package(
|
||||
if not scans:
|
||||
return {"detail": "Not found"}
|
||||
|
||||
all_findings = []
|
||||
all_findings: list[dict] = []
|
||||
for s in scans:
|
||||
findings = (
|
||||
(await session.execute(select(Finding).where(Finding.scan_id == s.id))).scalars().all()
|
||||
)
|
||||
all_findings.extend(f.__dict__ for f in findings)
|
||||
for f in findings:
|
||||
all_findings.append({"id": f.id, **f.data})
|
||||
|
||||
return {
|
||||
"name": scans[0].package_name,
|
||||
@@ -107,14 +108,5 @@ async def get_package(
|
||||
}
|
||||
for s in scans
|
||||
],
|
||||
"findings": [
|
||||
{
|
||||
"id": f["id"],
|
||||
"rule": f.get("rule"),
|
||||
"severity": f.get("severity"),
|
||||
"message": f.get("message"),
|
||||
"location": f.get("location"),
|
||||
}
|
||||
for f in all_findings
|
||||
],
|
||||
"findings": all_findings,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""REST API for scans."""
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy import func, select, text
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
@@ -63,9 +63,12 @@ async def scan_stats(session: AsyncSession = Depends(get_session)):
|
||||
|
||||
top_rules = (
|
||||
await session.execute(
|
||||
select(Finding.rule, func.count(Finding.id).label("cnt"))
|
||||
.group_by(Finding.rule)
|
||||
.order_by(func.count(Finding.id).desc())
|
||||
select(
|
||||
func.json_extract(Finding.data, "$.rule").label("rule"),
|
||||
func.count(Finding.id).label("cnt"),
|
||||
)
|
||||
.group_by(text("rule"))
|
||||
.order_by(text("cnt DESC"))
|
||||
.limit(10)
|
||||
)
|
||||
).all()
|
||||
@@ -103,14 +106,5 @@ async def get_scan(scan_id: int, session: AsyncSession = Depends(get_session)):
|
||||
"started_at": scan.started_at.isoformat() if scan.started_at else None,
|
||||
"finished_at": scan.finished_at.isoformat() if scan.finished_at else None,
|
||||
"error_message": scan.error_message,
|
||||
"findings": [
|
||||
{
|
||||
"id": f.id,
|
||||
"rule": f.rule,
|
||||
"severity": f.severity,
|
||||
"message": f.message,
|
||||
"location": f.location,
|
||||
}
|
||||
for f in scan.findings
|
||||
],
|
||||
"findings": [{"id": f.id, **f.data} for f in scan.findings],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user