-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
156 lines (135 loc) · 4.54 KB
/
main.py
File metadata and controls
156 lines (135 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python3
"""
CODE SENTINEL - CLI Entry Point
Simple command-line interface for running scans.
"""
import sys
import argparse
from pathlib import Path
from rich.console import Console
from src.scanner import scan
console = Console()
def main():
"""Main CLI entry point."""
parser = argparse.ArgumentParser(
description="CODE SENTINEL - AI-Powered Security Scanner",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python main.py scan ./my-project
python main.py scan ./app.py --model codellama
python main.py scan . --prompt detailed
"""
)
subparsers = parser.add_subparsers(dest="command", help="Commands")
# Scan command
scan_parser = subparsers.add_parser("scan", help="Scan code for vulnerabilities")
scan_parser.add_argument(
"path",
type=str,
help="Path to file or directory to scan"
)
scan_parser.add_argument(
"--model",
type=str,
default=None, # Let scanner choose default based on client
help="AI model to use (default varies by client)"
)
scan_parser.add_argument(
"--client",
type=str,
default="ollama",
choices=["ollama", "groq", "huggingface", "hf"],
help="AI client type (default: ollama)"
)
scan_parser.add_argument(
"--prompt",
type=str,
default="standard",
choices=["standard", "detailed", "quick"],
help="Prompt template type (default: standard)"
)
scan_parser.add_argument(
"--quiet",
action="store_true",
help="Minimal output"
)
scan_parser.add_argument(
"--api-key",
type=str,
help="API key for cloud providers (or set via environment variable)"
)
scan_parser.add_argument(
"--format",
type=str,
default="terminal",
choices=["terminal", "html", "json"],
help="Output format (default: terminal)"
)
scan_parser.add_argument(
"--output",
type=str,
help="Output file path (required for html/json formats)"
)
scan_parser.add_argument(
"--no-cache",
action="store_true",
help="Disable caching (force fresh scan)"
)
args = parser.parse_args()
# Show help if no command
if not args.command:
parser.print_help()
return
# Handle scan command
if args.command == "scan":
path = Path(args.path)
if not path.exists():
console.print(f"[red]✗ Path does not exist: {path}[/red]")
sys.exit(1)
# Validate output requirements
if args.format in ["html", "json"] and not args.output:
console.print(f"[red]✗ --output required for {args.format} format[/red]")
sys.exit(1)
# Prepare client kwargs
client_kwargs = {}
if args.model: # Only add model if specified
client_kwargs["model"] = args.model
if args.api_key:
client_kwargs["api_key"] = args.api_key
# Determine verbosity based on format
verbose = not args.quiet and args.format == "terminal"
results = scan(
path=str(path),
client_type=args.client,
prompt_type=args.prompt,
verbose=verbose,
use_cache=not args.no_cache,
**client_kwargs
)
if not results:
sys.exit(1)
# Generate report based on format
if args.format == "html":
from src.reporter import Reporter
output_file = Reporter.generate_html(results, args.output)
console.print(f"[green]✓ HTML report saved to: {output_file}[/green]")
elif args.format == "json":
from src.reporter import Reporter
output_file = Reporter.generate_json(results, args.output)
console.print(f"[green]✓ JSON report saved to: {output_file}[/green]")
# Exit with error if any scan failed or critical/high vulnerabilities found
failed = sum(1 for r in results if not r.success)
if failed > 0:
sys.exit(1)
# Check for critical/high severity vulnerabilities
from src.models import Severity
critical_high = sum(
1 for r in results
for v in r.vulnerabilities
if v.severity in [Severity.CRITICAL, Severity.HIGH]
)
if critical_high > 0:
sys.exit(1)
if __name__ == "__main__":
main()