corgea-cli 1.8.4__tar.gz → 1.8.7__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.
Files changed (38) hide show
  1. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/Cargo.lock +76 -1
  2. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/Cargo.toml +3 -1
  3. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/PKG-INFO +1 -1
  4. corgea_cli-1.8.7/skills/corgea/SKILL.md +168 -0
  5. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/inspect.rs +3 -3
  6. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/list.rs +4 -4
  7. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/main.rs +4 -2
  8. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/scan.rs +78 -13
  9. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/scanners/blast.rs +15 -15
  10. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/utils/api.rs +127 -65
  11. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/wait.rs +3 -3
  12. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/.github/workflows/npm-publish.yml +0 -0
  13. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/.github/workflows/release-binaries.yml +0 -0
  14. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/.github/workflows/release.yml +0 -0
  15. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/.github/workflows/test.yml +0 -0
  16. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/.github/workflows/update_docs..yml +0 -0
  17. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/.gitignore +0 -0
  18. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/LICENSE +0 -0
  19. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/README.md +0 -0
  20. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/bin/corgea.js +0 -0
  21. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/build_release.sh +0 -0
  22. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/package.json +0 -0
  23. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/pyproject.toml +0 -0
  24. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/scripts/npm/bundle-binaries.js +0 -0
  25. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/authorize.rs +0 -0
  26. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/cicd.rs +0 -0
  27. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/config.rs +0 -0
  28. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/log.rs +0 -0
  29. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/scanners/fortify.rs +0 -0
  30. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/scanners/parsers/checkmarx.rs +0 -0
  31. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/scanners/parsers/coverity.rs +0 -0
  32. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/scanners/parsers/mod.rs +0 -0
  33. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/scanners/parsers/sarif.rs +0 -0
  34. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/scanners/parsers/semgrep.rs +0 -0
  35. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/setup_hooks.rs +0 -0
  36. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/targets.rs +0 -0
  37. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/utils/generic.rs +0 -0
  38. {corgea_cli-1.8.4 → corgea_cli-1.8.7}/src/utils/terminal.rs +0 -0
@@ -293,6 +293,35 @@ version = "0.3.1"
293
293
  source = "registry+https://github.com/rust-lang/crates.io-index"
294
294
  checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
295
295
 
296
+ [[package]]
297
+ name = "cookie"
298
+ version = "0.18.1"
299
+ source = "registry+https://github.com/rust-lang/crates.io-index"
300
+ checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
301
+ dependencies = [
302
+ "percent-encoding",
303
+ "time",
304
+ "version_check",
305
+ ]
306
+
307
+ [[package]]
308
+ name = "cookie_store"
309
+ version = "0.21.1"
310
+ source = "registry+https://github.com/rust-lang/crates.io-index"
311
+ checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9"
312
+ dependencies = [
313
+ "cookie",
314
+ "document-features",
315
+ "idna",
316
+ "log",
317
+ "publicsuffix",
318
+ "serde",
319
+ "serde_derive",
320
+ "serde_json",
321
+ "time",
322
+ "url",
323
+ ]
324
+
296
325
  [[package]]
297
326
  name = "core-foundation"
298
327
  version = "0.9.4"
@@ -311,13 +340,14 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
311
340
 
312
341
  [[package]]
313
342
  name = "corgea"
314
- version = "1.8.4"
343
+ version = "1.8.7"
315
344
  dependencies = [
316
345
  "chrono",
317
346
  "clap",
318
347
  "dirs",
319
348
  "git2",
320
349
  "globset",
350
+ "http",
321
351
  "http-body-util",
322
352
  "hyper",
323
353
  "hyper-util",
@@ -478,6 +508,15 @@ dependencies = [
478
508
  "syn",
479
509
  ]
480
510
 
511
+ [[package]]
512
+ name = "document-features"
513
+ version = "0.2.12"
514
+ source = "registry+https://github.com/rust-lang/crates.io-index"
515
+ checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
516
+ dependencies = [
517
+ "litrs",
518
+ ]
519
+
481
520
  [[package]]
482
521
  name = "either"
483
522
  version = "1.15.0"
@@ -1131,6 +1170,12 @@ version = "0.8.0"
1131
1170
  source = "registry+https://github.com/rust-lang/crates.io-index"
1132
1171
  checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
1133
1172
 
1173
+ [[package]]
1174
+ name = "litrs"
1175
+ version = "1.0.0"
1176
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1177
+ checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
1178
+
1134
1179
  [[package]]
1135
1180
  name = "lock_api"
1136
1181
  version = "0.4.14"
@@ -1421,6 +1466,22 @@ dependencies = [
1421
1466
  "unicode-ident",
1422
1467
  ]
1423
1468
 
1469
+ [[package]]
1470
+ name = "psl-types"
1471
+ version = "2.0.11"
1472
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1473
+ checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
1474
+
1475
+ [[package]]
1476
+ name = "publicsuffix"
1477
+ version = "2.3.0"
1478
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1479
+ checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf"
1480
+ dependencies = [
1481
+ "idna",
1482
+ "psl-types",
1483
+ ]
1484
+
1424
1485
  [[package]]
1425
1486
  name = "quick-xml"
1426
1487
  version = "0.36.2"
@@ -1502,6 +1563,8 @@ checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f"
1502
1563
  dependencies = [
1503
1564
  "base64",
1504
1565
  "bytes",
1566
+ "cookie",
1567
+ "cookie_store",
1505
1568
  "futures-channel",
1506
1569
  "futures-core",
1507
1570
  "futures-util",
@@ -1890,10 +1953,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1890
1953
  checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
1891
1954
  dependencies = [
1892
1955
  "deranged",
1956
+ "itoa",
1893
1957
  "num-conv",
1894
1958
  "powerfmt",
1895
1959
  "serde_core",
1896
1960
  "time-core",
1961
+ "time-macros",
1897
1962
  ]
1898
1963
 
1899
1964
  [[package]]
@@ -1902,6 +1967,16 @@ version = "0.1.8"
1902
1967
  source = "registry+https://github.com/rust-lang/crates.io-index"
1903
1968
  checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
1904
1969
 
1970
+ [[package]]
1971
+ name = "time-macros"
1972
+ version = "0.2.27"
1973
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1974
+ checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
1975
+ dependencies = [
1976
+ "num-conv",
1977
+ "time-core",
1978
+ ]
1979
+
1905
1980
  [[package]]
1906
1981
  name = "tinystr"
1907
1982
  version = "0.8.1"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "corgea"
3
- version = "1.8.4"
3
+ version = "1.8.7"
4
4
  edition = "2021"
5
5
  readme = "README.md"
6
6
 
@@ -11,6 +11,7 @@ clap = { version = "4.4.13", features = ["derive"] }
11
11
  dirs = "5.0.1"
12
12
  reqwest = { version = "0.12.23", default-features = false, features = [
13
13
  "blocking",
14
+ "cookies",
14
15
  "json",
15
16
  "multipart",
16
17
  "native-tls",
@@ -34,6 +35,7 @@ chrono = "0.4"
34
35
  tokio = { version = "1.0", features = ["full"] }
35
36
  hyper = { version = "1.0", features = ["full"] }
36
37
  hyper-util = { version = "0.1", features = ["full"] }
38
+ http = "1"
37
39
  http-body-util = "0.1"
38
40
  url = "2.5"
39
41
  open = "5.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: corgea-cli
3
- Version: 1.8.4
3
+ Version: 1.8.7
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -0,0 +1,168 @@
1
+ ---
2
+ name: corgea
3
+ description: Scans code for security vulnerabilities using Corgea's AI-powered BLAST scanner and third-party tools, manages findings, and displays AI-generated fixes. Use when the user needs to scan for security issues, upload scan reports, list or inspect vulnerabilities, view fixes, or integrate security scanning into CI/CD.
4
+ allowed-tools: Shell, Read, Grep, Glob, StrReplace
5
+ ---
6
+
7
+ # Corgea CLI
8
+
9
+ Find and fix security vulnerabilities using AI-powered scanning (BLAST), third-party scanners, and AI-generated fixes.
10
+
11
+ ## Commands
12
+
13
+ ### Scan — `corgea scan [scanner]`
14
+
15
+ Default scanner is `blast` (AI-powered, server-side). Also supports `semgrep` and `snyk` (must be installed separately), blast should be used by default unless the user asked not to.
16
+
17
+ ```bash
18
+ corgea scan # BLAST scan, full project
19
+ corgea scan semgrep # Semgrep scan, upload results
20
+ corgea scan snyk # Snyk Code scan, upload results
21
+ ```
22
+
23
+ #### BLAST Options
24
+
25
+ ```bash
26
+ corgea scan --only-uncommitted # Staged/modified/untracked files only
27
+ corgea scan --target src/,pyproject.toml # Specific paths (comma-separated)
28
+ corgea scan --target "src/**/*.py" # Glob patterns
29
+ corgea scan --target git:diff=origin/main...HEAD # Git diff range
30
+ corgea scan --target git:staged,git:modified # Git selectors
31
+ corgea scan --target - # File list from stdin
32
+ corgea scan --scan-type secrets # Single scan type
33
+ corgea scan --scan-type blast,policy,secrets,pii # Multiple scan types
34
+ corgea scan --scan-type policy --policy 1 # Specific policy ID
35
+ corgea scan --fail-on CR # Exit 1 on critical issues (CR, HI, ME, LO)
36
+ corgea scan --fail # Exit 1 based on project blocking rules
37
+ corgea scan --out-format json --out-file r.json # Export (json, html, sarif, markdown)
38
+ corgea scan --project-name my-service # Override project name
39
+ ```
40
+
41
+ Scan types: `blast` (base AI), `policy` (PolicyIQ), `malicious`, `secrets`, `pii`.
42
+
43
+ `--only-uncommitted` and `--target` are mutually exclusive. `--fail-on` and `--fail` are mutually exclusive.
44
+
45
+ ### Upload — `corgea upload [report]`
46
+
47
+ Upload an existing scan report to Corgea.
48
+
49
+ ```bash
50
+ corgea upload path/to/report.json # JSON, SARIF, Coverity XML
51
+ corgea upload path/to/report.fpr # Fortify FPR
52
+ corgea upload report.sarif --project-name svc # Custom project name
53
+ cat report.json | corgea upload # From stdin
54
+ ```
55
+
56
+ Supported: Semgrep JSON, SARIF, Checkmarx (CLI/Web/XML), Coverity, Fortify FPR.
57
+
58
+ ### Wait — `corgea wait [scan_id]`
59
+
60
+ ```bash
61
+ corgea wait # Wait for latest scan
62
+ corgea wait --scan-id SCAN_ID # Wait for specific scan
63
+ ```
64
+
65
+ ### List — `corgea list` (alias: `corgea ls`)
66
+
67
+ ```bash
68
+ corgea ls # List scans
69
+ corgea ls --issues --scan-id SCAN_ID # Issues for a scan
70
+ corgea ls --sca-issues # SCA (dependency) issues
71
+ corgea ls --issues --page 2 --page-size 10 # Pagination
72
+ corgea ls --issues --scan-id SCAN_ID --json # JSON output
73
+ ```
74
+
75
+ | Flag | Short | Description |
76
+ |------|-------|-------------|
77
+ | `--issues` | `-i` | List code/SAST issues |
78
+ | `--sca-issues` | `-c` | List SCA issues |
79
+ | `--scan-id` | `-s` | Filter to a scan |
80
+ | `--page` | `-p` | Page number |
81
+ | `--page-size` | | Items per page |
82
+ | `--json` | | JSON output |
83
+
84
+ ### Inspect — `corgea inspect <id>`
85
+
86
+ ```bash
87
+ corgea inspect SCAN_ID # Scan overview with issue counts
88
+ corgea inspect --issue ISSUE_ID # Full issue details + fix
89
+ corgea inspect --issue --summary ISSUE_ID # Summary only
90
+ corgea inspect --issue --fix ISSUE_ID # Fix explanation only
91
+ corgea inspect --issue --diff ISSUE_ID # Diff only
92
+ corgea inspect --issue --json ISSUE_ID # JSON output
93
+ ```
94
+
95
+ | Flag | Short | Description |
96
+ |------|-------|-------------|
97
+ | `--issue` | `-i` | Treat ID as issue (default: scan) |
98
+ | `--summary` | `-s` | Summary only |
99
+ | `--fix` | `-f` | Fix explanation only |
100
+ | `--diff` | `-d` | Diff only |
101
+ | `--json` | | JSON output |
102
+
103
+ ### Setup Hooks — `corgea setup-hooks`
104
+
105
+ ```bash
106
+ corgea setup-hooks # Interactive configuration
107
+ corgea setup-hooks --default-config # Default: secrets + PII, fail on LO
108
+ ```
109
+
110
+ Installs a pre-commit hook running `corgea scan blast --only-uncommitted`. Bypass with `git commit --no-verify`.
111
+
112
+ ## Common Workflows
113
+
114
+ ### Scan full project
115
+
116
+ ```bash
117
+ corgea scan
118
+ ```
119
+
120
+ ### Scan uncommitted changes
121
+
122
+ ```bash
123
+ corgea scan --only-uncommitted --fail-on HI
124
+ ```
125
+
126
+ ### Scan a PR diff
127
+
128
+ ```bash
129
+ corgea scan --target git:diff=origin/main...HEAD --fail-on CR
130
+ ```
131
+
132
+ ### Review and apply a fix
133
+
134
+ ```bash
135
+ corgea ls --issues --scan-id SCAN_ID
136
+ corgea inspect --issue --diff ISSUE_ID
137
+ ```
138
+
139
+ ### CI/CD pipeline
140
+
141
+ ```bash
142
+ corgea scan --fail-on CR --out-format sarif --out-file results.sarif
143
+ ```
144
+
145
+ ### Upload third-party reports
146
+
147
+ ```bash
148
+ corgea upload report.json --project-name my-app
149
+ ```
150
+
151
+ ### Export results
152
+
153
+ ```bash
154
+ corgea scan --out-format html --out-file report.html
155
+ corgea scan --out-format sarif --out-file report.sarif
156
+ ```
157
+
158
+ ## Severity Levels
159
+
160
+ `CR` (Critical), `HI` (High), `ME` (Medium), `LO` (Low)
161
+
162
+
163
+
164
+ ## Troubleshooting
165
+
166
+ - **"token invalid" or authentication errors**: The user needs to authenticate with Corgea. Ask them to run `corgea login` (browser OAuth) or `corgea login <API_TOKEN>` to set up credentials. For single-tenant instances, use `corgea login --url https://<instance>.corgea.app <TOKEN>`. Tokens can also be set via the `CORGEA_API_TOKEN` environment variable.
167
+ - **Third-party scanner not found**: `semgrep` or `snyk` must be installed and on `PATH`.
168
+ - **Upload failures**: The CLI retries 3 times per file. Check file paths and permissions.
@@ -19,7 +19,7 @@ pub fn run(
19
19
  println!();
20
20
  if *issues {
21
21
  let show_everything = !*summary && !*fix_explanation && !*fix_diff;
22
- let issue_details = match utils::api::get_issue(&config.get_url(), &config.get_token(), id) {
22
+ let issue_details = match utils::api::get_issue(&config.get_url(), id) {
23
23
  Ok(issue) => issue,
24
24
  Err(e) => {
25
25
  eprintln!("Failed to fetch issue details for issue ID {} with error:\n{}", id, e);
@@ -69,7 +69,7 @@ pub fn run(
69
69
  }
70
70
  }
71
71
  } else {
72
- let scan_details = match utils::api::get_scan(&config.get_url(), &config.get_token(), id) {
72
+ let scan_details = match utils::api::get_scan(&config.get_url(), id) {
73
73
  Ok(details) => details,
74
74
  Err(e) => {
75
75
  eprintln!("Failed to fetch scan details for scan ID {}: {}", id, e);
@@ -92,7 +92,7 @@ pub fn run(
92
92
  print_section("Engine", &scan_details.engine);
93
93
  let created_at = chrono::DateTime::<chrono::Utc>::from(SystemTime::now()).format("%Y-%m-%d %H:%M:%S").to_string();
94
94
  print_section("Created At", &created_at);
95
- match scanners::blast::fetch_and_group_scan_issues(&config.get_url(), &config.get_token(), &scan_details.project) {
95
+ match scanners::blast::fetch_and_group_scan_issues(&config.get_url(), &scan_details.project) {
96
96
  Ok(counts) => {
97
97
  let total_issues = counts.values().sum::<usize>();
98
98
  let order = vec!["CR", "HI", "ME", "LO"];
@@ -8,7 +8,7 @@ pub fn run(config: &Config, issues: &bool, sca_issues: &bool, json: &bool, page:
8
8
  let project_name = utils::generic::get_current_working_directory().unwrap_or("unknown".to_string());
9
9
  println!("");
10
10
  if *sca_issues {
11
- let sca_issues_response = match utils::api::get_sca_issues(&config.get_url(), &config.get_token(), Some((*page).unwrap_or(1)), *page_size, scan_id.clone()) {
11
+ let sca_issues_response = match utils::api::get_sca_issues(&config.get_url(), Some((*page).unwrap_or(1)), *page_size, scan_id.clone()) {
12
12
  Ok(response) => response,
13
13
  Err(e) => {
14
14
  debug(&format!("Error Sending Request: {}", e.to_string()));
@@ -87,7 +87,7 @@ pub fn run(config: &Config, issues: &bool, sca_issues: &bool, json: &bool, page:
87
87
 
88
88
  utils::terminal::print_table(table, Some(sca_issues_response.page), Some(sca_issues_response.total_pages));
89
89
  } else if *issues {
90
- let issues_response = match utils::api::get_scan_issues(&config.get_url(), &config.get_token(), &project_name, Some((*page).unwrap_or(1)), *page_size, scan_id.clone()) {
90
+ let issues_response = match utils::api::get_scan_issues(&config.get_url(), &project_name, Some((*page).unwrap_or(1)), *page_size, scan_id.clone()) {
91
91
  Ok(response) => response,
92
92
  Err(e) => {
93
93
  debug(&format!("Error Sending Request: {}", e.to_string()));
@@ -115,7 +115,7 @@ pub fn run(config: &Config, issues: &bool, sca_issues: &bool, json: &bool, page:
115
115
  if scan_id.is_some() {
116
116
  let mut page: u32 = 1;
117
117
  loop {
118
- match utils::api::check_blocking_rules(&config.get_url(), &config.get_token(), scan_id.as_ref().unwrap(), Some(page)) {
118
+ match utils::api::check_blocking_rules(&config.get_url(), scan_id.as_ref().unwrap(), Some(page)) {
119
119
  Ok(rules) => {
120
120
  if rules.block {
121
121
  render_blocking_rules = true;
@@ -224,7 +224,7 @@ pub fn run(config: &Config, issues: &bool, sca_issues: &bool, json: &bool, page:
224
224
 
225
225
  utils::terminal::print_table(table, issues_response.page, issues_response.total_pages);
226
226
  } else {
227
- let (scans, page, total_pages) = match utils::api::query_scan_list(&config.get_url(), &config.get_token(), Some(&project_name), *page, *page_size) {
227
+ let (scans, page, total_pages) = match utils::api::query_scan_list(&config.get_url(), Some(&project_name), *page, *page_size) {
228
228
  Ok(scans) => {
229
229
  let page = scans.page;
230
230
  let total_pages = scans.total_pages;
@@ -186,7 +186,8 @@ fn main() {
186
186
  eprintln!("No token set.\nPlease run 'corgea login' to authenticate.\nFor more info checkout our docs at Check out our docs at https://docs.corgea.app/install_cli#login-with-the-cli");
187
187
  std::process::exit(1);
188
188
  }
189
- match utils::api::verify_token(config.get_token().as_str(), config.get_url().as_str()) {
189
+ utils::api::set_auth_token(&config.get_token());
190
+ match utils::api::verify_token(config.get_url().as_str()) {
190
191
  Ok(true) => {
191
192
  return;
192
193
  }
@@ -207,7 +208,8 @@ fn main() {
207
208
  match effective_token {
208
209
  Some(token_value) => {
209
210
  let token_source = if token.is_some() { "parameter" } else { "CORGEA_TOKEN environment variable" };
210
- match utils::api::verify_token(&token_value, url.as_deref().unwrap_or(corgea_config.get_url().as_str())) {
211
+ utils::api::set_auth_token(&token_value);
212
+ match utils::api::verify_token(url.as_deref().unwrap_or(corgea_config.get_url().as_str())) {
211
213
  Ok(true) => {
212
214
  corgea_config.set_token(token_value.clone()).expect("Failed to set token");
213
215
  if let Some(url) = url {
@@ -131,8 +131,8 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
131
131
  let github_env_vars = get_github_env_vars();
132
132
 
133
133
  let run_id = Uuid::new_v4().to_string();
134
- let token = config.get_token();
135
134
  let base_url = config.get_url();
135
+ let api_base = "/api/v1";
136
136
  let project;
137
137
 
138
138
  if in_ci {
@@ -143,20 +143,20 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
143
143
  } else {
144
144
  project = utils::generic::determine_project_name(project_name.as_deref());
145
145
  }
146
- let repo_data = std::env::var("REPO_DATA").unwrap_or_else(|_| "".to_string()); //encoded data to forward.
146
+ let repo_data = std::env::var("REPO_DATA").unwrap_or_else(|_| "".to_string());
147
147
 
148
148
  let scan_upload_url = if repo_data.is_empty() {
149
149
  format!(
150
- "{}/api/cli/scan-upload?token={}&engine={}&run_id={}&project={}&ci={}&ci_platform={}", base_url, token, scanner, run_id, project, in_ci, ci_platform
150
+ "{}{}/scan-upload?engine={}&run_id={}&project={}&ci={}&ci_platform={}", base_url, api_base, scanner, run_id, project, in_ci, ci_platform
151
151
  )
152
152
  } else {
153
153
  format!(
154
- "{}/api/cli/scan-upload?token={}&engine={}&run_id={}&project={}&ci={}&ci_platform={}&repo_data={}", base_url, token, scanner, run_id, project, in_ci, ci_platform, repo_data
154
+ "{}{}/scan-upload?engine={}&run_id={}&project={}&ci={}&ci_platform={}&repo_data={}", base_url, api_base, scanner, run_id, project, in_ci, ci_platform, repo_data
155
155
  )
156
156
  };
157
157
 
158
158
  let git_config_upload_url = format!(
159
- "{}/api/cli/git-config-upload?token={}&run_id={}", base_url, token, run_id
159
+ "{}{}/git-config-upload?run_id={}", base_url, api_base, run_id
160
160
  );
161
161
  let client = utils::api::http_client();
162
162
 
@@ -177,7 +177,7 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
177
177
  }
178
178
 
179
179
  let src_upload_url = format!(
180
- "{}/api/cli/code-upload?token={}&run_id={}&path={}", base_url, token, run_id, path
180
+ "{}{}/code-upload?run_id={}&path={}", base_url, api_base, run_id, path
181
181
  );
182
182
  debug(&format!("Uploading file: {}", path));
183
183
  let fp = Path::new(&path);
@@ -198,7 +198,10 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
198
198
  match res {
199
199
  Ok(response) => {
200
200
  if !response.status().is_success() {
201
- eprintln!("Failed to upload file {} {}... retrying", response.status(), path);
201
+ let status = response.status();
202
+ let body = response.text().unwrap_or_else(|_| "Unable to read response body".to_string());
203
+ debug(&format!("Code upload failed with status: {}. Response body: {}", status, body));
204
+ eprintln!("Failed to upload file {} {}... retrying", status, path);
202
205
  std::thread::sleep(std::time::Duration::from_secs(1));
203
206
  attempts += 1;
204
207
  } else {
@@ -231,8 +234,23 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
231
234
  let input_bytes = input.as_bytes();
232
235
  let input_size = input_bytes.len();
233
236
  let max_upload_size = 50 * 1024 * 1024; // 50mb
234
- let chunk_size = 1024 * 1024; // 1mb
235
- let res = if input_size > max_upload_size {
237
+ let chunk_size = match std::env::var("DEBUG_CORGEA_OVERRIDE_REPORT_CHUNK_SIZE") {
238
+ Ok(val) => {
239
+ match val.parse::<usize>() {
240
+ Ok(mb) if mb > 0 => {
241
+ debug(&format!("Overriding report chunk size to {} MB", mb));
242
+ mb * 1024 * 1024
243
+ }
244
+ _ => {
245
+ eprintln!("Invalid DEBUG_CORGEA_OVERRIDE_REPORT_CHUNK_SIZE value '{}', using default 1 MB", val);
246
+ 1024 * 1024
247
+ }
248
+ }
249
+ }
250
+ Err(_) => 1024 * 1024, // default 1mb
251
+ };
252
+ let is_chunked = input_size > max_upload_size;
253
+ let res = if is_chunked {
236
254
  let total_chunks = (input_size + chunk_size - 1) / chunk_size;
237
255
  debug(&format!("Uploading scan in {} chunks", total_chunks));
238
256
  let mut offset = 0usize;
@@ -246,8 +264,38 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
246
264
  .header("Upload-Length", input_size.to_string())
247
265
  .body(chunk.to_vec())
248
266
  .send();
267
+
249
268
  let should_break = match &response {
250
- Ok(res) => !res.status().is_success(),
269
+ Ok(res) => {
270
+ if !res.status().is_success() {
271
+ true
272
+ } else {
273
+ if let Some(server_offset) = res.headers().get("Upload-Offset") {
274
+ let expected_offset = offset + chunk.len();
275
+ if let Ok(server_offset_str) = server_offset.to_str() {
276
+ if let Ok(server_offset_val) = server_offset_str.parse::<usize>() {
277
+ if server_offset_val != expected_offset {
278
+ eprintln!(
279
+ "Upload offset mismatch on chunk {}/{}: server has {} bytes but expected {}. \
280
+ This may indicate that chunks are being routed to different server instances. \
281
+ Please contact support.",
282
+ index + 1, total_chunks, server_offset_val, expected_offset
283
+ );
284
+ true
285
+ } else {
286
+ false
287
+ }
288
+ } else {
289
+ false
290
+ }
291
+ } else {
292
+ false
293
+ }
294
+ } else {
295
+ false
296
+ }
297
+ }
298
+ },
251
299
  Err(_) => true,
252
300
  };
253
301
  last_response = Some(response);
@@ -269,6 +317,8 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
269
317
  let mut sast_scan_id: Option<String> = None;
270
318
  let mut project_id: Option<String> = None;
271
319
 
320
+ let mut upload_failed = false;
321
+
272
322
  match res {
273
323
  Ok(response) => {
274
324
  if response.status().is_success() {
@@ -305,13 +355,24 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
305
355
  }
306
356
  }
307
357
  }
308
- println!("Successfully uploaded scan.");
358
+
359
+ if is_chunked && sast_scan_id.is_none() {
360
+ eprintln!("Failed to upload scan: server did not return a scan ID after all chunks were sent. The scan was not created on the platform.");
361
+ upload_failed = true;
362
+ } else {
363
+ println!("Successfully uploaded scan.");
364
+ }
309
365
  } else {
310
- eprintln!("Failed to upload scan: {}", response.status());
366
+ upload_failed = true;
367
+ let status = response.status();
368
+ let body = response.text().unwrap_or_else(|_| "Unable to read response body".to_string());
369
+ debug(&format!("Scan upload failed with status: {}. Response body: {}", status, body));
370
+ eprintln!("Failed to upload scan: {}", status);
311
371
  }
312
372
  }
313
373
  Err(e) => {
314
374
  eprintln!("Failed to send request: {}", e);
375
+ upload_failed = true;
315
376
  }
316
377
  }
317
378
 
@@ -343,7 +404,7 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
343
404
 
344
405
  if in_ci {
345
406
  let ci_data_upload_url = format!(
346
- "{}/api/cli/ci-data-upload?token={}&run_id={}&platform={}", base_url, token, run_id, ci_platform
407
+ "{}{}/ci-data-upload?run_id={}&platform={}", base_url, api_base, run_id, ci_platform
347
408
  );
348
409
 
349
410
  let mut github_env_vars_json = serde_json::Map::new();
@@ -376,6 +437,10 @@ pub fn upload_scan(config: &Config, paths: Vec<String>, scanner: String, input:
376
437
  }
377
438
  }
378
439
 
440
+ if upload_failed {
441
+ std::process::exit(1);
442
+ }
443
+
379
444
  println!("Successfully scanned using {} and uploaded to Corgea.", scanner);
380
445
 
381
446
  if upload_error_count > 0 {
@@ -180,7 +180,7 @@ pub fn run(
180
180
  let _ = packaging_thread.join();
181
181
  print!("\r{}Project packaged successfully.\n", utils::terminal::set_text_color("", utils::terminal::TerminalColor::Green));
182
182
  println!("\n\nSubmitting scan to Corgea:");
183
- let upload_result = match utils::api::upload_zip(&zip_path, &config.get_token(), &config.get_url(), &project_name, repo_info, scan_type, policy) {
183
+ let upload_result = match utils::api::upload_zip(&zip_path, &config.get_url(), &project_name, repo_info, scan_type, policy) {
184
184
  Ok(result) => result,
185
185
  Err(e) => {
186
186
  eprintln!("\n\nOh no! We encountered an issue while uploading the zip file '{}' to the server.\nPlease ensure that:
@@ -225,7 +225,7 @@ pub fn run(
225
225
  utils::terminal::show_loading_message("Collecting scan results... ([T]s)", stop_signal_clone);
226
226
  });
227
227
 
228
- let classifications = match report_scan_status(&config.get_url(), &config.get_token(), &project_name) {
228
+ let classifications = match report_scan_status(&config.get_url(), &project_name) {
229
229
  Ok(issues_classes) => {
230
230
  *stop_signal.lock().unwrap() = true;
231
231
  let _ = results_thread.join();
@@ -258,7 +258,7 @@ pub fn run(
258
258
  }
259
259
  };
260
260
  if *fail {
261
- let blocking_rules = match utils::api::check_blocking_rules(&config.get_url(), &config.get_token(), &scan_id, None) {
261
+ let blocking_rules = match utils::api::check_blocking_rules(&config.get_url(), &scan_id, None) {
262
262
  Ok(rules) => rules,
263
263
  Err(e) => {
264
264
  eprintln!("Failed to check blocking rules: {}", e);
@@ -286,14 +286,14 @@ pub fn run(
286
286
  });
287
287
 
288
288
  if out_format == "json" {
289
- let issues = match utils::api::get_all_issues(&config.get_url(), &config.get_token(), &project_name, Some(scan_id.clone())) {
289
+ let issues = match utils::api::get_all_issues(&config.get_url(), &project_name, Some(scan_id.clone())) {
290
290
  Ok(issues) => issues,
291
291
  Err(e) => {
292
292
  eprintln!("\n\nFailed to fetch issues: {}\n\n", e);
293
293
  std::process::exit(1);
294
294
  }
295
295
  };
296
- let sca_issues = match utils::api::get_all_sca_issues(&config.get_url(), &config.get_token(), &project_name, Some(scan_id.clone())) {
296
+ let sca_issues = match utils::api::get_all_sca_issues(&config.get_url(), &project_name, Some(scan_id.clone())) {
297
297
  Ok(issues) => issues,
298
298
  Err(e) => {
299
299
  eprintln!("\n\nFailed to fetch SCA issues: {}\n\n", e);
@@ -311,7 +311,7 @@ pub fn run(
311
311
  println!("\n\nScan results written to: {}\n\n", out_file.clone());
312
312
  }
313
313
  else if out_format == "html" {
314
- let report = match utils::api::get_scan_report(&config.get_url(), &config.get_token(), &scan_id, None) {
314
+ let report = match utils::api::get_scan_report(&config.get_url(), &scan_id, None) {
315
315
  Ok(html) => html,
316
316
  Err(e) => {
317
317
  eprintln!("\n\nFailed to fetch scan report: {}\n\n", e);
@@ -325,7 +325,7 @@ pub fn run(
325
325
  println!("\n\nScan report written to: {}\n\n", out_file.clone());
326
326
  }
327
327
  else if out_format == "sarif" {
328
- let report = match utils::api::get_scan_report(&config.get_url(), &config.get_token(), &scan_id, Some("sarif")) {
328
+ let report = match utils::api::get_scan_report(&config.get_url(), &scan_id, Some("sarif")) {
329
329
  Ok(sarif) => sarif,
330
330
  Err(e) => {
331
331
  eprintln!("\n\nFailed to fetch SARIF report: {}\n\n", e);
@@ -339,7 +339,7 @@ pub fn run(
339
339
  println!("\n\nScan report written to: {}\n\n", out_file.clone());
340
340
  }
341
341
  else if out_format == "markdown" {
342
- let report = match utils::api::get_scan_report(&config.get_url(), &config.get_token(), &scan_id, Some("markdown")) {
342
+ let report = match utils::api::get_scan_report(&config.get_url(), &scan_id, Some("markdown")) {
343
343
  Ok(markdown) => markdown,
344
344
  Err(e) => {
345
345
  eprintln!("\n\nFailed to fetch Markdown report: {}\n\n", e);
@@ -402,7 +402,7 @@ pub fn wait_for_scan(config: &Config, scan_id: &str) {
402
402
 
403
403
  loop {
404
404
  std::thread::sleep(std::time::Duration::from_secs(1));
405
- match check_scan_status(&scan_id, &config.get_url(), &config.get_token()) {
405
+ match check_scan_status(&scan_id, &config.get_url()) {
406
406
  Ok(true) => {
407
407
  *stop_signal.lock().unwrap() = true;
408
408
  break;
@@ -444,16 +444,16 @@ pub fn wait_for_scan(config: &Config, scan_id: &str) {
444
444
  }
445
445
 
446
446
 
447
- pub fn check_scan_status(scan_id: &str, url: &str, token: &str) -> Result<bool, Box<dyn Error>> {
448
- match utils::api::get_scan(url, token, scan_id) {
447
+ pub fn check_scan_status(scan_id: &str, url: &str) -> Result<bool, Box<dyn Error>> {
448
+ match utils::api::get_scan(url, scan_id) {
449
449
  Ok(scan) => Ok(scan.status == "complete"),
450
450
  Err(e) => Err(e)
451
451
  }
452
452
  }
453
453
 
454
454
 
455
- pub fn fetch_and_group_scan_issues(url: &str, token: &str, project: &str) -> Result<HashMap<String, usize>, Box<dyn std::error::Error>> {
456
- let issues = match utils::api::get_all_issues(url, token, project, None) {
455
+ pub fn fetch_and_group_scan_issues(url: &str, project: &str) -> Result<HashMap<String, usize>, Box<dyn std::error::Error>> {
456
+ let issues = match utils::api::get_all_issues(url, project, None) {
457
457
  Ok(issues) => issues,
458
458
  Err(err) => {
459
459
  return Err(format!("Failed to fetch scan issues: {}", err).into());
@@ -468,8 +468,8 @@ pub fn fetch_and_group_scan_issues(url: &str, token: &str, project: &str) -> Res
468
468
  Ok(classification_counts)
469
469
  }
470
470
 
471
- pub fn report_scan_status(url: &str, token: &str, project: &str) -> Result<HashMap<String, usize>, Box<dyn std::error::Error>>{
472
- let classification_counts = match fetch_and_group_scan_issues(url, token, project) {
471
+ pub fn report_scan_status(url: &str, project: &str) -> Result<HashMap<String, usize>, Box<dyn std::error::Error>>{
472
+ let classification_counts = match fetch_and_group_scan_issues(url, project) {
473
473
  Ok(counts) => counts,
474
474
  Err(e) => {
475
475
  return Err(e);
@@ -19,20 +19,129 @@ fn get_source() -> String {
19
19
  std::env::var("CORGEA_SOURCE").unwrap_or_else(|_| "cli".to_string())
20
20
  }
21
21
 
22
- pub fn http_client() -> reqwest::blocking::Client {
23
- let mut builder =
24
- reqwest::blocking::Client::builder().timeout(std::time::Duration::from_secs(5 * 30));
22
+ fn is_jwt(token: &str) -> bool {
23
+ let parts: Vec<&str> = token.splitn(4, '.').collect();
24
+ parts.len() == 3 && parts.iter().all(|p| !p.is_empty())
25
+ }
26
+
27
+ fn auth_headers(token: &str) -> HeaderMap {
28
+ let mut headers = HeaderMap::new();
29
+ if is_jwt(token) {
30
+ headers.insert(
31
+ "Authorization",
32
+ format!("Bearer {}", token).parse().unwrap(),
33
+ );
34
+ } else {
35
+ headers.insert("CORGEA-TOKEN", token.parse().unwrap());
36
+ }
37
+ headers.insert("CORGEA-SOURCE", get_source().parse().unwrap());
38
+ headers
39
+ }
40
+
41
+ static AUTH_TOKEN: std::sync::LazyLock<std::sync::RwLock<String>> =
42
+ std::sync::LazyLock::new(|| std::sync::RwLock::new(String::new()));
25
43
 
26
- if let Ok(https_proxy) = std::env::var("https_proxy") {
27
- debug(&format!("https_proxy detected: {}", https_proxy));
44
+ pub fn set_auth_token(token: &str) {
45
+ *AUTH_TOKEN.write().unwrap() = token.to_string();
46
+ }
47
+
48
+ static COOKIE_JAR: std::sync::LazyLock<std::sync::Arc<reqwest::cookie::Jar>> =
49
+ std::sync::LazyLock::new(|| std::sync::Arc::new(reqwest::cookie::Jar::default()));
50
+
51
+ static SHARED_CLIENT: std::sync::LazyLock<reqwest::blocking::Client> =
52
+ std::sync::LazyLock::new(|| {
53
+ let mut builder = reqwest::blocking::Client::builder()
54
+ .timeout(std::time::Duration::from_secs(5 * 30))
55
+ .cookie_provider(COOKIE_JAR.clone());
56
+
57
+ if let Ok(https_proxy) = std::env::var("https_proxy") {
58
+ debug(&format!("https_proxy detected: {}", https_proxy));
28
59
 
29
- if std::env::var("CORGEA_ACCEPT_CERT").is_ok() {
30
- debug(&format!("Skipping CA cert validation"));
31
- builder = builder.danger_accept_invalid_certs(true);
60
+ if std::env::var("CORGEA_ACCEPT_CERT").is_ok() {
61
+ debug(&format!("Skipping CA cert validation"));
62
+ builder = builder.danger_accept_invalid_certs(true);
63
+ }
32
64
  }
65
+
66
+ builder.build().expect("Failed to build http client")
67
+ });
68
+
69
+ pub struct HttpClient {
70
+ inner: reqwest::blocking::Client,
71
+ }
72
+
73
+ pub struct DebugRequestBuilder {
74
+ client: reqwest::blocking::Client,
75
+ inner: reqwest::blocking::RequestBuilder,
76
+ }
77
+
78
+ impl HttpClient {
79
+ pub fn get<U: reqwest::IntoUrl>(&self, url: U) -> DebugRequestBuilder {
80
+ DebugRequestBuilder { client: self.inner.clone(), inner: self.inner.get(url) }
33
81
  }
34
82
 
35
- builder.build().expect("Failed to build http client")
83
+ pub fn post<U: reqwest::IntoUrl>(&self, url: U) -> DebugRequestBuilder {
84
+ DebugRequestBuilder { client: self.inner.clone(), inner: self.inner.post(url) }
85
+ }
86
+
87
+ pub fn patch<U: reqwest::IntoUrl>(&self, url: U) -> DebugRequestBuilder {
88
+ DebugRequestBuilder { client: self.inner.clone(), inner: self.inner.patch(url) }
89
+ }
90
+ }
91
+
92
+ impl DebugRequestBuilder {
93
+ pub fn header<K, V>(self, key: K, value: V) -> Self
94
+ where
95
+ reqwest::header::HeaderName: TryFrom<K>,
96
+ <reqwest::header::HeaderName as TryFrom<K>>::Error: Into<http::Error>,
97
+ reqwest::header::HeaderValue: TryFrom<V>,
98
+ <reqwest::header::HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
99
+ {
100
+ Self { inner: self.inner.header(key, value), client: self.client }
101
+ }
102
+
103
+ pub fn query<T: Serialize + ?Sized>(self, query: &T) -> Self {
104
+ Self { inner: self.inner.query(query), client: self.client }
105
+ }
106
+
107
+ pub fn multipart(self, form: reqwest::blocking::multipart::Form) -> Self {
108
+ Self { inner: self.inner.multipart(form), client: self.client }
109
+ }
110
+
111
+ pub fn body<T: Into<reqwest::blocking::Body>>(self, body: T) -> Self {
112
+ Self { inner: self.inner.body(body), client: self.client }
113
+ }
114
+
115
+ pub fn send(self) -> reqwest::Result<reqwest::blocking::Response> {
116
+ use reqwest::cookie::CookieStore;
117
+
118
+ let token = AUTH_TOKEN.read().unwrap().clone();
119
+ let builder = if !token.is_empty() {
120
+ self.inner.headers(auth_headers(&token))
121
+ } else {
122
+ self.inner
123
+ };
124
+
125
+ let request = builder.build()?;
126
+
127
+ debug(&format!("→ {} {}", request.method(), request.url()));
128
+ debug(&format!(" Request headers: {:?}", request.headers()));
129
+ match COOKIE_JAR.cookies(request.url()) {
130
+ Some(cookies) => debug(&format!(" Cookie: {}", cookies.to_str().unwrap_or("<binary>"))),
131
+ None => debug(" Cookie: (none in jar for this URL)"),
132
+ }
133
+
134
+ let response = self.client.execute(request)?;
135
+
136
+ debug(&format!("← {} {}", response.status(), response.url()));
137
+ debug(&format!(" Response headers: {:?}", response.headers()));
138
+
139
+ Ok(response)
140
+ }
141
+ }
142
+
143
+ pub fn http_client() -> HttpClient {
144
+ HttpClient { inner: SHARED_CLIENT.clone() }
36
145
  }
37
146
 
38
147
  fn check_for_warnings(headers: &HeaderMap, status: StatusCode) {
@@ -58,7 +167,6 @@ pub struct UploadZipResult {
58
167
 
59
168
  pub fn upload_zip(
60
169
  file_path: &str,
61
- token: &str,
62
170
  url: &str,
63
171
  project_name: &str,
64
172
  repo_info: Option<utils::generic::RepoInfo>,
@@ -84,8 +192,6 @@ pub fn upload_zip(
84
192
 
85
193
  let response_object = client
86
194
  .post(format!("{}{}/start-scan", url, API_BASE))
87
- .header("CORGEA-TOKEN", token)
88
- .header("CORGEA-SOURCE", get_source())
89
195
  .query(&[
90
196
  ("scan_type", "blast"),
91
197
  ])
@@ -174,8 +280,6 @@ pub fn upload_zip(
174
280
 
175
281
  let response = match client
176
282
  .patch(format!("{}{}/start-scan/{}/", url, API_BASE, transfer_id))
177
- .header("CORGEA-TOKEN", token)
178
- .header("CORGEA-SOURCE", get_source())
179
283
  .header("Upload-Offset", offset.to_string())
180
284
  .header("Upload-Length", file_size.to_string())
181
285
  .header("Upload-Name", file_name)
@@ -236,12 +340,12 @@ pub fn upload_zip(
236
340
  Err("Failed to upload file".into())
237
341
  }
238
342
 
239
- pub fn get_all_issues(url: &str, token: &str, project: &str, scan_id: Option<String>) -> Result<Vec<Issue>, Box<dyn std::error::Error>> {
343
+ pub fn get_all_issues(url: &str, project: &str, scan_id: Option<String>) -> Result<Vec<Issue>, Box<dyn std::error::Error>> {
240
344
  let mut all_issues = Vec::new();
241
345
  let mut current_page: u32 = 1;
242
346
 
243
347
  loop {
244
- let response = match get_scan_issues(url, token, project, Some(current_page as u16), Some(30), scan_id.clone()) {
348
+ let response = match get_scan_issues(url, project, Some(current_page as u16), Some(30), scan_id.clone()) {
245
349
  Ok(response) => response,
246
350
  Err(e) => return Err(format!("Failed to get scan issues: {}", e).into())
247
351
  };
@@ -267,7 +371,6 @@ pub fn get_all_issues(url: &str, token: &str, project: &str, scan_id: Option<Str
267
371
 
268
372
  pub fn get_scan_issues(
269
373
  url: &str,
270
- token: &str,
271
374
  project: &str,
272
375
  page: Option<u16>,
273
376
  page_size: Option<u16>,
@@ -295,14 +398,10 @@ pub fn get_scan_issues(
295
398
  url.push_str("&page_size=30");
296
399
  }
297
400
  let client = http_client();
298
- let mut headers = HeaderMap::new();
299
- headers.insert("CORGEA-TOKEN", token.parse().unwrap());
300
- headers.insert("CORGEA-SOURCE", get_source().parse().unwrap());
301
401
 
302
402
  debug(&format!("Sending request to URL: {}", url));
303
- debug(&format!("Headers: {:?}", headers));
304
403
 
305
- let response = match client.get(&url).headers(headers).send() {
404
+ let response = match client.get(&url).send() {
306
405
  Ok(res) => {
307
406
  check_for_warnings(res.headers(), res.status());
308
407
  res
@@ -324,19 +423,13 @@ pub fn get_scan_issues(
324
423
  }
325
424
  }
326
425
 
327
- pub fn get_scan(url: &str, token: &str, scan_id: &str) -> Result<ScanResponse, Box<dyn std::error::Error>> {
426
+ pub fn get_scan(url: &str, scan_id: &str) -> Result<ScanResponse, Box<dyn std::error::Error>> {
328
427
  let url = format!("{}{}/scan/{}", url, API_BASE, scan_id);
329
428
 
330
429
  let client = http_client();
331
-
332
- let mut headers = HeaderMap::new();
333
- headers.insert("CORGEA-TOKEN", token.parse().unwrap());
334
- headers.insert("CORGEA-SOURCE", get_source().parse().unwrap());
335
430
  debug(&format!("Sending request to URL: {}", url));
336
- debug(&format!("Headers: {:?}", headers));
337
431
  let response = client
338
432
  .get(&url)
339
- .headers(headers)
340
433
  .send()
341
434
  .map_err(|e| format!("Failed to send request: {}", e))?;
342
435
 
@@ -354,7 +447,7 @@ pub fn get_scan(url: &str, token: &str, scan_id: &str) -> Result<ScanResponse, B
354
447
  }
355
448
  }
356
449
 
357
- pub fn get_scan_report(url: &str, token: &str, scan_id: &str, format: Option<&str>) -> Result<String, Box<dyn std::error::Error>> {
450
+ pub fn get_scan_report(url: &str, scan_id: &str, format: Option<&str>) -> Result<String, Box<dyn std::error::Error>> {
358
451
  let url = if let Some(fmt) = format {
359
452
  format!("{}{}/scan/{}/report?format={}", url, API_BASE, scan_id, fmt)
360
453
  } else {
@@ -362,16 +455,11 @@ pub fn get_scan_report(url: &str, token: &str, scan_id: &str, format: Option<&st
362
455
  };
363
456
 
364
457
  let client = http_client();
365
- let mut headers = HeaderMap::new();
366
- headers.insert("CORGEA-TOKEN", token.parse().unwrap());
367
- headers.insert("CORGEA-SOURCE", get_source().parse().unwrap());
368
458
 
369
459
  debug(&format!("Sending request to URL: {}", url));
370
- debug(&format!("Headers: {:?}", headers));
371
460
 
372
461
  let response = client
373
462
  .get(&url)
374
- .headers(headers)
375
463
  .send()
376
464
  .map_err(|e| format!("Failed to send request: {}", e))?;
377
465
 
@@ -384,7 +472,7 @@ pub fn get_scan_report(url: &str, token: &str, scan_id: &str, format: Option<&st
384
472
  }
385
473
  }
386
474
 
387
- pub fn get_issue(url: &str, token: &str, issue: &str) -> Result<FullIssueResponse, Box<dyn std::error::Error>> {
475
+ pub fn get_issue(url: &str, issue: &str) -> Result<FullIssueResponse, Box<dyn std::error::Error>> {
388
476
  let url = format!(
389
477
  "{}{}/issue/{}",
390
478
  url,
@@ -392,12 +480,8 @@ pub fn get_issue(url: &str, token: &str, issue: &str) -> Result<FullIssueRespons
392
480
  issue,
393
481
  );
394
482
  let client = http_client();
395
- let mut headers = HeaderMap::new();
396
- headers.insert("CORGEA-TOKEN", token.parse().unwrap());
397
- headers.insert("CORGEA-SOURCE", get_source().parse().unwrap());
398
483
  debug(&format!("Sending request to URL: {}", url));
399
- debug(&format!("Headers: {:?}", headers));
400
- let response = match client.get(&url).headers(headers).send() {
484
+ let response = match client.get(&url).send() {
401
485
  Ok(res) => {
402
486
  check_for_warnings(res.headers(), res.status());
403
487
  res
@@ -418,7 +502,6 @@ pub fn get_issue(url: &str, token: &str, issue: &str) -> Result<FullIssueRespons
418
502
 
419
503
  pub fn query_scan_list(
420
504
  url: &str,
421
- token: &str,
422
505
  project: Option<&str>,
423
506
  page: Option<u16>,
424
507
  page_size: Option<u16>
@@ -437,14 +520,9 @@ pub fn query_scan_list(
437
520
 
438
521
 
439
522
  let client = http_client();
440
- let mut headers = HeaderMap::new();
441
- headers.insert("CORGEA-TOKEN", token.parse().unwrap());
442
- headers.insert("CORGEA-SOURCE", get_source().parse().unwrap());
443
523
  debug(&format!("Sending request to URL: {}", url));
444
- debug(&format!("Headers: {:?}", headers));
445
524
  let response = match client
446
525
  .get(url)
447
- .headers(headers)
448
526
  .query(&query_params)
449
527
  .send() {
450
528
  Ok(res) => {
@@ -498,18 +576,13 @@ pub fn exchange_code_for_token(
498
576
  }
499
577
  }
500
578
 
501
- pub fn verify_token(token: &str, corgea_url: &str) -> Result<bool, Box<dyn Error>> {
579
+ pub fn verify_token(corgea_url: &str) -> Result<bool, Box<dyn Error>> {
502
580
  let url = format!("{}{}/verify", corgea_url, API_BASE);
503
581
  let client = http_client();
504
- let mut headers = HeaderMap::new();
505
- headers.insert("CORGEA-TOKEN", token.parse().unwrap());
506
- headers.insert("CORGEA-SOURCE", get_source().parse().unwrap());
507
582
  debug(&format!("Sending request to URL: {}", url));
508
- debug(&format!("Headers: {:?}", headers));
509
583
 
510
584
  let response = client
511
585
  .get(&url)
512
- .headers(headers)
513
586
  .send()?;
514
587
 
515
588
  check_for_warnings(response.headers(), response.status());
@@ -532,7 +605,6 @@ pub fn verify_token(token: &str, corgea_url: &str) -> Result<bool, Box<dyn Error
532
605
 
533
606
  pub fn check_blocking_rules(
534
607
  url: &str,
535
- token: &str,
536
608
  sast_scan_id: &str,
537
609
  page: Option<u32>
538
610
  ) -> Result<BlockingRuleResponse, Box<dyn Error>> {
@@ -541,16 +613,11 @@ pub fn check_blocking_rules(
541
613
  let query_params = vec![("page", page.to_string())];
542
614
 
543
615
  let client = http_client();
544
- let mut headers = HeaderMap::new();
545
- headers.insert("CORGEA-TOKEN", token.parse().unwrap());
546
- headers.insert("CORGEA-SOURCE", get_source().parse().unwrap());
547
616
  debug(&format!("Sending request to URL: {}", url));
548
- debug(&format!("Headers: {:?}", headers));
549
617
  debug(&format!("Query params: {:?}", query_params));
550
618
 
551
619
  let response = match client
552
620
  .get(url)
553
- .headers(headers)
554
621
  .query(&query_params)
555
622
  .send() {
556
623
  Ok(res) => {
@@ -583,7 +650,6 @@ pub fn check_blocking_rules(
583
650
 
584
651
  pub fn get_sca_issues(
585
652
  url: &str,
586
- token: &str,
587
653
  page: Option<u16>,
588
654
  page_size: Option<u16>,
589
655
  scan_id: Option<String>
@@ -605,12 +671,9 @@ pub fn get_sca_issues(
605
671
 
606
672
  debug(&format!("Sending request to URL: {}", endpoint));
607
673
  debug(&format!("Query params: {:?}", query_params));
608
- debug(&format!("Token: {}", token));
609
674
 
610
675
  let response = client
611
676
  .get(&endpoint)
612
- .header("CORGEA-TOKEN", token)
613
- .header("CORGEA-SOURCE", get_source())
614
677
  .query(&query_params)
615
678
  .send();
616
679
 
@@ -646,7 +709,6 @@ pub fn get_sca_issues(
646
709
 
647
710
  pub fn get_all_sca_issues(
648
711
  url: &str,
649
- token: &str,
650
712
  _project: &str,
651
713
  scan_id: Option<String>
652
714
  ) -> Result<Vec<SCAIssue>, Box<dyn std::error::Error>> {
@@ -654,7 +716,7 @@ pub fn get_all_sca_issues(
654
716
  let mut current_page: u32 = 1;
655
717
 
656
718
  loop {
657
- let response = match get_sca_issues(url, token, Some(current_page as u16), Some(30), scan_id.clone()) {
719
+ let response = match get_sca_issues(url, Some(current_page as u16), Some(30), scan_id.clone()) {
658
720
  Ok(response) => response,
659
721
  Err(e) => return Err(format!("Failed to get SCA issues: {}", e).into())
660
722
  };
@@ -12,7 +12,7 @@ pub fn run(config: &Config, scan_id: Option<String>, project_id: Option<String>)
12
12
  }
13
13
  };
14
14
 
15
- let scans_result = utils::api::query_scan_list(&config.get_url(), &config.get_token(), Some(&project_name), Some(1), None);
15
+ let scans_result = utils::api::query_scan_list(&config.get_url(), Some(&project_name), Some(1), None);
16
16
  let scans: Vec<utils::api::ScanResponse> = match scans_result {
17
17
  Ok(result) => result.scans.unwrap_or_default(),
18
18
  Err(e) => {
@@ -31,7 +31,7 @@ pub fn run(config: &Config, scan_id: Option<String>, project_id: Option<String>)
31
31
  };
32
32
  let (scan_id, processed) = match scan_id {
33
33
  Some(scan_id) => {
34
- let processed = match blast::check_scan_status(&scan_id, &config.get_url(), &config.get_token()) {
34
+ let processed = match blast::check_scan_status(&scan_id, &config.get_url()) {
35
35
  Ok(processed) => processed,
36
36
  Err(_) => {
37
37
  eprintln!(
@@ -73,7 +73,7 @@ pub fn run(config: &Config, scan_id: Option<String>, project_id: Option<String>)
73
73
  print!("Scan has been processed successfully!\n");
74
74
  }
75
75
 
76
- match blast::report_scan_status(&config.get_url(), &config.get_token(), &project_name) {
76
+ match blast::report_scan_status(&config.get_url(), &project_name) {
77
77
  Ok(_) => {
78
78
  println!(
79
79
  "\n\nYou can view the scan results at the following link:\n{}",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes