Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into gitlab-conclusion-fields
  • Loading branch information
ashearin committed Nov 29, 2023
2 parents 39f5ea3 + ce0b54e commit c849068
Show file tree
Hide file tree
Showing 12 changed files with 528 additions and 119 deletions.
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
- [Default Scorecard Checks](#scorecard-checks)
- [Detailed Check Documentation](docs/checks.md) (Scoring Criteria, Risks, and
Remediation)
- [Beginner's Guide to Scorecard Checks](#beginners-guide-to-scorecard-checks)

## Other Important Recommendations
- [Two-factor Authentication (2FA)](#two-factor-authentication-2fa)
Expand Down Expand Up @@ -94,14 +95,14 @@ metrics. Prominent projects that use Scorecard include:

### View a Project's Score

To see scores for projects regularly scanned by Scorecard, navigate to the webviewer, replacing the placeholder text with the platform, user/org, and repository name:
To see scores for projects regularly scanned by Scorecard, navigate to the webviewer, replacing the placeholder text with the platform, user/org, and repository name:
https://securityscorecards.dev/viewer/?uri=<github_or_gitlab>.com/<user_name_or_org>/<repository_name>.

For example:
For example:
- [https://securityscorecards.dev/viewer/?uri=github.com/ossf/scorecard](https://securityscorecards.dev/viewer/?uri=github.com/ossf/scorecard)
- [https://securityscorecards.dev/viewer/?uri=gitlab.com/fdroid/fdroidclient](https://securityscorecards.dev/viewer/?uri=gitlab.com/fdroid/fdroidclient)

To view scores for projects not included in the webviewer, use the [Scorecard CLI](#scorecard-command-line-interface).
To view scores for projects not included in the webviewer, use the [Scorecard CLI](#scorecard-command-line-interface).

### Public Data

Expand Down Expand Up @@ -506,6 +507,10 @@ Name | Description | Risk Level | Token Req
To see detailed information about each check, its scoring criteria, and
remediation steps, check out the [checks documentation page](docs/checks.md).

### Beginner's Guide to Scorecard Checks

For a guide to the checks you should use when getting started, see the [beginner's guide to scorecard checks](docs/beginner-checks.md).

## Other Important Recommendations

### Two-factor Authentication (2FA)
Expand Down Expand Up @@ -593,13 +598,13 @@ To report a security issue, please follow instructions [here](SECURITY.md).

### Join the Scorecards Project Meeting

#### Zoom
#### Zoom

We meet every other Thursday - 4p ET on this [zoom link](https://zoom.us/j/98835923979?pwd=RG5JZ3czZEtmRDlGdms0ZktmMFQvUT09).
We meet every other Thursday - 4p ET on this [zoom link](https://zoom.us/j/98835923979?pwd=RG5JZ3czZEtmRDlGdms0ZktmMFQvUT09).

#### Agenda

You can see the [agenda and meeting notes here](https://docs.google.com/document/d/1b6d3CVJLsl7YnTE7ZaZQHdkdYIvuOQ8rzAmvVdypOWM/edit?usp=sharing).
You can see the [agenda and meeting notes here](https://docs.google.com/document/d/1b6d3CVJLsl7YnTE7ZaZQHdkdYIvuOQ8rzAmvVdypOWM/edit?usp=sharing).


## Stargazers over time
Expand Down
16 changes: 12 additions & 4 deletions checks/cii_best_practices.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"github.com/ossf/scorecard/v4/checks/evaluation"
"github.com/ossf/scorecard/v4/checks/raw"
sce "github.com/ossf/scorecard/v4/errors"
"github.com/ossf/scorecard/v4/probes"
"github.com/ossf/scorecard/v4/probes/zrunner"
)

// CheckCIIBestPractices is the registered name for CIIBestPractices.
Expand All @@ -40,11 +42,17 @@ func CIIBestPractices(c *checker.CheckRequest) checker.CheckResult {
return checker.CreateRuntimeErrorResult(CheckCIIBestPractices, e)
}

// Return raw results.
if c.RawResults != nil {
c.RawResults.CIIBestPracticesResults = rawData
// Set the raw results.
pRawResults := getRawResults(c)
pRawResults.CIIBestPracticesResults = rawData

// Evaluate the probes.
findings, err := zrunner.Run(pRawResults, probes.CIIBestPractices)
if err != nil {
e := sce.WithMessage(sce.ErrScorecardInternal, err.Error())
return checker.CreateRuntimeErrorResult(CheckCIIBestPractices, e)
}

// Return the score evaluation.
return evaluation.CIIBestPractices(CheckCIIBestPractices, c.Dlogger, &rawData)
return evaluation.CIIBestPractices(CheckCIIBestPractices, findings, c.Dlogger)
}
75 changes: 48 additions & 27 deletions checks/evaluation/cii_best_practices.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@
package evaluation

import (
"fmt"

"github.com/ossf/scorecard/v4/checker"
"github.com/ossf/scorecard/v4/clients"
sce "github.com/ossf/scorecard/v4/errors"
"github.com/ossf/scorecard/v4/finding"
"github.com/ossf/scorecard/v4/probes/hasOpenSSFBadge"
)

// Note: exported for unit tests.
const (
silverScore = 7
// Note: if this value is changed, please update the action's threshold score
Expand All @@ -32,31 +30,54 @@ const (
)

// CIIBestPractices applies the score policy for the CIIBestPractices check.
func CIIBestPractices(name string, _ checker.DetailLogger, r *checker.CIIBestPracticesData) checker.CheckResult {
if r == nil {
e := sce.WithMessage(sce.ErrScorecardInternal, "empty raw data")
func CIIBestPractices(name string,
findings []finding.Finding, dl checker.DetailLogger,
) checker.CheckResult {
expectedProbes := []string{
hasOpenSSFBadge.Probe,
}

if !finding.UniqueProbesEqual(findings, expectedProbes) {
e := sce.WithMessage(sce.ErrScorecardInternal, "invalid probe results")
return checker.CreateRuntimeErrorResult(name, e)
}

var results checker.CheckResult
switch r.Badge {
case clients.NotFound:
results = checker.CreateMinScoreResult(name, "no effort to earn an OpenSSF best practices badge detected")
case clients.InProgress:
msg := fmt.Sprintf("badge detected: %v", r.Badge)
results = checker.CreateResultWithScore(name, msg, inProgressScore)
case clients.Passing:
msg := fmt.Sprintf("badge detected: %v", r.Badge)
results = checker.CreateResultWithScore(name, msg, passingScore)
case clients.Silver:
msg := fmt.Sprintf("badge detected: %v", r.Badge)
results = checker.CreateResultWithScore(name, msg, silverScore)
case clients.Gold:
msg := fmt.Sprintf("badge detected: %v", r.Badge)
results = checker.CreateMaxScoreResult(name, msg)
case clients.Unknown:
e := sce.WithMessage(sce.ErrScorecardInternal, fmt.Sprintf("unsupported badge: %v", r.Badge))
results = checker.CreateRuntimeErrorResult(name, e)
var score int
var text string

if len(findings) != 1 {
errText := "invalid probe results: multiple findings detected"
e := sce.WithMessage(sce.ErrScorecardInternal, errText)
return checker.CreateRuntimeErrorResult(name, e)
}
return results

f := &findings[0]
if f.Outcome == finding.OutcomeNegative {
text = "no effort to earn an OpenSSF best practices badge detected"
return checker.CreateMinScoreResult(name, text)
}
//nolint:nestif
if _, hasKey := f.Values[hasOpenSSFBadge.GoldLevel]; hasKey {
score = checker.MaxResultScore
text = "badge detected: Gold"
} else if _, hasKey := f.Values[hasOpenSSFBadge.SilverLevel]; hasKey {
score = silverScore
text = "badge detected: Silver"
} else if _, hasKey := f.Values[hasOpenSSFBadge.PassingLevel]; hasKey {
score = passingScore
text = "badge detected: Passing"
} else if _, hasKey := f.Values[hasOpenSSFBadge.InProgressLevel]; hasKey {
score = inProgressScore
text = "badge detected: InProgress"
} else if _, hasKey := f.Values[hasOpenSSFBadge.UnknownLevel]; hasKey {
text = "unknown badge detected"
e := sce.WithMessage(sce.ErrScorecardInternal, text)
return checker.CreateRuntimeErrorResult(name, e)
} else {
text = "unsupported badge detected"
e := sce.WithMessage(sce.ErrScorecardInternal, text)
return checker.CreateRuntimeErrorResult(name, e)
}

return checker.CreateResultWithScore(name, text, score)
}
189 changes: 127 additions & 62 deletions checks/evaluation/cii_best_practices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,71 +16,136 @@ package evaluation
import (
"testing"

"github.com/ossf/scorecard/v4/checker"
"github.com/ossf/scorecard/v4/clients"
sce "github.com/ossf/scorecard/v4/errors"
"github.com/ossf/scorecard/v4/finding"
"github.com/ossf/scorecard/v4/probes/hasOpenSSFBadge"
scut "github.com/ossf/scorecard/v4/utests"
)

func TestCIIBestPractices(t *testing.T) {
t.Run("CIIBestPractices", func(t *testing.T) {
t.Run("in progress", func(t *testing.T) {
r := &checker.CIIBestPracticesData{
Badge: clients.InProgress,
}
result := CIIBestPractices("CIIBestPractices", nil, r)
if result.Score != inProgressScore {
t.Errorf("CIIBestPractices() = %v, want %v", result.Score, inProgressScore)
}
})
t.Run("passing", func(t *testing.T) {
r := &checker.CIIBestPracticesData{
Badge: clients.Passing,
}
result := CIIBestPractices("CIIBestPractices", nil, r)
if result.Score != passingScore {
t.Errorf("CIIBestPractices() = %v, want %v", result.Score, passingScore)
}
})
t.Run("silver", func(t *testing.T) {
r := &checker.CIIBestPracticesData{
Badge: clients.Silver,
}
result := CIIBestPractices("CIIBestPractices", nil, r)
if result.Score != silverScore {
t.Errorf("CIIBestPractices() = %v, want %v", result.Score, silverScore)
}
})
t.Run("gold", func(t *testing.T) {
r := &checker.CIIBestPracticesData{
Badge: clients.Gold,
}
result := CIIBestPractices("CIIBestPractices", nil, r)
if result.Score != checker.MaxResultScore {
t.Errorf("CIIBestPractices() = %v, want %v", result.Score, checker.MaxResultScore)
}
})
t.Run("not found", func(t *testing.T) {
r := &checker.CIIBestPracticesData{
Badge: clients.NotFound,
}
result := CIIBestPractices("CIIBestPractices", nil, r)
if result.Score != checker.MinResultScore {
t.Errorf("CIIBestPractices() = %v, want %v", result.Score, checker.MinResultScore)
}
})
t.Run("error", func(t *testing.T) {
r := &checker.CIIBestPracticesData{
Badge: clients.Unknown,
}
result := CIIBestPractices("CIIBestPractices", nil, r)
if result.Score != -1 {
t.Errorf("CIIBestPractices() = %v, want %v", result.Score, -1)
}
})
t.Run("nil response", func(t *testing.T) {
result := CIIBestPractices("CIIBestPractices", nil, nil)
if result.Score != -1 {
t.Errorf("CIIBestPractices() = %v, want %v", result.Score, -1)
t.Parallel()
tests := []struct {
name string
findings []finding.Finding
result scut.TestReturn
}{
{
name: "Unsupported badge found with negative finding",
findings: []finding.Finding{
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomeNegative,
Values: map[string]int{
"Unsupported": 1,
},
},
},
result: scut.TestReturn{
Score: 0,
},
},
{
name: "Unsupported badge found with positive finding",
findings: []finding.Finding{
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
"Unsupported": 1,
},
},
},
result: scut.TestReturn{
Score: -1,
Error: sce.ErrScorecardInternal,
},
},
{
name: "Has InProgress Badge",
findings: []finding.Finding{
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
hasOpenSSFBadge.InProgressLevel: 1,
},
},
},
result: scut.TestReturn{
Score: 2,
},
},
{
name: "Has Passing Badge",
findings: []finding.Finding{
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
hasOpenSSFBadge.PassingLevel: 1,
},
},
},
result: scut.TestReturn{
Score: 5,
},
},
{
name: "Has Silver Badge",
findings: []finding.Finding{
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
hasOpenSSFBadge.SilverLevel: 1,
},
},
},
result: scut.TestReturn{
Score: 7,
},
},
{
name: "Has Gold Badge",
findings: []finding.Finding{
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
hasOpenSSFBadge.GoldLevel: 1,
},
},
},
result: scut.TestReturn{
Score: 10,
},
},
{
name: "Has Unknown Badge",
findings: []finding.Finding{
{
Probe: "hasOpenSSFBadge",
Outcome: finding.OutcomePositive,
Values: map[string]int{
"Unknown": 1,
},
},
},
result: scut.TestReturn{
Score: -1,
Error: sce.ErrScorecardInternal,
},
},
}
for _, tt := range tests {
tt := tt // Parallel testing
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
dl := scut.TestDetailLogger{}
got := CIIBestPractices(tt.name, tt.findings, &dl)
if !scut.ValidateTestReturn(t, tt.name, &tt.result, &got, &dl) {
t.Errorf("got %v, expected %v", got, tt.result)
}
})
})
}
}
Loading

0 comments on commit c849068

Please sign in to comment.