Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Feature DependencyDiff (Version 0 Part 2) #2046

Merged
merged 64 commits into from Jul 18, 2022
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
d043b13
temp
aidenwang9867 Jul 8, 2022
5f95398
Update dependencies.go
aidenwang9867 Jul 8, 2022
c29a841
Update errors.go
aidenwang9867 Jul 8, 2022
572bef5
Update scorecard_results.go
aidenwang9867 Jul 8, 2022
dc50937
Update vulnerabilities.go
aidenwang9867 Jul 8, 2022
4e90206
save
aidenwang9867 Jul 8, 2022
1fee520
temp
aidenwang9867 Jul 9, 2022
0595cdf
temp
aidenwang9867 Jul 9, 2022
c5cb697
temp
aidenwang9867 Jul 9, 2022
7bc6911
temp
aidenwang9867 Jul 11, 2022
62fb494
temp
aidenwang9867 Jul 11, 2022
b6c3b2c
Merge branch 'ossf:main' into depdiff_p2
aidenwang9867 Jul 11, 2022
92a117e
temp
aidenwang9867 Jul 11, 2022
c49c7f4
temp
aidenwang9867 Jul 11, 2022
c733ba5
temp
aidenwang9867 Jul 11, 2022
1379082
temp
aidenwang9867 Jul 11, 2022
8a89984
temp
aidenwang9867 Jul 11, 2022
cdd1840
temp
aidenwang9867 Jul 11, 2022
0e1223d
temp
aidenwang9867 Jul 11, 2022
2ac26d7
temp
aidenwang9867 Jul 11, 2022
2b0ffed
temp
aidenwang9867 Jul 11, 2022
3fd0f77
Merge branch 'main' into depdiuff_p1_pr
aidenwang9867 Jul 11, 2022
5549e91
Merge branch 'ossf:main' into depdiff_p2
aidenwang9867 Jul 11, 2022
3faf9ed
tempsave:
aidenwang9867 Jul 12, 2022
f6049b8
Merge branch 'depdiff_p2' of https://github.com/aidenwang9867/scoreca…
aidenwang9867 Jul 12, 2022
6d24320
Merge branch 'ossf:main' into depdiff_p2
aidenwang9867 Jul 12, 2022
847b3e7
temp
aidenwang9867 Jul 12, 2022
5c64505
temp
aidenwang9867 Jul 12, 2022
af29bc9
Merge branch 'ossf:main' into depdiff_p2
aidenwang9867 Jul 12, 2022
ad9c056
temp
aidenwang9867 Jul 13, 2022
23a1745
temp
aidenwang9867 Jul 13, 2022
5fea8bd
temp0713-1
aidenwang9867 Jul 13, 2022
1c313bd
temp0713-2
aidenwang9867 Jul 13, 2022
5e9c33d
temp0713-3
aidenwang9867 Jul 13, 2022
cae5546
Merge branch 'main' into depdiff_p2
aidenwang9867 Jul 13, 2022
4da19cf
temp0713-4
aidenwang9867 Jul 13, 2022
26be711
temp0713-4
aidenwang9867 Jul 14, 2022
f3419b2
temp0713-5
aidenwang9867 Jul 14, 2022
70f81c2
temp0713-6
aidenwang9867 Jul 14, 2022
e3f4d87
temp0713-7
aidenwang9867 Jul 14, 2022
c9b8cc7
temp0713-8
aidenwang9867 Jul 14, 2022
aea729f
temp0713-9
aidenwang9867 Jul 14, 2022
fd3d7b1
temp0713-10
aidenwang9867 Jul 14, 2022
0e3cb52
temp0713-11
aidenwang9867 Jul 14, 2022
70a3894
temp0713-12
aidenwang9867 Jul 14, 2022
a9658df
1
aidenwang9867 Jul 14, 2022
e1e0653
temp
aidenwang9867 Jul 14, 2022
751d67d
temp
aidenwang9867 Jul 14, 2022
9de05d8
Merge branch 'main' into depdiff_p2
aidenwang9867 Jul 14, 2022
459cf97
temp
aidenwang9867 Jul 15, 2022
4e4e201
Merge branch 'depdiff_p2' of https://github.com/aidenwang9867/scoreca…
aidenwang9867 Jul 15, 2022
f243586
temp
aidenwang9867 Jul 15, 2022
0493379
temp
aidenwang9867 Jul 15, 2022
baae011
temp
aidenwang9867 Jul 15, 2022
1f42bf7
Merge branch 'main' into depdiff_p2
aidenwang9867 Jul 15, 2022
fc1e227
temp
aidenwang9867 Jul 16, 2022
a7547d4
temp
aidenwang9867 Jul 16, 2022
347d74d
save
aidenwang9867 Jul 18, 2022
4e5e7a4
Merge branch 'main' into depdiff_p2
aidenwang9867 Jul 18, 2022
e825159
save
aidenwang9867 Jul 18, 2022
a8f30d9
Merge branch 'depdiff_p2' of https://github.com/aidenwang9867/scoreca…
aidenwang9867 Jul 18, 2022
08fa625
save
aidenwang9867 Jul 18, 2022
3cb16cc
final_commit_before_merge
aidenwang9867 Jul 18, 2022
e2b13e0
Merge branch 'main' into depdiff_p2
aidenwang9867 Jul 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
162 changes: 162 additions & 0 deletions dependencydiff/dependencydiff.go
@@ -0,0 +1,162 @@
// Copyright 2022 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 dependencydiff

import (
"context"
"fmt"
"path"

"github.com/ossf/scorecard/v4/checker"
"github.com/ossf/scorecard/v4/checks"
"github.com/ossf/scorecard/v4/clients"
"github.com/ossf/scorecard/v4/clients/githubrepo"
"github.com/ossf/scorecard/v4/log"
"github.com/ossf/scorecard/v4/pkg"
)

// Depdiff is the exported name for dependency-diff.
const Depdiff = "Dependency-diff"

type dependencydiffContext struct {
logger *log.Logger
ownerName, repoName, baseSHA, headSHA string
ctx context.Context
ghRepo clients.Repo
ghRepoClient clients.RepoClient
ossFuzzClient clients.RepoClient
vulnsClient clients.VulnerabilitiesClient
ciiClient clients.CIIBestPracticesClient
changeTypesToCheck map[pkg.ChangeType]bool
checkNamesToRun []string
dependencydiffs []dependency
results []pkg.DependencyCheckResult
}

// GetDependencyDiffResults gets dependency changes between two given code commits BASE and HEAD
// along with the Scorecard check results of the dependencies, and returns a slice of DependencyCheckResult.
// TO use this API, an access token must be set following https://github.com/ossf/scorecard#authentication.
func GetDependencyDiffResults(
ctx context.Context, ownerName, repoName, baseSHA, headSHA string, scorecardChecksNames []string,
changeTypesToCheck map[pkg.ChangeType]bool) ([]pkg.DependencyCheckResult, error) {
// Fetch the raw dependency diffs.
dCtx := dependencydiffContext{
logger: log.NewLogger(log.InfoLevel),
ownerName: ownerName,
repoName: repoName,
baseSHA: baseSHA,
headSHA: headSHA,
ctx: ctx,
changeTypesToCheck: changeTypesToCheck,
checkNamesToRun: scorecardChecksNames,
}
err := fetchRawDependencyDiffData(&dCtx)
if err != nil {
return nil, fmt.Errorf("error in fetchRawDependencyDiffData: %w", err)
}

// Initialize the repo and client(s) corresponding to the checks to run.
err = initRepoAndClientByChecks(&dCtx)
if err != nil {
return nil, fmt.Errorf("error in initRepoAndClientByChecks: %w", err)
}
getScorecardCheckResults(&dCtx)
return dCtx.results, nil
}

func initRepoAndClientByChecks(dCtx *dependencydiffContext) error {
aidenwang9867 marked this conversation as resolved.
Show resolved Hide resolved
// Create the repo and the corresponding client if its check needs to run.
ghRepo, err := githubrepo.MakeGithubRepo(path.Join(dCtx.ownerName, dCtx.repoName))
if err != nil {
return fmt.Errorf("error creating the github repo: %w", err)
}
dCtx.ghRepo = ghRepo
dCtx.ghRepoClient = githubrepo.CreateGithubRepoClient(dCtx.ctx, dCtx.logger)
// Initialize these three clients as nil at first.
var ossFuzzClient clients.RepoClient
for _, cn := range dCtx.checkNamesToRun {
switch cn {
case checks.CheckFuzzing:
ossFuzzClient, err = githubrepo.CreateOssFuzzRepoClient(dCtx.ctx, dCtx.logger)
if err != nil {
return fmt.Errorf("error initializing the oss fuzz repo client: %w", err)
}
dCtx.ossFuzzClient = ossFuzzClient
case checks.CheckVulnerabilities:
dCtx.vulnsClient = clients.DefaultVulnerabilitiesClient()
case checks.CheckCIIBestPractices:
dCtx.ciiClient = clients.DefaultCIIBestPracticesClient()
}
}
return nil
}

func initScorecardChecks(checkNames []string) checker.CheckNameToFnMap {
aidenwang9867 marked this conversation as resolved.
Show resolved Hide resolved
checksToRun := checker.CheckNameToFnMap{}
if checkNames == nil && len(checkNames) == 0 {
// If no check names are provided, we run all the checks for the caller.
checksToRun = checks.AllChecks
} else {
for _, cn := range checkNames {
checksToRun[cn] = checks.AllChecks[cn]
}
}
return checksToRun
}

func getScorecardCheckResults(dCtx *dependencydiffContext) {
// Initialize the checks to run from the caller's input.
checksToRun := initScorecardChecks(dCtx.checkNamesToRun)
for _, d := range dCtx.dependencydiffs {
depCheckResult := pkg.DependencyCheckResult{
PackageURL: d.PackageURL,
SourceRepository: d.SourceRepository,
ChangeType: d.ChangeType,
ManifestPath: d.ManifestPath,
Ecosystem: d.Ecosystem,
Version: d.Version,
Name: d.Name,
}
// For now we skip those without source repo urls.
// TODO: use the BigQuery dataset to supplement null source repo URLs to fetch the Scorecard results for them.
if d.SourceRepository != nil && *d.SourceRepository != "" {
if d.ChangeType != nil && (dCtx.changeTypesToCheck[*d.ChangeType] || dCtx.changeTypesToCheck == nil) {
laurentsimon marked this conversation as resolved.
Show resolved Hide resolved
// Run scorecard on those types of dependencies that the caller would like to check.
// If the input map changeTypesToCheck is empty, by default, we run checks for all valid types.
// TODO: use the Scorecare REST API to retrieve the Scorecard result statelessly.
scorecardResult, err := pkg.RunScorecards(
dCtx.ctx,
dCtx.ghRepo,
// TODO: In future versions, ideally, this should be
// the commitSHA corresponding to d.Version instead of HEAD.
clients.HeadSHA,
checksToRun,
dCtx.ghRepoClient,
dCtx.ossFuzzClient,
dCtx.ciiClient,
dCtx.vulnsClient,
)
// If the run fails, we leave the current dependency scorecard result empty and record the error
// rather than letting the entire API return nil since we still expect results for other dependencies.
if err != nil {
aidenwang9867 marked this conversation as resolved.
Show resolved Hide resolved
depCheckResult.ScorecardResultsWithError.Error = fmt.Errorf("error running the scorecard checks: %w", err)
aidenwang9867 marked this conversation as resolved.
Show resolved Hide resolved
} else { // Otherwise, we record the scorecard check results for this dependency.
depCheckResult.ScorecardResultsWithError.ScorecardResults = &scorecardResult
}
}
}
dCtx.results = append(dCtx.results, depCheckResult)
}
}