Skip to content

Commit

Permalink
Use RepoClient API for Fuzzing (#855)
Browse files Browse the repository at this point in the history
Co-authored-by: Azeem Shaikh <azeems@google.com>
  • Loading branch information
azeemshaikh38 and azeemsgoogle authored Aug 14, 2021
1 parent 4c585f2 commit 42ee430
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 8 deletions.
20 changes: 14 additions & 6 deletions checks/fuzzing.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ package checks
import (
"fmt"

"github.com/google/go-github/v38/github"

"github.com/ossf/scorecard/v2/checker"
"github.com/ossf/scorecard/v2/clients"
"github.com/ossf/scorecard/v2/clients/githubrepo"
sce "github.com/ossf/scorecard/v2/errors"
)

Expand All @@ -33,15 +33,23 @@ func init() {

// Fuzzing runs Fuzzing check.
func Fuzzing(c *checker.CheckRequest) checker.CheckResult {
url := fmt.Sprintf("github.com/%s/%s", c.Owner, c.Repo)
searchString := url + " repo:google/oss-fuzz in:file filename:project.yaml"
results, _, err := c.Client.Search.Code(c.Ctx, searchString, &github.SearchOptions{})
ossFuzzRepo := githubrepo.CreateGithubRepoClient(c.Ctx, c.Client, c.GraphClient)
if err := ossFuzzRepo.InitRepo("google", "oss-fuzz"); err != nil {
e := sce.Create(sce.ErrScorecardInternal, fmt.Sprintf("InitRepo: %v", err))
return checker.CreateRuntimeErrorResult(CheckFuzzing, e)
}

req := clients.SearchRequest{
Query: c.RepoClient.URL(),
Filename: "project.yaml",
}
result, err := ossFuzzRepo.Search(req)
if err != nil {
e := sce.Create(sce.ErrScorecardInternal, fmt.Sprintf("Client.Search.Code: %v", err))
return checker.CreateRuntimeErrorResult(CheckFuzzing, e)
}

if *results.Total > 0 {
if result.Hits > 0 {
return checker.CreateMaxScoreResult(CheckFuzzing,
"project is fuzzed in OSS-Fuzz")
}
Expand Down
27 changes: 27 additions & 0 deletions clients/githubrepo/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (

// Client is GitHub-specific implementation of RepoClient.
type Client struct {
owner string
repoName string
repo *github.Repository
repoClient *github.Client
graphClient *graphqlHandler
Expand All @@ -44,6 +46,8 @@ func (client *Client) InitRepo(owner, repoName string) error {
return clients.NewRepoUnavailableError(err)
}
client.repo = repo
client.owner = owner
client.repoName = repoName

// Init tarballHandler.
if err := client.tarball.init(client.ctx, client.repo); err != nil {
Expand All @@ -63,6 +67,11 @@ func (client *Client) InitRepo(owner, repoName string) error {
return nil
}

// URL implements RepoClient.URL.
func (client *Client) URL() string {
return fmt.Sprintf("github.com/%s/%s", client.owner, client.repoName)
}

// ListFiles implements RepoClient.ListFiles.
func (client *Client) ListFiles(predicate func(string) (bool, error)) ([]string, error) {
return client.tarball.listFiles(predicate)
Expand Down Expand Up @@ -103,6 +112,24 @@ func (client *Client) GetDefaultBranch() (clients.BranchRef, error) {
return client.graphClient.getDefaultBranch()
}

// Search implements RepoClient.Search.
func (client *Client) Search(request clients.SearchRequest) (clients.SearchResult, error) {
var query string
if request.Filename == "" {
query = fmt.Sprintf("%s repo:%s/%s", request.Query, client.owner, client.repoName)
} else {
query = fmt.Sprintf("%s repo:%s/%s in:file filename:%s",
request.Query, client.owner, client.repoName, request.Filename)
}
res, _, err := client.repoClient.Search.Code(client.ctx, query, &github.SearchOptions{})
if err != nil {
return clients.SearchResult{}, fmt.Errorf("Search.Code: %w", err)
}
return clients.SearchResult{
Hits: res.GetTotal(),
}, nil
}

// Close implements RepoClient.Close.
func (client *Client) Close() error {
return client.tarball.cleanup()
Expand Down
2 changes: 2 additions & 0 deletions clients/repo_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func NewRepoUnavailableError(err error) error {
// RepoClient interface is used by Scorecard checks to access a repo.
type RepoClient interface {
InitRepo(owner, repo string) error
URL() string
IsArchived() (bool, error)
ListFiles(predicate func(string) (bool, error)) ([]string, error)
GetFileContent(filename string) ([]byte, error)
Expand All @@ -53,5 +54,6 @@ type RepoClient interface {
ListCommits() ([]Commit, error)
ListReleases() ([]Release, error)
ListContributors() ([]Contributor, error)
Search(request SearchRequest) (SearchResult, error)
Close() error
}
27 changes: 27 additions & 0 deletions clients/search.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2021 Security Scorecard Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package clients

// SearchRequest queries a repo for `Query`.
// If `Filename` is provided, only files with matching path is queried.
type SearchRequest struct {
Query string
Filename string
}

// SearchResult returns the results from a search request on a repo.
type SearchResult struct {
Hits int
}
9 changes: 7 additions & 2 deletions e2e/fuzzing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// nolint: dupl
package e2e

import (
Expand All @@ -22,18 +23,22 @@ import (

"github.com/ossf/scorecard/v2/checker"
"github.com/ossf/scorecard/v2/checks"
"github.com/ossf/scorecard/v2/clients/githubrepo"
scut "github.com/ossf/scorecard/v2/utests"
)

var _ = Describe("E2E TEST:Fuzzing", func() {
var _ = Describe("E2E TEST:"+checks.CheckFuzzing, func() {
Context("E2E TEST:Validating use of fuzzing tools", func() {
It("Should return use of fuzzing tools", func() {
dl := scut.TestDetailLogger{}
repoClient := githubrepo.CreateGithubRepoClient(context.Background(), ghClient, graphClient)
err := repoClient.InitRepo("tensorflow", "tensorflow")
Expect(err).Should(BeNil())
req := checker.CheckRequest{
Ctx: context.Background(),
Client: ghClient,
HTTPClient: httpClient,
RepoClient: nil,
RepoClient: repoClient,
Owner: "tensorflow",
Repo: "tensorflow",
GraphClient: graphClient,
Expand Down

0 comments on commit 42ee430

Please sign in to comment.