corgea-cli 1.3.0__tar.gz → 1.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/Cargo.lock +1 -1
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/Cargo.toml +1 -1
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/PKG-INFO +17 -1
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/README.md +16 -0
- corgea_cli-1.3.1/src/log.rs +7 -0
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/src/login.rs +2 -0
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/src/main.rs +1 -0
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/src/scan.rs +52 -4
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/.github/workflows/release.yml +0 -0
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/.gitignore +0 -0
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/LICENSE +0 -0
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/build_release.sh +0 -0
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/pyproject.toml +0 -0
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/src/cicd.rs +0 -0
- {corgea_cli-1.3.0 → corgea_cli-1.3.1}/src/config.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: corgea-cli
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.1
|
|
4
4
|
Classifier: Development Status :: 5 - Production/Stable
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -36,3 +36,19 @@ Corgea one-line command to upload SAST results. This command will run your scann
|
|
|
36
36
|
|
|
37
37
|
</Card>
|
|
38
38
|
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
### Using pip
|
|
42
|
+
```
|
|
43
|
+
pip install corgea-cli
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Manual Installation
|
|
47
|
+
You can get the latest binaries for your OS from https://github.com/Corgea/cli/releases.
|
|
48
|
+
|
|
49
|
+
### Setup
|
|
50
|
+
Once the binary is installed, login with your token from the Corgea app.
|
|
51
|
+
```
|
|
52
|
+
corgea login <token>
|
|
53
|
+
```
|
|
54
|
+
|
|
@@ -9,3 +9,19 @@ Corgea one-line command to upload SAST results. This command will run your scann
|
|
|
9
9
|
[](https://www.loom.com/share/0d3ed94d1f01401a86906fc9713ee709?sid=b11c1f5a-66ff-4dbf-a83a-c9bea15a5d7b)
|
|
10
10
|
|
|
11
11
|
</Card>
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
### Using pip
|
|
16
|
+
```
|
|
17
|
+
pip install corgea-cli
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Manual Installation
|
|
21
|
+
You can get the latest binaries for your OS from https://github.com/Corgea/cli/releases.
|
|
22
|
+
|
|
23
|
+
### Setup
|
|
24
|
+
Once the binary is installed, login with your token from the Corgea app.
|
|
25
|
+
```
|
|
26
|
+
corgea login <token>
|
|
27
|
+
```
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
use reqwest;
|
|
2
2
|
use std::collections::HashMap;
|
|
3
3
|
use std::error::Error;
|
|
4
|
+
use crate::log::debug;
|
|
4
5
|
|
|
5
6
|
pub fn verify_token(token: &str, corgea_url: &str) -> Result<bool, Box<dyn Error>> {
|
|
6
7
|
let url = format!("{}/api/cli/verify/{}", corgea_url, token);
|
|
8
|
+
debug(&format!("GET: {}", url));
|
|
7
9
|
let response = reqwest::blocking::get(url)?;
|
|
8
10
|
|
|
9
11
|
if response.status().is_success() {
|
|
@@ -7,6 +7,7 @@ use uuid::Uuid;
|
|
|
7
7
|
use std::path::Path;
|
|
8
8
|
use std::process::Command;
|
|
9
9
|
use crate::cicd::{*};
|
|
10
|
+
use crate::log::debug;
|
|
10
11
|
|
|
11
12
|
pub fn run_command(base_cmd: &String, mut command: Command) -> String {
|
|
12
13
|
match which::which(base_cmd) {
|
|
@@ -90,6 +91,8 @@ pub fn read_file_report(config: &Config, file_path: &str) {
|
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
pub fn parse_scan(config: &Config, input: String, save_to_file: bool) {
|
|
94
|
+
debug("Parsing the scan report json");
|
|
95
|
+
|
|
93
96
|
let mut paths: Vec<String> = Vec::new();
|
|
94
97
|
let mut scanner = String::new();
|
|
95
98
|
let data: std::result::Result<Value, _> = serde_json::from_str(&input);
|
|
@@ -99,6 +102,7 @@ pub fn parse_scan(config: &Config, input: String, save_to_file: bool) {
|
|
|
99
102
|
let schema = data.get("$schema").and_then(|v| v.as_str()).unwrap_or("unknown");
|
|
100
103
|
|
|
101
104
|
if input.contains("semgrep.dev") {
|
|
105
|
+
debug("Detected semgrep schema");
|
|
102
106
|
scanner = "semgrep".to_string();
|
|
103
107
|
if let Some(results) = data.get("results").and_then(|v| v.as_array()) {
|
|
104
108
|
for result in results {
|
|
@@ -108,13 +112,16 @@ pub fn parse_scan(config: &Config, input: String, save_to_file: bool) {
|
|
|
108
112
|
}
|
|
109
113
|
}
|
|
110
114
|
} else if schema.contains("sarif") {
|
|
115
|
+
debug("Detected sarif schema");
|
|
111
116
|
let run = data.get("runs").and_then(|v| v.as_array()).and_then(|v| v.get(0));
|
|
112
117
|
let driver = run.and_then(|v| v.get("tool")).and_then(|v| v.get("driver")).and_then(|v| v.get("name"));
|
|
113
118
|
let tool = driver.and_then(|v| v.as_str()).unwrap_or("unknown");
|
|
114
119
|
|
|
115
120
|
if tool == "SnykCode" {
|
|
121
|
+
debug("Detected snyk version of sarif schema");
|
|
116
122
|
scanner = "snyk".to_string();
|
|
117
123
|
} else if tool == "CodeQL" {
|
|
124
|
+
debug("Detected codeql version of sarif schema");
|
|
118
125
|
scanner = "codeql".to_string();
|
|
119
126
|
} else {
|
|
120
127
|
eprintln!("{} is not supported as this time.", tool);
|
|
@@ -136,8 +143,9 @@ pub fn parse_scan(config: &Config, input: String, save_to_file: bool) {
|
|
|
136
143
|
}
|
|
137
144
|
}
|
|
138
145
|
}
|
|
139
|
-
|
|
146
|
+
// checkmarx report generated by CLI
|
|
140
147
|
} else if input.contains("Cx") && data.get("results").is_some() && data.get("scanID").is_some() {
|
|
148
|
+
debug("Detected checkmarx cli schema");
|
|
141
149
|
scanner = "checkmarx".to_string();
|
|
142
150
|
if let Some(results) = data.get("results").and_then(|v| v.as_array()) {
|
|
143
151
|
for result in results {
|
|
@@ -154,6 +162,37 @@ pub fn parse_scan(config: &Config, input: String, save_to_file: bool) {
|
|
|
154
162
|
}
|
|
155
163
|
}
|
|
156
164
|
}
|
|
165
|
+
// for checkmarx report generated by web
|
|
166
|
+
} else if input.contains("Cx") && data.get("scanResults").is_some() && data.get("reportId").is_some() {
|
|
167
|
+
debug("Detected checkmarx web schema");
|
|
168
|
+
scanner = "checkmarx".to_string();
|
|
169
|
+
if let Some(scan_results) = data.get("scanResults") {
|
|
170
|
+
if let Some(sast) = scan_results.get("sast") {
|
|
171
|
+
if let Some(languges) = sast.get("languages").and_then(|v| v.as_array()) {
|
|
172
|
+
for language in languges {
|
|
173
|
+
if let Some(queries) = language.get("queries").and_then(|v| v.as_array()) {
|
|
174
|
+
for query in queries {
|
|
175
|
+
if let Some(vulns) = query.get("vulnerabilities").and_then(|v| v.as_array()) {
|
|
176
|
+
for vuln in vulns {
|
|
177
|
+
if let Some(nodes) = vuln.get("nodes").and_then(|v| v.as_array()) {
|
|
178
|
+
for node in nodes {
|
|
179
|
+
if let Some(path) = node.get("fileName") {
|
|
180
|
+
if let Some(truncated_path) = path.as_str() {
|
|
181
|
+
paths.push(truncated_path.get(1..).unwrap_or("").to_string());
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
} else {
|
|
195
|
+
debug("Couldn't detect what kind of report this is.")
|
|
157
196
|
}
|
|
158
197
|
}
|
|
159
198
|
Err(e) => {
|
|
@@ -183,6 +222,7 @@ fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input: Stri
|
|
|
183
222
|
let project;
|
|
184
223
|
|
|
185
224
|
if in_ci {
|
|
225
|
+
debug("Running in CI");
|
|
186
226
|
project = format!("{}-{}",
|
|
187
227
|
github_env_vars.get("GITHUB_REPOSITORY").expect("Failed to get GITHUB_REPOSITORY").to_string(),
|
|
188
228
|
github_env_vars.get("GITHUB_PR").expect("Failed to get GITHUB_REPOSITORY").to_string())
|
|
@@ -196,7 +236,10 @@ fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input: Stri
|
|
|
196
236
|
let git_config_upload_url = format!(
|
|
197
237
|
"{}/api/cli/git-config-upload?token={}&run_id={}", base_url, token, run_id
|
|
198
238
|
);
|
|
199
|
-
let client = reqwest::blocking::Client::
|
|
239
|
+
let client = reqwest::blocking::Client::builder()
|
|
240
|
+
.timeout(std::time::Duration::from_secs(5 * 60))
|
|
241
|
+
.build()
|
|
242
|
+
.expect("Failed to build client");
|
|
200
243
|
|
|
201
244
|
println!("Uploading required files for the scan...");
|
|
202
245
|
|
|
@@ -215,13 +258,15 @@ fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input: Stri
|
|
|
215
258
|
let src_upload_url = format!(
|
|
216
259
|
"{}/api/cli/code-upload?token={}&run_id={}&path={}", base_url, token, run_id, path
|
|
217
260
|
);
|
|
261
|
+
debug(&format!("Uploading file: {}", path));
|
|
218
262
|
let fp = Path::new(&path);
|
|
219
263
|
|
|
220
264
|
let form = reqwest::blocking::multipart::Form::new()
|
|
221
265
|
.file("file", fp)
|
|
222
266
|
.expect("Failed to read file");
|
|
223
267
|
|
|
224
|
-
|
|
268
|
+
|
|
269
|
+
debug(&format!("POST: {}", src_upload_url));
|
|
225
270
|
let res = client.post(&src_upload_url)
|
|
226
271
|
.multipart(form)
|
|
227
272
|
.send();
|
|
@@ -245,6 +290,7 @@ fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input: Stri
|
|
|
245
290
|
println!("Uploading the scan...");
|
|
246
291
|
|
|
247
292
|
// main scan upload
|
|
293
|
+
debug(&format!("POST: {}", scan_upload_url));
|
|
248
294
|
let res = client.post(scan_upload_url)
|
|
249
295
|
.header(header::CONTENT_TYPE, "application/json")
|
|
250
296
|
.body(input.clone())
|
|
@@ -267,11 +313,12 @@ fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input: Stri
|
|
|
267
313
|
let git_config_path = Path::new(".git/config");
|
|
268
314
|
|
|
269
315
|
if git_config_path.exists() {
|
|
316
|
+
debug("Uploading .git/config");
|
|
270
317
|
let form = reqwest::blocking::multipart::Form::new()
|
|
271
318
|
.file("file", git_config_path)
|
|
272
319
|
.expect("Failed to read file");
|
|
273
320
|
|
|
274
|
-
|
|
321
|
+
debug(&format!("POST: {}", git_config_upload_url));
|
|
275
322
|
let res = client.post(&git_config_upload_url)
|
|
276
323
|
.multipart(form)
|
|
277
324
|
.send();
|
|
@@ -306,6 +353,7 @@ fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input: Stri
|
|
|
306
353
|
}
|
|
307
354
|
};
|
|
308
355
|
|
|
356
|
+
debug(&format!("POST: {}", ci_data_upload_url));
|
|
309
357
|
let _res = client.post(ci_data_upload_url)
|
|
310
358
|
.header(header::CONTENT_TYPE, "application/json")
|
|
311
359
|
.body(github_env_vars_json_string)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|