1use std::fmt;
2use std::path::{Path, PathBuf};
3
4use serde::{Deserialize, Serialize};
5
6use crate::registry::package::PackageMetadata;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
10pub enum Severity {
11 Info,
12 Low,
13 Medium,
14 High,
15 Critical,
16}
17
18impl fmt::Display for Severity {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 match self {
21 Severity::Info => write!(f, "INFO"),
22 Severity::Low => write!(f, "LOW"),
23 Severity::Medium => write!(f, "MEDIUM"),
24 Severity::High => write!(f, "HIGH"),
25 Severity::Critical => write!(f, "CRITICAL"),
26 }
27 }
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct Finding {
33 pub severity: Severity,
34 pub category: FindingCategory,
35 pub title: String,
36 pub description: String,
37 pub file: Option<String>,
39 pub line: Option<usize>,
41 pub snippet: Option<String>,
43}
44
45#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
47pub enum FindingCategory {
48 CodeExecution,
50 NetworkAccess,
52 ProcessSpawn,
54 FileSystemAccess,
56 Obfuscation,
58 InstallScript,
60 EnvAccess,
62 Suspicious,
64 MaintainerChange,
66 HallucinatedPackage,
68 KnownVulnerability,
70 DependencyRisk,
72 Provenance,
74 BinaryFile,
76 DataFlow,
78}
79
80impl fmt::Display for FindingCategory {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 match self {
83 FindingCategory::CodeExecution => write!(f, "Code Execution"),
84 FindingCategory::NetworkAccess => write!(f, "Network Access"),
85 FindingCategory::ProcessSpawn => write!(f, "Process Spawn"),
86 FindingCategory::FileSystemAccess => write!(f, "File System Access"),
87 FindingCategory::Obfuscation => write!(f, "Obfuscation"),
88 FindingCategory::InstallScript => write!(f, "Install Script"),
89 FindingCategory::EnvAccess => write!(f, "Env Access"),
90 FindingCategory::Suspicious => write!(f, "Suspicious"),
91 FindingCategory::MaintainerChange => write!(f, "Maintainer Change"),
92 FindingCategory::HallucinatedPackage => write!(f, "Hallucinated Package"),
93 FindingCategory::KnownVulnerability => write!(f, "Known Vulnerability"),
94 FindingCategory::DependencyRisk => write!(f, "Dependency Risk"),
95 FindingCategory::Provenance => write!(f, "Provenance"),
96 FindingCategory::BinaryFile => write!(f, "Binary File"),
97 FindingCategory::DataFlow => write!(f, "Data Flow"),
98 }
99 }
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct AnalysisReport {
105 pub package_name: String,
106 pub version: String,
107 pub findings: Vec<Finding>,
108 pub risk_score: f64,
109 pub risk_label: RiskLabel,
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub enum RiskLabel {
114 Clean,
115 Low,
116 Medium,
117 High,
118 Critical,
119}
120
121pub struct AnalysisContext<'a> {
123 pub name: &'a str,
124 pub version: &'a str,
125 pub files: &'a [(PathBuf, String)],
126 pub package_json: &'a serde_json::Value,
127 pub metadata: &'a PackageMetadata,
128 pub package_dir: &'a Path,
129}
130
131impl fmt::Display for RiskLabel {
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 match self {
134 RiskLabel::Clean => write!(f, "CLEAN"),
135 RiskLabel::Low => write!(f, "LOW RISK"),
136 RiskLabel::Medium => write!(f, "MEDIUM RISK"),
137 RiskLabel::High => write!(f, "HIGH RISK"),
138 RiskLabel::Critical => write!(f, "DO NOT INSTALL"),
139 }
140 }
141}