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.
@@ -195,7 +195,7 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
195
195
 
196
196
  [[package]]
197
197
  name = "corgea"
198
- version = "1.3.0"
198
+ version = "1.3.1"
199
199
  dependencies = [
200
200
  "clap",
201
201
  "dirs",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "corgea"
3
- version = "1.3.0"
3
+ version = "1.3.1"
4
4
  edition = "2021"
5
5
 
6
6
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: corgea-cli
3
- Version: 1.3.0
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://cdn.loom.com/sessions/thumbnails/0d3ed94d1f01401a86906fc9713ee709-with-play.gif)](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
+ ```
@@ -0,0 +1,7 @@
1
+ use std::env;
2
+
3
+ pub fn debug(input: &str) {
4
+ if env::var("DEBUG").is_ok() {
5
+ println!("DEBUG: {}", input);
6
+ }
7
+ }
@@ -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() {
@@ -2,6 +2,7 @@ mod login;
2
2
  mod config;
3
3
  mod scan;
4
4
  mod cicd;
5
+ mod log;
5
6
 
6
7
  use std::str::FromStr;
7
8
  use clap::{Parser, Subcommand};
@@ -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
- // checkmarx
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::new();
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
- let client = reqwest::blocking::Client::new();
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
- let client = reqwest::blocking::Client::new();
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