Skip to content
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ conviso --help
- Tasks (only valid YAML): `python -m conviso.app tasks list --company-id 443 --project-id 26102 --only-valid`
- Tasks (create with inline YAML): `python -m conviso.app tasks create --company-id 443 --label "Quick Task" --yaml "name: quick\nsteps:\n - action: echo\n message: ok"`
- Vulnerabilities: `python -m conviso.app vulns list --company-id 443 --severities HIGH,CRITICAL --asset-tags cloud --all`
- Vulnerabilities (last 7 days): `python -m conviso.app vulns list --company-id 443 --days-back 7 --severities HIGH,CRITICAL --all`

Output options: `--format table|json|csv`, `--output path` to save JSON/CSV.

Expand Down
11 changes: 11 additions & 0 deletions src/conviso/commands/vulnerabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import typer
from typing import Optional
import json
from datetime import date, timedelta
from conviso.core.notifier import info, error, summary, success
from conviso.clients.client_graphql import graphql_request
from conviso.core.output_manager import export_data
Expand All @@ -26,6 +27,7 @@ def list_vulnerabilities(
project_types: Optional[str] = typer.Option(None, "--project-types", help="Comma-separated project types (e.g. PENETRATION_TEST, WEB_PENETRATION_TESTING)."),
cves: Optional[str] = typer.Option(None, "--cves", help="Comma-separated CVE identifiers."),
issue_types: Optional[str] = typer.Option(None, "--types", help="Comma-separated failure types (e.g. WEB_VULNERABILITY, DAST_FINDING, SAST_FINDING, SOURCE_CODE_VULNERABILITY, NETWORK_VULNERABILITY, SCA_FINDING)."),
days_back: Optional[int] = typer.Option(None, "--days-back", help="Filter by created date in the last N days (sets --created-start automatically)."),
created_start: Optional[str] = typer.Option(None, "--created-start", help="Created at >= (YYYY-MM-DD)."),
created_end: Optional[str] = typer.Option(None, "--created-end", help="Created at <= (YYYY-MM-DD)."),
risk_until_start: Optional[str] = typer.Option(None, "--risk-until-start", help="Risk accepted until >= (YYYY-MM-DD)."),
Expand Down Expand Up @@ -156,6 +158,15 @@ def _split_strs(value: Optional[str]):
if business_impact_list:
business_impact_list = [b.upper() for b in business_impact_list]

if days_back is not None:
if days_back < 0:
error("--days-back must be >= 0.")
raise typer.Exit(code=1)
if created_start:
error("Use either --days-back or --created-start, not both.")
raise typer.Exit(code=1)
created_start = (date.today() - timedelta(days=days_back)).isoformat()

created_range = None
if created_start or created_end:
created_range = {"startDate": created_start, "endDate": created_end}
Expand Down
Loading