From bb87b40fe8e68ed6931cfe9e6d0fb0ae3872e77a Mon Sep 17 00:00:00 2001 From: Wagner Elias Date: Fri, 20 Feb 2026 14:56:40 -0300 Subject: [PATCH] feat(vulns): add --days-back filter shortcut --- README.md | 1 + src/conviso/commands/vulnerabilities.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/README.md b/README.md index 8ea8425..c4b6fef 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/src/conviso/commands/vulnerabilities.py b/src/conviso/commands/vulnerabilities.py index c5fa12d..5d1694b 100644 --- a/src/conviso/commands/vulnerabilities.py +++ b/src/conviso/commands/vulnerabilities.py @@ -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 @@ -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)."), @@ -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}