github.com/google/go-github/v57@v57.0.0/github/security_advisories_test.go (about) 1 // Copyright 2023 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 "net/http" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/google/go-cmp/cmp" 17 ) 18 19 func TestSecurityAdvisoriesService_RequestCVE(t *testing.T) { 20 client, mux, _, teardown := setup() 21 defer teardown() 22 23 mux.HandleFunc("/repos/o/r/security-advisories/ghsa_id_ok/cve", func(w http.ResponseWriter, r *http.Request) { 24 testMethod(t, r, "POST") 25 w.WriteHeader(http.StatusOK) 26 }) 27 28 mux.HandleFunc("/repos/o/r/security-advisories/ghsa_id_accepted/cve", func(w http.ResponseWriter, r *http.Request) { 29 testMethod(t, r, "POST") 30 w.WriteHeader(http.StatusAccepted) 31 }) 32 33 ctx := context.Background() 34 _, err := client.SecurityAdvisories.RequestCVE(ctx, "o", "r", "ghsa_id_ok") 35 if err != nil { 36 t.Errorf("SecurityAdvisoriesService.RequestCVE returned error: %v", err) 37 } 38 39 _, err = client.SecurityAdvisories.RequestCVE(ctx, "o", "r", "ghsa_id_accepted") 40 if err != nil { 41 t.Errorf("SecurityAdvisoriesService.RequestCVE returned error: %v", err) 42 } 43 44 const methodName = "RequestCVE" 45 testBadOptions(t, methodName, func() (err error) { 46 _, err = client.SecurityAdvisories.RequestCVE(ctx, "\n", "\n", "\n") 47 return err 48 }) 49 50 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 51 resp, err := client.SecurityAdvisories.RequestCVE(ctx, "o", "r", "ghsa_id") 52 if err == nil { 53 t.Errorf("testNewRequestAndDoFailure %v should have return err", methodName) 54 } 55 return resp, err 56 }) 57 } 58 59 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg_BadRequest(t *testing.T) { 60 client, mux, _, teardown := setup() 61 defer teardown() 62 63 mux.HandleFunc("/orgs/o/security-advisories", func(w http.ResponseWriter, r *http.Request) { 64 testMethod(t, r, "GET") 65 66 http.Error(w, "Bad Request", 400) 67 }) 68 69 ctx := context.Background() 70 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", nil) 71 if err == nil { 72 t.Errorf("Expected HTTP 400 response") 73 } 74 if got, want := resp.Response.StatusCode, http.StatusBadRequest; got != want { 75 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return status %d, want %d", got, want) 76 } 77 if advisories != nil { 78 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return %+v, want nil", advisories) 79 } 80 } 81 82 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg_NotFound(t *testing.T) { 83 client, mux, _, teardown := setup() 84 defer teardown() 85 86 mux.HandleFunc("/orgs/o/security-advisories", func(w http.ResponseWriter, r *http.Request) { 87 testMethod(t, r, "GET") 88 89 query := r.URL.Query() 90 if query.Get("state") != "draft" { 91 t.Errorf("ListRepositorySecurityAdvisoriesForOrg returned %+v, want %+v", query.Get("state"), "draft") 92 } 93 94 http.NotFound(w, r) 95 }) 96 97 ctx := context.Background() 98 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", &ListRepositorySecurityAdvisoriesOptions{ 99 State: "draft", 100 }) 101 if err == nil { 102 t.Errorf("Expected HTTP 404 response") 103 } 104 if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { 105 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return status %d, want %d", got, want) 106 } 107 if advisories != nil { 108 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return %+v, want nil", advisories) 109 } 110 } 111 112 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg_UnmarshalError(t *testing.T) { 113 client, mux, _, teardown := setup() 114 defer teardown() 115 116 mux.HandleFunc("/orgs/o/security-advisories", func(w http.ResponseWriter, r *http.Request) { 117 testMethod(t, r, "GET") 118 119 w.WriteHeader(http.StatusOK) 120 assertWrite(t, w, []byte(`[{"ghsa_id": 12334354}]`)) 121 }) 122 123 ctx := context.Background() 124 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", nil) 125 if err == nil { 126 t.Errorf("Expected unmarshal error") 127 } else if !strings.Contains(err.Error(), "json: cannot unmarshal number into Go struct field SecurityAdvisory.ghsa_id of type string") { 128 t.Errorf("ListRepositorySecurityAdvisoriesForOrg returned unexpected error: %v", err) 129 } 130 if got, want := resp.Response.StatusCode, http.StatusOK; got != want { 131 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return status %d, want %d", got, want) 132 } 133 if advisories != nil { 134 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return %+v, want nil", advisories) 135 } 136 } 137 138 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg(t *testing.T) { 139 client, mux, _, teardown := setup() 140 defer teardown() 141 142 mux.HandleFunc("/orgs/o/security-advisories", func(w http.ResponseWriter, r *http.Request) { 143 testMethod(t, r, "GET") 144 145 w.WriteHeader(http.StatusOK) 146 assertWrite(t, w, []byte(`[ 147 { 148 "ghsa_id": "GHSA-abcd-1234-efgh", 149 "cve_id": "CVE-2050-00000" 150 } 151 ]`)) 152 }) 153 154 ctx := context.Background() 155 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", nil) 156 if err != nil { 157 t.Errorf("ListRepositorySecurityAdvisoriesForOrg returned error: %v, want nil", err) 158 } 159 if got, want := resp.Response.StatusCode, http.StatusOK; got != want { 160 t.Errorf("ListRepositorySecurityAdvisoriesForOrg return status %d, want %d", got, want) 161 } 162 163 want := []*SecurityAdvisory{ 164 { 165 GHSAID: String("GHSA-abcd-1234-efgh"), 166 CVEID: String("CVE-2050-00000"), 167 }, 168 } 169 if !cmp.Equal(advisories, want) { 170 t.Errorf("ListRepositorySecurityAdvisoriesForOrg returned %+v, want %+v", advisories, want) 171 } 172 173 methodName := "ListRepositorySecurityAdvisoriesForOrg" 174 testBadOptions(t, methodName, func() (err error) { 175 _, _, err = client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "\n", &ListRepositorySecurityAdvisoriesOptions{ 176 Sort: "\n", 177 }) 178 return err 179 }) 180 181 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 182 got, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", nil) 183 if got != nil { 184 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 185 } 186 return resp, err 187 }) 188 } 189 190 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories_BadRequest(t *testing.T) { 191 client, mux, _, teardown := setup() 192 defer teardown() 193 194 mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) { 195 testMethod(t, r, "GET") 196 197 http.Error(w, "Bad Request", 400) 198 }) 199 200 ctx := context.Background() 201 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil) 202 if err == nil { 203 t.Errorf("Expected HTTP 400 response") 204 } 205 if got, want := resp.Response.StatusCode, http.StatusBadRequest; got != want { 206 t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want) 207 } 208 if advisories != nil { 209 t.Errorf("ListRepositorySecurityAdvisories return %+v, want nil", advisories) 210 } 211 } 212 213 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories_NotFound(t *testing.T) { 214 client, mux, _, teardown := setup() 215 defer teardown() 216 217 mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) { 218 testMethod(t, r, "GET") 219 220 query := r.URL.Query() 221 if query.Get("state") != "draft" { 222 t.Errorf("ListRepositorySecurityAdvisories returned %+v, want %+v", query.Get("state"), "draft") 223 } 224 225 http.NotFound(w, r) 226 }) 227 228 ctx := context.Background() 229 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", &ListRepositorySecurityAdvisoriesOptions{ 230 State: "draft", 231 }) 232 if err == nil { 233 t.Errorf("Expected HTTP 404 response") 234 } 235 if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want { 236 t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want) 237 } 238 if advisories != nil { 239 t.Errorf("ListRepositorySecurityAdvisories return %+v, want nil", advisories) 240 } 241 } 242 243 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories_UnmarshalError(t *testing.T) { 244 client, mux, _, teardown := setup() 245 defer teardown() 246 247 mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) { 248 testMethod(t, r, "GET") 249 250 w.WriteHeader(http.StatusOK) 251 assertWrite(t, w, []byte(`[{"ghsa_id": 12334354}]`)) 252 }) 253 254 ctx := context.Background() 255 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil) 256 if err == nil { 257 t.Errorf("Expected unmarshal error") 258 } else if !strings.Contains(err.Error(), "json: cannot unmarshal number into Go struct field SecurityAdvisory.ghsa_id of type string") { 259 t.Errorf("ListRepositorySecurityAdvisories returned unexpected error: %v", err) 260 } 261 if got, want := resp.Response.StatusCode, http.StatusOK; got != want { 262 t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want) 263 } 264 if advisories != nil { 265 t.Errorf("ListRepositorySecurityAdvisories return %+v, want nil", advisories) 266 } 267 } 268 269 func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories(t *testing.T) { 270 client, mux, _, teardown := setup() 271 defer teardown() 272 273 mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) { 274 testMethod(t, r, "GET") 275 276 w.WriteHeader(http.StatusOK) 277 assertWrite(t, w, []byte(`[ 278 { 279 "ghsa_id": "GHSA-abcd-1234-efgh", 280 "cve_id": "CVE-2050-00000" 281 } 282 ]`)) 283 }) 284 285 ctx := context.Background() 286 advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil) 287 if err != nil { 288 t.Errorf("ListRepositorySecurityAdvisories returned error: %v, want nil", err) 289 } 290 if got, want := resp.Response.StatusCode, http.StatusOK; got != want { 291 t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want) 292 } 293 294 want := []*SecurityAdvisory{ 295 { 296 GHSAID: String("GHSA-abcd-1234-efgh"), 297 CVEID: String("CVE-2050-00000"), 298 }, 299 } 300 if !cmp.Equal(advisories, want) { 301 t.Errorf("ListRepositorySecurityAdvisories returned %+v, want %+v", advisories, want) 302 } 303 304 methodName := "ListRepositorySecurityAdvisories" 305 testBadOptions(t, methodName, func() (err error) { 306 _, _, err = client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "\n", "\n", &ListRepositorySecurityAdvisoriesOptions{ 307 Sort: "\n", 308 }) 309 return err 310 }) 311 312 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 313 got, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil) 314 if got != nil { 315 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 316 } 317 return resp, err 318 }) 319 } 320 321 func TestListGlobalSecurityAdvisories(t *testing.T) { 322 client, mux, _, teardown := setup() 323 defer teardown() 324 325 mux.HandleFunc("/advisories", func(w http.ResponseWriter, r *http.Request) { 326 testMethod(t, r, "GET") 327 testFormValues(t, r, values{"cve_id": "CVE-xoxo-1234"}) 328 329 fmt.Fprint(w, `[{ 330 "id": 1, 331 "ghsa_id": "GHSA-xoxo-1234-xoxo", 332 "cve_id": "CVE-xoxo-1234", 333 "url": "https://api.github.com/advisories/GHSA-xoxo-1234-xoxo", 334 "html_url": "https://github.com/advisories/GHSA-xoxo-1234-xoxo", 335 "repository_advisory_url": "https://api.github.com/repos/project/a-package/security-advisories/GHSA-xoxo-1234-xoxo", 336 "summary": "Heartbleed security advisory", 337 "description": "This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information.", 338 "type": "reviewed", 339 "severity": "high", 340 "source_code_location": "https://github.com/project/a-package", 341 "identifiers": [ 342 { 343 "type": "GHSA", 344 "value": "GHSA-xoxo-1234-xoxo" 345 }, 346 { 347 "type": "CVE", 348 "value": "CVE-xoxo-1234" 349 } 350 ], 351 "references": ["https://nvd.nist.gov/vuln/detail/CVE-xoxo-1234"], 352 "published_at": "1996-06-20T00:00:00Z", 353 "updated_at": "1996-06-20T00:00:00Z", 354 "github_reviewed_at": "1996-06-20T00:00:00Z", 355 "nvd_published_at": "1996-06-20T00:00:00Z", 356 "withdrawn_at": null, 357 "vulnerabilities": [ 358 { 359 "package": { 360 "ecosystem": "npm", 361 "name": "a-package" 362 }, 363 "first_patched_version": "1.0.3", 364 "vulnerable_version_range": "<=1.0.2", 365 "vulnerable_functions": ["a_function"] 366 } 367 ], 368 "cvss": { 369 "vector_string": "CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H", 370 "score": 7.6 371 }, 372 "cwes": [ 373 { 374 "cwe_id": "CWE-400", 375 "name": "Uncontrolled Resource Consumption" 376 } 377 ], 378 "credits": [ 379 { 380 "user": { 381 "login": "user", 382 "id": 1, 383 "node_id": "12=", 384 "avatar_url": "a", 385 "gravatar_id": "", 386 "url": "a", 387 "html_url": "b", 388 "followers_url": "b", 389 "following_url": "c", 390 "gists_url": "d", 391 "starred_url": "e", 392 "subscriptions_url": "f", 393 "organizations_url": "g", 394 "repos_url": "h", 395 "events_url": "i", 396 "received_events_url": "j", 397 "type": "User", 398 "site_admin": false 399 }, 400 "type": "analyst" 401 } 402 ] 403 } 404 ]`) 405 }) 406 407 ctx := context.Background() 408 opts := &ListGlobalSecurityAdvisoriesOptions{CVEID: String("CVE-xoxo-1234")} 409 410 advisories, _, err := client.SecurityAdvisories.ListGlobalSecurityAdvisories(ctx, opts) 411 if err != nil { 412 t.Errorf("SecurityAdvisories.ListGlobalSecurityAdvisories returned error: %v", err) 413 } 414 415 date := Timestamp{time.Date(1996, time.June, 20, 00, 00, 00, 0, time.UTC)} 416 want := []*GlobalSecurityAdvisory{ 417 { 418 ID: Int64(1), 419 SecurityAdvisory: SecurityAdvisory{ 420 GHSAID: String("GHSA-xoxo-1234-xoxo"), 421 CVEID: String("CVE-xoxo-1234"), 422 URL: String("https://api.github.com/advisories/GHSA-xoxo-1234-xoxo"), 423 HTMLURL: String("https://github.com/advisories/GHSA-xoxo-1234-xoxo"), 424 Severity: String("high"), 425 Summary: String("Heartbleed security advisory"), 426 Description: String("This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information."), 427 Identifiers: []*AdvisoryIdentifier{ 428 { 429 Type: String("GHSA"), 430 Value: String("GHSA-xoxo-1234-xoxo"), 431 }, 432 { 433 Type: String("CVE"), 434 Value: String("CVE-xoxo-1234"), 435 }, 436 }, 437 PublishedAt: &date, 438 UpdatedAt: &date, 439 WithdrawnAt: nil, 440 CVSS: &AdvisoryCVSS{ 441 VectorString: String("CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H"), 442 Score: Float64(7.6), 443 }, 444 CWEs: []*AdvisoryCWEs{ 445 { 446 CWEID: String("CWE-400"), 447 Name: String("Uncontrolled Resource Consumption"), 448 }, 449 }, 450 }, 451 References: []string{"https://nvd.nist.gov/vuln/detail/CVE-xoxo-1234"}, 452 Vulnerabilities: []*GlobalSecurityVulnerability{ 453 { 454 Package: &VulnerabilityPackage{ 455 Ecosystem: String("npm"), 456 Name: String("a-package"), 457 }, 458 FirstPatchedVersion: String("1.0.3"), 459 VulnerableVersionRange: String("<=1.0.2"), 460 VulnerableFunctions: []string{"a_function"}, 461 }, 462 }, 463 RepositoryAdvisoryURL: String("https://api.github.com/repos/project/a-package/security-advisories/GHSA-xoxo-1234-xoxo"), 464 Type: String("reviewed"), 465 SourceCodeLocation: String("https://github.com/project/a-package"), 466 GithubReviewedAt: &date, 467 NVDPublishedAt: &date, 468 Credits: []*Credit{ 469 { 470 User: &User{ 471 Login: String("user"), 472 ID: Int64(1), 473 NodeID: String("12="), 474 AvatarURL: String("a"), 475 GravatarID: String(""), 476 URL: String("a"), 477 HTMLURL: String("b"), 478 FollowersURL: String("b"), 479 FollowingURL: String("c"), 480 GistsURL: String("d"), 481 StarredURL: String("e"), 482 SubscriptionsURL: String("f"), 483 OrganizationsURL: String("g"), 484 ReposURL: String("h"), 485 EventsURL: String("i"), 486 ReceivedEventsURL: String("j"), 487 Type: String("User"), 488 SiteAdmin: Bool(false), 489 }, 490 Type: String("analyst"), 491 }, 492 }, 493 }, 494 } 495 496 if !cmp.Equal(advisories, want) { 497 t.Errorf("SecurityAdvisories.ListGlobalSecurityAdvisories %+v, want %+v", advisories, want) 498 } 499 500 const methodName = "ListGlobalSecurityAdvisories" 501 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 502 _, resp, err := client.SecurityAdvisories.ListGlobalSecurityAdvisories(ctx, nil) 503 return resp, err 504 }) 505 } 506 507 func TestGetGlobalSecurityAdvisories(t *testing.T) { 508 client, mux, _, teardown := setup() 509 defer teardown() 510 511 mux.HandleFunc("/advisories/GHSA-xoxo-1234-xoxo", func(w http.ResponseWriter, r *http.Request) { 512 testMethod(t, r, "GET") 513 514 fmt.Fprint(w, `{ 515 "id": 1, 516 "ghsa_id": "GHSA-xoxo-1234-xoxo", 517 "cve_id": "CVE-xoxo-1234", 518 "url": "https://api.github.com/advisories/GHSA-xoxo-1234-xoxo", 519 "html_url": "https://github.com/advisories/GHSA-xoxo-1234-xoxo", 520 "repository_advisory_url": "https://api.github.com/repos/project/a-package/security-advisories/GHSA-xoxo-1234-xoxo", 521 "summary": "Heartbleed security advisory", 522 "description": "This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information.", 523 "type": "reviewed", 524 "severity": "high", 525 "source_code_location": "https://github.com/project/a-package", 526 "identifiers": [ 527 { 528 "type": "GHSA", 529 "value": "GHSA-xoxo-1234-xoxo" 530 }, 531 { 532 "type": "CVE", 533 "value": "CVE-xoxo-1234" 534 } 535 ], 536 "references": ["https://nvd.nist.gov/vuln/detail/CVE-xoxo-1234"], 537 "published_at": "1996-06-20T00:00:00Z", 538 "updated_at": "1996-06-20T00:00:00Z", 539 "github_reviewed_at": "1996-06-20T00:00:00Z", 540 "nvd_published_at": "1996-06-20T00:00:00Z", 541 "withdrawn_at": null, 542 "vulnerabilities": [ 543 { 544 "package": { 545 "ecosystem": "npm", 546 "name": "a-package" 547 }, 548 "first_patched_version": "1.0.3", 549 "vulnerable_version_range": "<=1.0.2", 550 "vulnerable_functions": ["a_function"] 551 } 552 ], 553 "cvss": { 554 "vector_string": "CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H", 555 "score": 7.6 556 }, 557 "cwes": [ 558 { 559 "cwe_id": "CWE-400", 560 "name": "Uncontrolled Resource Consumption" 561 } 562 ], 563 "credits": [ 564 { 565 "user": { 566 "login": "user", 567 "id": 1, 568 "node_id": "12=", 569 "avatar_url": "a", 570 "gravatar_id": "", 571 "url": "a", 572 "html_url": "b", 573 "followers_url": "b", 574 "following_url": "c", 575 "gists_url": "d", 576 "starred_url": "e", 577 "subscriptions_url": "f", 578 "organizations_url": "g", 579 "repos_url": "h", 580 "events_url": "i", 581 "received_events_url": "j", 582 "type": "User", 583 "site_admin": false 584 }, 585 "type": "analyst" 586 } 587 ] 588 }`) 589 }) 590 591 ctx := context.Background() 592 advisory, _, err := client.SecurityAdvisories.GetGlobalSecurityAdvisories(ctx, "GHSA-xoxo-1234-xoxo") 593 if err != nil { 594 t.Errorf("SecurityAdvisories.GetGlobalSecurityAdvisories returned error: %v", err) 595 } 596 597 date := Timestamp{time.Date(1996, time.June, 20, 00, 00, 00, 0, time.UTC)} 598 want := &GlobalSecurityAdvisory{ 599 ID: Int64(1), 600 SecurityAdvisory: SecurityAdvisory{ 601 GHSAID: String("GHSA-xoxo-1234-xoxo"), 602 CVEID: String("CVE-xoxo-1234"), 603 URL: String("https://api.github.com/advisories/GHSA-xoxo-1234-xoxo"), 604 HTMLURL: String("https://github.com/advisories/GHSA-xoxo-1234-xoxo"), 605 Severity: String("high"), 606 Summary: String("Heartbleed security advisory"), 607 Description: String("This bug allows an attacker to read portions of the affected server’s memory, potentially disclosing sensitive information."), 608 Identifiers: []*AdvisoryIdentifier{ 609 { 610 Type: String("GHSA"), 611 Value: String("GHSA-xoxo-1234-xoxo"), 612 }, 613 { 614 Type: String("CVE"), 615 Value: String("CVE-xoxo-1234"), 616 }, 617 }, 618 PublishedAt: &date, 619 UpdatedAt: &date, 620 WithdrawnAt: nil, 621 CVSS: &AdvisoryCVSS{ 622 VectorString: String("CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:C/C:H/I:H/A:H"), 623 Score: Float64(7.6), 624 }, 625 CWEs: []*AdvisoryCWEs{ 626 { 627 CWEID: String("CWE-400"), 628 Name: String("Uncontrolled Resource Consumption"), 629 }, 630 }, 631 }, 632 RepositoryAdvisoryURL: String("https://api.github.com/repos/project/a-package/security-advisories/GHSA-xoxo-1234-xoxo"), 633 Type: String("reviewed"), 634 SourceCodeLocation: String("https://github.com/project/a-package"), 635 References: []string{"https://nvd.nist.gov/vuln/detail/CVE-xoxo-1234"}, 636 GithubReviewedAt: &date, 637 NVDPublishedAt: &date, 638 639 Vulnerabilities: []*GlobalSecurityVulnerability{ 640 { 641 Package: &VulnerabilityPackage{ 642 Ecosystem: String("npm"), 643 Name: String("a-package"), 644 }, 645 FirstPatchedVersion: String("1.0.3"), 646 VulnerableVersionRange: String("<=1.0.2"), 647 VulnerableFunctions: []string{"a_function"}, 648 }, 649 }, 650 Credits: []*Credit{ 651 { 652 User: &User{ 653 Login: String("user"), 654 ID: Int64(1), 655 NodeID: String("12="), 656 AvatarURL: String("a"), 657 GravatarID: String(""), 658 URL: String("a"), 659 HTMLURL: String("b"), 660 FollowersURL: String("b"), 661 FollowingURL: String("c"), 662 GistsURL: String("d"), 663 StarredURL: String("e"), 664 SubscriptionsURL: String("f"), 665 OrganizationsURL: String("g"), 666 ReposURL: String("h"), 667 EventsURL: String("i"), 668 ReceivedEventsURL: String("j"), 669 Type: String("User"), 670 SiteAdmin: Bool(false), 671 }, 672 Type: String("analyst"), 673 }, 674 }, 675 } 676 677 if !cmp.Equal(advisory, want) { 678 t.Errorf("SecurityAdvisories.GetGlobalSecurityAdvisories %+v, want %+v", advisory, want) 679 } 680 681 const methodName = "GetGlobalSecurityAdvisories" 682 683 testBadOptions(t, methodName, func() (err error) { 684 _, _, err = client.SecurityAdvisories.GetGlobalSecurityAdvisories(ctx, "CVE-\n-1234") 685 return err 686 }) 687 688 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 689 got, resp, err := client.SecurityAdvisories.GetGlobalSecurityAdvisories(ctx, "e") 690 if got != nil { 691 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 692 } 693 return resp, err 694 }) 695 }