diff --git a/src/models/code_scannings.rs b/src/models/code_scannings.rs index 68407d6a..ecda9642 100644 --- a/src/models/code_scannings.rs +++ b/src/models/code_scannings.rs @@ -3,21 +3,48 @@ use super::*; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[non_exhaustive] pub struct CodeScanningAlert { - pub number: i64, - pub created_at: String, - pub updated_at: Option, - pub url: String, - pub html_url: String, - pub state: String, - pub fixed_at: Option, - pub dismissed_by: Dismisser, - pub dismissed_at: String, - pub dismissed_reason: String, - pub dismissed_comment: String, + /// The unique identifier of the code scanning alert. + pub number: u64, + pub created_at: chrono::DateTime, + #[serde(skip_serializing_if = "Option::is_none")] + pub updated_at: Option>, + pub url: Url, + pub html_url: Url, + pub state: CodeScanningState, + #[serde(skip_serializing_if = "Option::is_none")] + pub fixed_at: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub dismissed_by: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub dismissed_at: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub dismissed_reason: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub dismissed_comment: Option, pub rule: Rule, pub tool: Tool, pub most_recent_instance: MostRecentInstance, - pub instances_url: String, + pub instances_url: Url, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[non_exhaustive] +#[serde(rename_all = "snake_case")] +pub enum CodeScanningState { + Open, + Dismissed, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[non_exhaustive] +#[serde(rename_all = "snake_case")] +pub enum DismissedReason { + #[serde(rename = "false positive")] + FalsePositive, + #[serde(rename = "won't fix")] + WonTFix, + #[serde(rename = "used in tests")] + UsedInTests, } #[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)] @@ -49,20 +76,28 @@ pub struct Dismisser { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[non_exhaustive] pub struct Rule { - pub id: String, - pub severity: String, - pub description: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub id: Option, pub name: String, - pub tags: Vec, - pub security_severity_level: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub severity: Option, + pub description: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub full_description: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub tags: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub security_severity_level: Option, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[non_exhaustive] pub struct Tool { pub name: String, + #[serde(skip_serializing_if = "Option::is_none")] pub guid: Option, - pub version: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub version: Option, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] @@ -71,7 +106,7 @@ pub struct MostRecentInstance { #[serde(rename = "ref")] pub ref_field: String, pub analysis_key: String, - pub environment: Environment, + pub environment: String, pub category: String, pub state: String, pub commit_sha: String, @@ -83,10 +118,13 @@ pub struct MostRecentInstance { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[non_exhaustive] pub struct Environment { - #[serde(rename = "build-mode")] + #[serde(rename = "build-mode", skip_serializing_if = "Option::is_none")] pub build_mode: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub category: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub language: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub runner: Option>, } diff --git a/src/models/webhook_events/payload/code_scanning_alert.rs b/src/models/webhook_events/payload/code_scanning_alert.rs index 848b3aa7..eb9f1464 100644 --- a/src/models/webhook_events/payload/code_scanning_alert.rs +++ b/src/models/webhook_events/payload/code_scanning_alert.rs @@ -1,15 +1,26 @@ use serde::{Deserialize, Serialize}; +use crate::models::{code_scannings::CodeScanningAlert, orgs::Organization, Author, Repository}; + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[non_exhaustive] pub struct CodeScanningAlertWebhookEventPayload { + /// The action that was performed. pub action: CodeScanningAlertWebhookEventAction, - pub alert: serde_json::Value, + /// The code scanning alert that was affected. + pub alert: CodeScanningAlert, /// The commit SHA of the code scanning alert. When the action is reopened_by_user or closed_by_user, the event was triggered by the sender and this value will be empty. pub commit_oid: String, + #[serde(skip_serializing_if = "Option::is_none")] pub enterprise: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub organization: Option, /// The Git reference of the code scanning alert. When the action is reopened_by_user or closed_by_user, the event was triggered by the sender and this value will be empty. pub r#ref: String, + /// The repository that the code scanning alert belongs to. + pub repository: Repository, + /// The user that triggered the code scanning alert. + pub sender: Author, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] diff --git a/tests/resources/codescanning_alert_single.json b/tests/resources/codescanning_alert_single.json index 50e2d3c5..f0bbadae 100644 --- a/tests/resources/codescanning_alert_single.json +++ b/tests/resources/codescanning_alert_single.json @@ -51,7 +51,7 @@ "ref": "refs/heads/main", "analysis_key": ".github/workflows/codeql-analysis.yml:CodeQL-Build", "category": ".github/workflows/codeql-analysis.yml:CodeQL-Build", - "environment": {}, + "environment": "{}", "state": "dismissed", "commit_sha": "39406e42cb832f683daa691dd652a8dc36ee8930", "message": { @@ -69,4 +69,4 @@ ] }, "instances_url": "https://api.github.com/repos/octocat/hello-world/code-scanning/alerts/42/instances" -} \ No newline at end of file +} diff --git a/tests/resources/codescanning_alerts_multiple.json b/tests/resources/codescanning_alerts_multiple.json index bdfaf5c0..9239c5d7 100644 --- a/tests/resources/codescanning_alerts_multiple.json +++ b/tests/resources/codescanning_alerts_multiple.json @@ -52,7 +52,7 @@ "ref": "refs/heads/main", "analysis_key": ".github/workflows/codeql-analysis.yml:CodeQL-Build", "category": ".github/workflows/codeql-analysis.yml:CodeQL-Build", - "environment": {}, + "environment": "{}", "state": "dismissed", "commit_sha": "39406e42cb832f683daa691dd652a8dc36ee8930", "message": { @@ -72,75 +72,75 @@ "instances_url": "https://api.github.com/repos/octocat/hello-world/code-scanning/alerts/1/instances" }, { - "number": 42, - "created_at": "2020-06-19T11:21:34Z", - "url": "https://api.github.com/repos/octocat/hello-world/code-scanning/alerts/42", - "html_url": "https://github.com/octocat/hello-world/code-scanning/42", - "state": "dismissed", - "fixed_at": null, - "dismissed_by": { - "login": "octocat", - "id": 54933897, - "node_id": "MDQ6VXNlcjE=", - "avatar_url": "https://github.com/images/error/octocat_happy.gif", - "gravatar_id": "", - "url": "https://api.github.com/users/octocat", - "html_url": "https://github.com/octocat", - "followers_url": "https://api.github.com/users/octocat/followers", - "following_url": "https://api.github.com/users/octocat/following{/other_user}", - "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", - "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", - "organizations_url": "https://api.github.com/users/octocat/orgs", - "repos_url": "https://api.github.com/users/octocat/repos", - "events_url": "https://api.github.com/users/octocat/events{/privacy}", - "received_events_url": "https://api.github.com/users/octocat/received_events", - "type": "User", - "site_admin": false - }, - "dismissed_at": "2020-02-14T12:29:18Z", - "dismissed_reason": "false positive", - "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library.", - "rule": { - "id": "js/zipslip", - "severity": "error", - "security_severity_level": "high", - "description": "Arbitrary file write during zip extraction (\"Zip Slip\")", - "name": "js/zipslip", - "full_description": "Extracting files from a malicious zip archive without validating that the destination file path is within the destination directory can cause files outside the destination directory to be overwritten.", - "tags": [ - "security", - "external/cwe/cwe-022" - ], - "help": "# Arbitrary file write during zip extraction (\"Zip Slip\")\\nExtracting files from a malicious zip archive without validating that the destination file path is within the destination directory can cause files outside the destination directory to be overwritten ...", - "help_uri": "https://codeql.github.com/" - }, - "tool": { - "name": "CodeQL", - "guid": null, - "version": "2.4.0" - }, - "most_recent_instance": { - "ref": "refs/heads/main", - "analysis_key": ".github/workflows/codeql-analysis.yml:CodeQL-Build", - "category": ".github/workflows/codeql-analysis.yml:CodeQL-Build", - "environment": {}, + "number": 42, + "created_at": "2020-06-19T11:21:34Z", + "url": "https://api.github.com/repos/octocat/hello-world/code-scanning/alerts/42", + "html_url": "https://github.com/octocat/hello-world/code-scanning/42", "state": "dismissed", - "commit_sha": "39406e42cb832f683daa691dd652a8dc36ee8930", - "message": { - "text": "This path depends on a user-provided value." + "fixed_at": null, + "dismissed_by": { + "login": "octocat", + "id": 54933897, + "node_id": "MDQ6VXNlcjE=", + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "dismissed_at": "2020-02-14T12:29:18Z", + "dismissed_reason": "false positive", + "dismissed_comment": "This alert is not actually correct, because there's a sanitizer included in the library.", + "rule": { + "id": "js/zipslip", + "severity": "error", + "security_severity_level": "high", + "description": "Arbitrary file write during zip extraction (\"Zip Slip\")", + "name": "js/zipslip", + "full_description": "Extracting files from a malicious zip archive without validating that the destination file path is within the destination directory can cause files outside the destination directory to be overwritten.", + "tags": [ + "security", + "external/cwe/cwe-022" + ], + "help": "# Arbitrary file write during zip extraction (\"Zip Slip\")\\nExtracting files from a malicious zip archive without validating that the destination file path is within the destination directory can cause files outside the destination directory to be overwritten ...", + "help_uri": "https://codeql.github.com/" }, - "location": { - "path": "spec-main/api-session-spec.ts", - "start_line": 917, - "end_line": 917, - "start_column": 7, - "end_column": 18 + "tool": { + "name": "CodeQL", + "guid": null, + "version": "2.4.0" }, - "classifications": [ - "test" - ] - }, - "instances_url": "https://api.github.com/repos/octocat/hello-world/code-scanning/alerts/42/instances" -} -] \ No newline at end of file + "most_recent_instance": { + "ref": "refs/heads/main", + "analysis_key": ".github/workflows/codeql-analysis.yml:CodeQL-Build", + "category": ".github/workflows/codeql-analysis.yml:CodeQL-Build", + "environment": "{}", + "state": "dismissed", + "commit_sha": "39406e42cb832f683daa691dd652a8dc36ee8930", + "message": { + "text": "This path depends on a user-provided value." + }, + "location": { + "path": "spec-main/api-session-spec.ts", + "start_line": 917, + "end_line": 917, + "start_column": 7, + "end_column": 18 + }, + "classifications": [ + "test" + ] + }, + "instances_url": "https://api.github.com/repos/octocat/hello-world/code-scanning/alerts/42/instances" + } +]