github.com/google/go-github/v49@v49.1.0/github/code-scanning.go (about) 1 // Copyright 2020 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "context" 10 "fmt" 11 "strconv" 12 "strings" 13 ) 14 15 // CodeScanningService handles communication with the code scanning related 16 // methods of the GitHub API. 17 // 18 // GitHub API docs: https://docs.github.com/en/rest/code-scanning 19 type CodeScanningService service 20 21 // Rule represents the complete details of GitHub Code Scanning alert type. 22 type Rule struct { 23 ID *string `json:"id,omitempty"` 24 Severity *string `json:"severity,omitempty"` 25 Description *string `json:"description,omitempty"` 26 Name *string `json:"name,omitempty"` 27 SecuritySeverityLevel *string `json:"security_severity_level,omitempty"` 28 FullDescription *string `json:"full_description,omitempty"` 29 Tags []string `json:"tags,omitempty"` 30 Help *string `json:"help,omitempty"` 31 } 32 33 // Location represents the exact location of the GitHub Code Scanning Alert in the scanned project. 34 type Location struct { 35 Path *string `json:"path,omitempty"` 36 StartLine *int `json:"start_line,omitempty"` 37 EndLine *int `json:"end_line,omitempty"` 38 StartColumn *int `json:"start_column,omitempty"` 39 EndColumn *int `json:"end_column,omitempty"` 40 } 41 42 // Message is a part of MostRecentInstance struct which provides the appropriate message when any action is performed on the analysis object. 43 type Message struct { 44 Text *string `json:"text,omitempty"` 45 } 46 47 // MostRecentInstance provides details of the most recent instance of this alert for the default branch or for the specified Git reference. 48 type MostRecentInstance struct { 49 Ref *string `json:"ref,omitempty"` 50 AnalysisKey *string `json:"analysis_key,omitempty"` 51 Environment *string `json:"environment,omitempty"` 52 State *string `json:"state,omitempty"` 53 CommitSHA *string `json:"commit_sha,omitempty"` 54 Message *Message `json:"message,omitempty"` 55 Location *Location `json:"location,omitempty"` 56 Classifications []string `json:"classifications,omitempty"` 57 } 58 59 // Tool represents the tool used to generate a GitHub Code Scanning Alert. 60 type Tool struct { 61 Name *string `json:"name,omitempty"` 62 GUID *string `json:"guid,omitempty"` 63 Version *string `json:"version,omitempty"` 64 } 65 66 // Alert represents an individual GitHub Code Scanning Alert on a single repository. 67 // 68 // GitHub API docs: https://docs.github.com/en/rest/code-scanning 69 type Alert struct { 70 Number *int `json:"number,omitempty"` 71 Repository *Repository `json:"repository,omitempty"` 72 RuleID *string `json:"rule_id,omitempty"` 73 RuleSeverity *string `json:"rule_severity,omitempty"` 74 RuleDescription *string `json:"rule_description,omitempty"` 75 Rule *Rule `json:"rule,omitempty"` 76 Tool *Tool `json:"tool,omitempty"` 77 CreatedAt *Timestamp `json:"created_at,omitempty"` 78 UpdatedAt *Timestamp `json:"updated_at,omitempty"` 79 FixedAt *Timestamp `json:"fixed_at,omitempty"` 80 State *string `json:"state,omitempty"` 81 ClosedBy *User `json:"closed_by,omitempty"` 82 ClosedAt *Timestamp `json:"closed_at,omitempty"` 83 URL *string `json:"url,omitempty"` 84 HTMLURL *string `json:"html_url,omitempty"` 85 MostRecentInstance *MostRecentInstance `json:"most_recent_instance,omitempty"` 86 Instances []*MostRecentInstance `json:"instances,omitempty"` 87 DismissedBy *User `json:"dismissed_by,omitempty"` 88 DismissedAt *Timestamp `json:"dismissed_at,omitempty"` 89 DismissedReason *string `json:"dismissed_reason,omitempty"` 90 DismissedComment *string `json:"dismissed_comment,omitempty"` 91 InstancesURL *string `json:"instances_url,omitempty"` 92 } 93 94 // ID returns the ID associated with an alert. It is the number at the end of the security alert's URL. 95 func (a *Alert) ID() int64 { 96 if a == nil { 97 return 0 98 } 99 100 s := a.GetHTMLURL() 101 102 // Check for an ID to parse at the end of the url 103 if i := strings.LastIndex(s, "/"); i >= 0 { 104 s = s[i+1:] 105 } 106 107 // Return the alert ID as a 64-bit integer. Unable to convert or out of range returns 0. 108 id, err := strconv.ParseInt(s, 10, 64) 109 if err != nil { 110 return 0 111 } 112 113 return id 114 } 115 116 // AlertListOptions specifies optional parameters to the CodeScanningService.ListAlerts 117 // method. 118 type AlertListOptions struct { 119 // State of the code scanning alerts to list. Set to closed to list only closed code scanning alerts. Default: open 120 State string `url:"state,omitempty"` 121 122 // Return code scanning alerts for a specific branch reference. The ref must be formatted as heads/<branch name>. 123 Ref string `url:"ref,omitempty"` 124 125 ListCursorOptions 126 127 // Add ListOptions so offset pagination with integer type "page" query parameter is accepted 128 // since ListCursorOptions accepts "page" as string only. 129 ListOptions 130 } 131 132 // AnalysesListOptions specifies optional parameters to the CodeScanningService.ListAnalysesForRepo method. 133 type AnalysesListOptions struct { 134 // Return code scanning analyses belonging to the same SARIF upload. 135 SarifID *string `url:"sarif_id,omitempty"` 136 137 // Return code scanning analyses for a specific branch reference. The ref can be formatted as refs/heads/<branch name> or simply <branch name>. 138 Ref *string `url:"ref,omitempty"` 139 140 ListOptions 141 } 142 143 // ScanningAnalysis represents an individual GitHub Code Scanning ScanningAnalysis on a single repository. 144 // 145 // GitHub API docs: https://docs.github.com/en/rest/code-scanning 146 type ScanningAnalysis struct { 147 ID *int64 `json:"id,omitempty"` 148 Ref *string `json:"ref,omitempty"` 149 CommitSHA *string `json:"commit_sha,omitempty"` 150 AnalysisKey *string `json:"analysis_key,omitempty"` 151 Environment *string `json:"environment,omitempty"` 152 Error *string `json:"error,omitempty"` 153 Category *string `json:"category,omitempty"` 154 CreatedAt *Timestamp `json:"created_at,omitempty"` 155 ResultsCount *int `json:"results_count,omitempty"` 156 RulesCount *int `json:"rules_count,omitempty"` 157 URL *string `json:"url,omitempty"` 158 SarifID *string `json:"sarif_id,omitempty"` 159 Tool *Tool `json:"tool,omitempty"` 160 Deletable *bool `json:"deletable,omitempty"` 161 Warning *string `json:"warning,omitempty"` 162 } 163 164 // SarifAnalysis specifies the results of a code scanning job. 165 // 166 // GitHub API docs: https://docs.github.com/en/rest/code-scanning 167 type SarifAnalysis struct { 168 CommitSHA *string `json:"commit_sha,omitempty"` 169 Ref *string `json:"ref,omitempty"` 170 Sarif *string `json:"sarif,omitempty"` 171 CheckoutURI *string `json:"checkout_uri,omitempty"` 172 StartedAt *Timestamp `json:"started_at,omitempty"` 173 ToolName *string `json:"tool_name,omitempty"` 174 } 175 176 // SarifID identifies a sarif analysis upload. 177 // 178 // GitHub API docs: https://docs.github.com/en/rest/code-scanning 179 type SarifID struct { 180 ID *string `json:"id,omitempty"` 181 URL *string `json:"url,omitempty"` 182 } 183 184 // ListAlertsForOrg lists code scanning alerts for an org. 185 // 186 // You must use an access token with the security_events scope to use this endpoint. GitHub Apps must have the security_events 187 // read permission to use this endpoint. 188 // 189 // GitHub API docs: https://docs.github.com/en/rest/code-scanning#list-code-scanning-alerts-for-an-organization 190 func (s *CodeScanningService) ListAlertsForOrg(ctx context.Context, org string, opts *AlertListOptions) ([]*Alert, *Response, error) { 191 u := fmt.Sprintf("orgs/%v/code-scanning/alerts", org) 192 u, err := addOptions(u, opts) 193 if err != nil { 194 return nil, nil, err 195 } 196 197 req, err := s.client.NewRequest("GET", u, nil) 198 if err != nil { 199 return nil, nil, err 200 } 201 202 var alerts []*Alert 203 resp, err := s.client.Do(ctx, req, &alerts) 204 if err != nil { 205 return nil, resp, err 206 } 207 208 return alerts, resp, nil 209 } 210 211 // ListAlertsForRepo lists code scanning alerts for a repository. 212 // 213 // Lists all open code scanning alerts for the default branch (usually master) and protected branches in a repository. 214 // You must use an access token with the security_events scope to use this endpoint. GitHub Apps must have the security_events 215 // read permission to use this endpoint. 216 // 217 // GitHub API docs: https://docs.github.com/en/rest/code-scanning#list-code-scanning-alerts-for-a-repository 218 func (s *CodeScanningService) ListAlertsForRepo(ctx context.Context, owner, repo string, opts *AlertListOptions) ([]*Alert, *Response, error) { 219 u := fmt.Sprintf("repos/%v/%v/code-scanning/alerts", owner, repo) 220 u, err := addOptions(u, opts) 221 if err != nil { 222 return nil, nil, err 223 } 224 225 req, err := s.client.NewRequest("GET", u, nil) 226 if err != nil { 227 return nil, nil, err 228 } 229 230 var alerts []*Alert 231 resp, err := s.client.Do(ctx, req, &alerts) 232 if err != nil { 233 return nil, resp, err 234 } 235 236 return alerts, resp, nil 237 } 238 239 // GetAlert gets a single code scanning alert for a repository. 240 // 241 // You must use an access token with the security_events scope to use this endpoint. 242 // GitHub Apps must have the security_events read permission to use this endpoint. 243 // 244 // The security alert_id is the number at the end of the security alert's URL. 245 // 246 // GitHub API docs: https://docs.github.com/en/rest/code-scanning#get-a-code-scanning-alert 247 func (s *CodeScanningService) GetAlert(ctx context.Context, owner, repo string, id int64) (*Alert, *Response, error) { 248 u := fmt.Sprintf("repos/%v/%v/code-scanning/alerts/%v", owner, repo, id) 249 250 req, err := s.client.NewRequest("GET", u, nil) 251 if err != nil { 252 return nil, nil, err 253 } 254 255 a := new(Alert) 256 resp, err := s.client.Do(ctx, req, a) 257 if err != nil { 258 return nil, resp, err 259 } 260 261 return a, resp, nil 262 } 263 264 // UploadSarif uploads the result of code scanning job to GitHub. 265 // 266 // For the parameter sarif, you must first compress your SARIF file using gzip and then translate the contents of the file into a Base64 encoding string. 267 // You must use an access token with the security_events scope to use this endpoint. GitHub Apps must have the security_events 268 // write permission to use this endpoint. 269 // 270 // GitHub API docs: https://docs.github.com/en/rest/code-scanning#upload-an-analysis-as-sarif-data 271 func (s *CodeScanningService) UploadSarif(ctx context.Context, owner, repo string, sarif *SarifAnalysis) (*SarifID, *Response, error) { 272 u := fmt.Sprintf("repos/%v/%v/code-scanning/sarifs", owner, repo) 273 274 req, err := s.client.NewRequest("POST", u, sarif) 275 if err != nil { 276 return nil, nil, err 277 } 278 279 sarifID := new(SarifID) 280 resp, err := s.client.Do(ctx, req, sarifID) 281 if err != nil { 282 return nil, resp, err 283 } 284 285 return sarifID, resp, nil 286 } 287 288 // ListAnalysesForRepo lists code scanning analyses for a repository. 289 // 290 // Lists the details of all code scanning analyses for a repository, starting with the most recent. 291 // You must use an access token with the security_events scope to use this endpoint. 292 // GitHub Apps must have the security_events read permission to use this endpoint. 293 // 294 // GitHub API docs: https://docs.github.com/en/rest/code-scanning#list-code-scanning-analyses-for-a-repository 295 func (s *CodeScanningService) ListAnalysesForRepo(ctx context.Context, owner, repo string, opts *AnalysesListOptions) ([]*ScanningAnalysis, *Response, error) { 296 u := fmt.Sprintf("repos/%v/%v/code-scanning/analyses", owner, repo) 297 u, err := addOptions(u, opts) 298 if err != nil { 299 return nil, nil, err 300 } 301 302 req, err := s.client.NewRequest("GET", u, nil) 303 if err != nil { 304 return nil, nil, err 305 } 306 307 var analyses []*ScanningAnalysis 308 resp, err := s.client.Do(ctx, req, &analyses) 309 if err != nil { 310 return nil, resp, err 311 } 312 313 return analyses, resp, nil 314 } 315 316 // GetAnalysis gets a single code scanning analysis for a repository. 317 // 318 // You must use an access token with the security_events scope to use this endpoint. 319 // GitHub Apps must have the security_events read permission to use this endpoint. 320 // 321 // The security analysis_id is the ID of the analysis, as returned from the ListAnalysesForRepo operation. 322 // 323 // GitHub API docs: https://docs.github.com/en/rest/code-scanning#get-a-code-scanning-analysis-for-a-repository 324 func (s *CodeScanningService) GetAnalysis(ctx context.Context, owner, repo string, id int64) (*ScanningAnalysis, *Response, error) { 325 u := fmt.Sprintf("repos/%v/%v/code-scanning/analyses/%v", owner, repo, id) 326 327 req, err := s.client.NewRequest("GET", u, nil) 328 if err != nil { 329 return nil, nil, err 330 } 331 332 analysis := new(ScanningAnalysis) 333 resp, err := s.client.Do(ctx, req, analysis) 334 if err != nil { 335 return nil, resp, err 336 } 337 338 return analysis, resp, nil 339 }