Skip to content

Commit

Permalink
added API to lists security advisories in a repository
Browse files Browse the repository at this point in the history
  • Loading branch information
anishrajan25 authored Aug 26, 2023
1 parent 1041151 commit 7285192
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 1 deletion.
24 changes: 24 additions & 0 deletions github/security_advisories.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,27 @@ func (s *SecurityAdvisoriesService) ListRepositorySecurityAdvisoriesForOrg(ctx c

return advisories, resp, nil
}

// ListRepositorySecurityAdvisories lists the security advisories in a repository.
//
// Github API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/security-advisories/repository-advisories?apiVersion=2022-11-28#list-repository-security-advisories
func (s *SecurityAdvisoriesService) ListRepositorySecurityAdvisories(ctx context.Context, owner string, repo string, opt *ListRepositorySecurityAdvisoriesOptions) ([]*RepoSecurityAdvisory, *Response, error) {
url := fmt.Sprintf("repos/%v/%v/security-advisories", owner, repo)
url, err := addOptions(url, opt)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}

var advisories []*RepoSecurityAdvisory
resp, err := s.client.Do(ctx, req, &advisories)
if err != nil {
return nil, resp, err
}

return advisories, resp, nil
}
140 changes: 139 additions & 1 deletion github/security_advisories_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,18 @@ func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg_NotFou
mux.HandleFunc("/orgs/o/security-advisories", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")

query := r.URL.Query()
if query.Get("state") != "draft" {
t.Errorf("ListRepositorySecurityAdvisoriesForOrg returned %+v, want %+v", query.Get("state"), "draft")
}

http.NotFound(w, r)
})

ctx := context.Background()
advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", nil)
advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisoriesForOrg(ctx, "o", &ListRepositorySecurityAdvisoriesOptions{
State: "draft",
})
if err == nil {
t.Errorf("Expected HTTP 404 response")
}
Expand Down Expand Up @@ -176,3 +183,134 @@ func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg(t *tes
return resp, err
})
}

func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories_BadRequest(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")

http.Error(w, "Bad Request", 400)
})

ctx := context.Background()
advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil)
if err == nil {
t.Errorf("Expected HTTP 400 response")
}
if got, want := resp.Response.StatusCode, http.StatusBadRequest; got != want {
t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want)
}
if advisories != nil {
t.Errorf("ListRepositorySecurityAdvisories return %+v, want nil", advisories)
}
}

func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories_NotFound(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")

query := r.URL.Query()
if query.Get("state") != "draft" {
t.Errorf("ListRepositorySecurityAdvisories returned %+v, want %+v", query.Get("state"), "draft")
}

http.NotFound(w, r)
})

ctx := context.Background()
advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", &ListRepositorySecurityAdvisoriesOptions{
State: "draft",
})
if err == nil {
t.Errorf("Expected HTTP 404 response")
}
if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want {
t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want)
}
if advisories != nil {
t.Errorf("ListRepositorySecurityAdvisories return %+v, want nil", advisories)
}
}

func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories_UnmarshalError(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")

w.WriteHeader(http.StatusOK)
w.Write([]byte(`[{"ghsa_id": 12334354}]`))
})

ctx := context.Background()
advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil)
if err == nil {
t.Errorf("Expected unmarshal error")
} else if !strings.Contains(err.Error(), "json: cannot unmarshal number into Go struct field RepoSecurityAdvisory.ghsa_id of type string") {
t.Errorf("ListRepositorySecurityAdvisories returned unexpected error: %v", err)
}
if got, want := resp.Response.StatusCode, http.StatusOK; got != want {
t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want)
}
if advisories != nil {
t.Errorf("ListRepositorySecurityAdvisories return %+v, want nil", advisories)
}
}

func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/r/security-advisories", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")

w.WriteHeader(http.StatusOK)
w.Write([]byte(`[
{
"ghsa_id": "GHSA-abcd-1234-efgh",
"cve_id": "CVE-2050-00000"
}
]`))
})

ctx := context.Background()
advisories, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil)
if err != nil {
t.Errorf("ListRepositorySecurityAdvisories returned error: %v, want nil", err)
}
if got, want := resp.Response.StatusCode, http.StatusOK; got != want {
t.Errorf("ListRepositorySecurityAdvisories return status %d, want %d", got, want)
}

want := []*RepoSecurityAdvisory{
{
GHSAID: String("GHSA-abcd-1234-efgh"),
CVEID: String("CVE-2050-00000"),
},
}
if !cmp.Equal(advisories, want) {
t.Errorf("ListRepositorySecurityAdvisories returned %+v, want %+v", advisories, want)
}

methodName := "ListRepositorySecurityAdvisories"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "\n", "\n", &ListRepositorySecurityAdvisoriesOptions{
Sort: "\n",
})
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.SecurityAdvisories.ListRepositorySecurityAdvisories(ctx, "o", "r", nil)
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

0 comments on commit 7285192

Please sign in to comment.