Skip to content

Commit 5335018

Browse files
authored
feat(vulns): add --status filtering (#19)
# Description This PR adds native --status filtering to `python -m conviso.app vulns list`, aligned with the Conviso Platform `IssueStatusLabel` enum (CREATED, DRAFT, IDENTIFIED, IN_PROGRESS, AWAITING_VALIDATION, FIX_ACCEPTED, RISK_ACCEPTED, FALSE_POSITIVE, SUPPRESSED). The CLI validates the input (case-insensitive, comma-separated) and forwards it to the GraphQL layer so the filtering is performed server-side. README and VERSION were also updated to reflect the new option. # How to Test 1. Check that the flag exists: Run `python -m conviso.app vulns list --help` Confirm `--status` is listed among the options. 2. Validate error handling for invalid values: Run `python -m conviso.app vulns list --company-id <ID> --status BAD --per-page 1` Expected behavior: the command should fail fast with a message listing the allowed status values. 3. Verify correct server-side filtering: Run `python -m conviso.app vulns list --company-id <ID> --status CREATED --all` Expected behavior: returned vulnerabilities should only have status `CREATED`. 4. Verify multi-status filtering: Run `python -m conviso.app vulns list --company-id <ID> --status CREATED,RISK_ACCEPTED --all` Expected behavior: returned vulnerabilities should only have status `CREATED` or `RISK_ACCEPTED`.
2 parents b0db123 + e523e93 commit 5335018

3 files changed

Lines changed: 23 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ conviso --help
9696
- Tasks (only valid YAML): `python -m conviso.app tasks list --company-id 443 --project-id 26102 --only-valid`
9797
- 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"`
9898
- Vulnerabilities: `python -m conviso.app vulns list --company-id 443 --severities HIGH,CRITICAL --asset-tags cloud --all`
99+
- Vulnerabilities: `python -m conviso.app vulns list --company-id 443 --status RISK_ACCEPTED,AWAITING_VALIDATION --all`
99100
- Vulnerabilities (last 7 days): `python -m conviso.app vulns list --company-id 443 --days-back 7 --severities HIGH,CRITICAL --all`
100101
- Vulnerabilities by author: `python -m conviso.app vulns list --company-id 443 --author "Fernando" --all`
101102
- Vulnerabilities with local free-text search: `python -m conviso.app vulns list --company-id 443 --all --grep "jwt"`

src/conviso/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.3.6
1+
0.3.7

src/conviso/commands/vulnerabilities.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def list_vulnerabilities(
2929
asset_ids: Optional[str] = typer.Option(None, "--asset-ids", "-a", help="Comma-separated asset IDs to filter."),
3030
project_ids: Optional[str] = typer.Option(None, "--project-ids", "-P", help="Comma-separated project IDs to filter."),
3131
severities: Optional[str] = typer.Option(None, "--severities", "-s", help="Comma-separated severities (NOTIFICATION,LOW,MEDIUM,HIGH,CRITICAL)."),
32+
status: Optional[str] = typer.Option(None,"--status",help="Comma-separated vulnerability status labels (CREATED,DRAFT,IDENTIFIED,IN_PROGRESS,AWAITING_VALIDATION,FIX_ACCEPTED,RISK_ACCEPTED,FALSE_POSITIVE,SUPPRESSED)."),
3233
asset_tags: Optional[str] = typer.Option(None, "--asset-tags", "-t", help="Comma-separated asset tags."),
3334
project_types: Optional[str] = typer.Option(None, "--project-types", help="Comma-separated project types (e.g. PENETRATION_TEST, WEB_PENETRATION_TESTING)."),
3435
cves: Optional[str] = typer.Option(None, "--cves", help="Comma-separated CVE identifiers."),
@@ -77,6 +78,17 @@ def list_vulnerabilities(
7778
fmt_lower = fmt.lower()
7879

7980
SEVERITY_ALLOWED = {"NOTIFICATION", "LOW", "MEDIUM", "HIGH", "CRITICAL"}
81+
STATUS_ALLOWED = {
82+
"CREATED",
83+
"DRAFT",
84+
"IDENTIFIED",
85+
"IN_PROGRESS",
86+
"AWAITING_VALIDATION",
87+
"FIX_ACCEPTED",
88+
"RISK_ACCEPTED",
89+
"FALSE_POSITIVE",
90+
"SUPPRESSED",
91+
}
8092
ATTACK_SURFACE_ALLOWED = {"INTERNET_FACING", "INTERNAL", "NOT_DEFINED"}
8193
DATA_CLASS_ALLOWED = {"PII", "PAYMENT_CARD_INDUSTRY", "NON_SENSITIVE", "NOT_DEFINED"}
8294
BUSINESS_IMPACT_ALLOWED = {"LOW", "MEDIUM", "HIGH", "NOT_DEFINED"}
@@ -418,6 +430,13 @@ def _split_strs(value: Optional[str]):
418430
except ValueError as exc:
419431
error(str(exc))
420432
raise typer.Exit(code=1)
433+
status_list = None
434+
if status:
435+
try:
436+
status_list = validate_csv_choices(status, STATUS_ALLOWED, "--status")
437+
except ValueError as exc:
438+
error(str(exc))
439+
raise typer.Exit(code=1)
421440
asset_tags_list = _split_strs(asset_tags)
422441
project_types_list = _split_strs(project_types)
423442
if project_types_list:
@@ -468,6 +487,8 @@ def _split_strs(value: Optional[str]):
468487
filters["projectIds"] = projects_list
469488
if severities_list:
470489
filters["severities"] = severities_list
490+
if status_list:
491+
filters["statuses"] = status_list
471492
if asset_tags_list:
472493
filters["assetTags"] = asset_tags_list
473494
if project_types_list:

0 commit comments

Comments
 (0)