Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
laurentsimon committed May 13, 2022
1 parent bd85657 commit e0785c7
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 141 deletions.
88 changes: 25 additions & 63 deletions checker/raw_result.go
Expand Up @@ -339,88 +339,50 @@ func PermissionLocationToString(l PermissionLocation) string {
}
}

// PermissionAlertType represents a permission type.
type PermissionAlertType int
// PermissionType represents a permission type.
type PermissionType int

const (
// PermissionAlertTypeUndeclared an undecleared permission.
PermissionAlertTypeUndeclared = iota
// PermissionAlertTypeWrite is a permission set to `write`.
PermissionAlertTypeWrite
// PermissionTypeUndefined an undecleared permission.
PermissionTypeUndefined = iota
// PermissionTypeWrite is a permission set to `write` for a permission we consider potentially dangerous.
PermissionTypeWrite
// PermissionTypeRead is a permission set to `read`.
PermissionTypeRead
// PermissionTypeNone is a permission set to `none`.
PermissionTypeNone
// PermissionTypeOther is for other kinds of alerts, mostly to support debug messages.
// TODO: remove it once we have implemented severity (#1874).
PermissionTypeOther
)

// PermissionAlertTypeToString stringifies a PermissionAlertType.
func PermissionAlertTypeToString(t PermissionAlertType) string {
// PermissionTypeToString stringifies a PermissionType.
func PermissionTypeToString(t PermissionType) string {
switch t {
case PermissionAlertTypeUndeclared:
return "undeclared"
case PermissionTypeUndefined:
return "undefined"

case PermissionAlertTypeWrite:
case PermissionTypeWrite:
return "write"
case PermissionTypeRead:
return "read"
case PermissionTypeNone:
return "none"

default:
return ""
return "unknown"
}
}

// TokenPermission defines a token permission alert.
//nolint
type TokenPermission struct {
Type PermissionType
Job *WorkflowJob
Remediation *Remediation
LocationType *PermissionLocation
AlertType *PermissionAlertType
Name *string
Value *string
File *File
Log Log
}

// LogLevel represents a log level.
// Note: may be removed once all checks are migrated.
type LogLevel int

const (
// LogLevelUnknown is unknown level.
// TODO: remove after migrating all checks.
LogLevelUnknown = iota
// LogLevelDebug is debug log.
LogLevelDebug
// LogLevelInfo is info log.
LogLevelInfo
// LogLevelWarn is warn log.
LogLevelWarn
)

// Log represent a log message.
type Log struct {
Msg string
Level LogLevel
}

// DetailToRawLog converts a CheckDetail to a raw log.
// Note: may be removed once all checks are migrated.
func DetailToRawLog(d *CheckDetail) Log {
switch d.Type {
case DetailDebug:
return Log{
Msg: d.Msg.Text,
Level: LogLevelDebug,
}
case DetailInfo:
return Log{
Msg: d.Msg.Text,
Level: LogLevelInfo,
}
case DetailWarn:
return Log{
Msg: d.Msg.Text,
Level: LogLevelWarn,
}
default:
return Log{
Msg: d.Msg.Text,
Level: LogLevelUnknown,
}
}
Msg *string
}
57 changes: 47 additions & 10 deletions checks/evaluation/permissions.go
Expand Up @@ -15,6 +15,8 @@
package evaluation

import (
"fmt"

"github.com/ossf/scorecard/v4/checker"
sce "github.com/ossf/scorecard/v4/errors"
)
Expand All @@ -26,7 +28,10 @@ func TokenPermissions(name string, dl checker.DetailLogger, r *checker.TokenPerm
return checker.CreateRuntimeErrorResult(name, e)
}

score, details := calculateScore(r)
score, err := calculateScore(r, dl)
if err != nil {
return checker.CreateRuntimeErrorResult(name, err)
}

if score != checker.MaxResultScore {
return checker.CreateResultWithScore(name,
Expand All @@ -37,7 +42,7 @@ func TokenPermissions(name string, dl checker.DetailLogger, r *checker.TokenPerm
"tokens are read-only in GitHub workflows")
}

func calculateScore(results *checker.TokenPermissionsData, dl checker.DetailLogger) int {
func calculateScore(results *checker.TokenPermissionsData, dl checker.DetailLogger) (int, error) {
// See list https://github.blog/changelog/2021-04-20-github-actions-control-permissions-for-github_token/.
// Note: there are legitimate reasons to use some of the permissions like checks, deployments, etc.
// in CI/CD systems https://docs.travis-ci.com/user/github-oauth-scopes/.
Expand All @@ -53,25 +58,57 @@ func calculateScore(results *checker.TokenPermissionsData, dl checker.DetailLogg
msg.Type = r.File.Type
msg.Snippet = r.File.Snippet
}
if r.Log.Msg != "" {
msg.Text = r.Log.Msg
text, err := createMessage(r)
if err != nil {
return checker.MinResultScore, err
}
msg.Text = text

switch r.Log.Level {
case checker.LogLevelDebug:
switch r.Type {
case checker.PermissionTypeOther:
dl.Debug(&msg)

case checker.LogLevelInfo:
case checker.PermissionTypeNone, checker.PermissionTypeRead:
dl.Info(&msg)

case checker.LogLevelWarn:

case checker.PermissionTypeWrite:
dl.Warn(&msg)
// TODO: construct a hash map indexed by workflow file.
}
}

// TODO: use the hash map to compute the score.
return 10
return int(score) - 1, nil
}

func createMessage(t checker.TokenPermission) (string, error) {
// By default, use the message already present.
if t.Msg != nil {
return *t.Msg, nil
}

// Ensure there's no implementation bug.
if t.LocationType == nil {
return "", sce.WithMessage(sce.ErrScorecardInternal, "locationType is nil")
}

// Use a different message depending on the type.
switch t.Type {
case checker.PermissionTypeUndefined:
return fmt.Sprintf("no %s permission defined",
checker.PermissionLocationToString(*t.LocationType)), nil

default:
if t.Name == nil || t.Value == nil {
return "", sce.WithMessage(sce.ErrScorecardInternal,
fmt.Sprintf("nil fields: %v, %v",
t.Name, t.Value))
}

return fmt.Sprintf("%s '%v' permission set to '%v'",
checker.PermissionLocationToString(*t.LocationType),
*t.Name, *t.Value), nil
}
}

/*
Expand Down

0 comments on commit e0785c7

Please sign in to comment.