Skip to content

Commit

Permalink
Merge branch 'main' into feature/support-allowlists
Browse files Browse the repository at this point in the history
Signed-off-by: Christopher Angelo Phillips <[email protected]>
  • Loading branch information
spiffcs authored Oct 3, 2024
2 parents 1bc700a + 7a8dc6b commit 629ab9d
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 17 deletions.
4 changes: 2 additions & 2 deletions .binny.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ tools:

- name: goreleaser
version:
want: v1.25.1
want: v2.3.2
method: github-release
with:
repo: goreleaser/goreleaser

- name: golangci-lint
version:
want: v1.54.2
want: v1.61.0
method: github-release
with:
repo: golangci/golangci-lint
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/bootstrap/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ inputs:
go-version:
description: "Go version to install"
required: true
default: "1.22.x"
default: "1.23.x"
cache-key-prefix:
description: "Prefix all cache keys with this value"
required: true
Expand Down
3 changes: 1 addition & 2 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ linters:
- dogsled
- dupl
- errcheck
- exportloopref
- funlen
- gocognit
- goconst
Expand Down Expand Up @@ -79,4 +78,4 @@ run:
# - structcheck # The owner seems to have abandoned the linter. Replaced by "unused".
# - testpackage
# - varcheck # The owner seems to have abandoned the linter. Replaced by "unused".
# - wsl # this doens't have an auto-fixer yet and is pretty noisy (https://github.com/bombsimon/wsl/issues/90)
# - wsl # this doens't have an auto-fixer yet and is pretty noisy (https://github.com/bombsimon/wsl/issues/90)
6 changes: 5 additions & 1 deletion .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=jcroql
version: 2

release:
prerelease: auto
draft: false
Expand Down Expand Up @@ -60,7 +64,7 @@ nfpms:
- deb

brews:
- tap:
- repository:
owner: anchore
name: homebrew-grant
token: "{{.Env.HOMEBREW_TOKEN}}"
Expand Down
4 changes: 2 additions & 2 deletions cmd/grant/cli/command/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ func Check(app clio.Application) *cobra.Command {
Use: "check",
Short: "Verify licenses in the SBOM conform to the configured policy",
Args: cobra.ArbitraryArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
PreRunE: func(_ *cobra.Command, args []string) error {
userInputs = args
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(_ *cobra.Command, _ []string) error {
return runCheck(cfg, userInputs)
},
}, cfg)
Expand Down
4 changes: 2 additions & 2 deletions cmd/grant/cli/command/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ func List(app clio.Application) *cobra.Command {
Use: "list",
Short: "List the licenses detected in the given OCI image, sbom, or directory/file",
Args: cobra.ArbitraryArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
PreRunE: func(_ *cobra.Command, args []string) error {
userInputs = args
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(_ *cobra.Command, _ []string) error {
return runList(cfg, userInputs)
},
}, cfg)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
module github.com/anchore/grant

go 1.22.4
go 1.23.2

require (
github.com/anchore/bubbly v0.0.0-20231115205105-6542675d79fe
github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a
github.com/anchore/go-logger v0.0.0-20240925152809-a16bcaef4ee4
github.com/anchore/stereoscope v0.0.3
github.com/anchore/syft v1.13.0
github.com/charmbracelet/bubbletea v1.1.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d h1:ZD4wdCBgJJzJybjTU
github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d/go.mod h1:Xh4ObY3fmoMzOEVXwDtS1uK44JC7+nRD0n29/1KYFYg=
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537 h1:GjNGuwK5jWjJMyVppBjYS54eOiiSNv4Ba869k4wh72Q=
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537/go.mod h1:1aiktV46ATCkuVg0O573ZrH56BUawTECPETbZyBcqT8=
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a h1:nJ2G8zWKASyVClGVgG7sfM5mwoZlZ2zYpIzN2OhjWkw=
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a/go.mod h1:ubLFmlsv8/DFUQrZwY5syT5/8Er3ugSr4rDFwHsE3hg=
github.com/anchore/go-logger v0.0.0-20240925152809-a16bcaef4ee4 h1:wu6JP0Uiw4cgOJu6MwinMjEK8OV8Uf/nZgG6Xu/Ue9w=
github.com/anchore/go-logger v0.0.0-20240925152809-a16bcaef4ee4/go.mod h1:CyK090ySIgB8Y29so1Mhqh3T/apkpL6kUsfY/c+GmfM=
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb h1:iDMnx6LIjtjZ46C0akqveX83WFzhpTD3eqOthawb5vU=
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb/go.mod h1:DmTY2Mfcv38hsHbG78xMiTDdxFtkHpgYNVDPsF2TgHk=
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc=
Expand Down
12 changes: 9 additions & 3 deletions grant/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
)

// Policy is a structure of rules that define how licenses are denied
// TODO: maybe there should be a strict option that denies all and then only allows what is explicitly allowed
type Policy struct {
Rules Rules
MatchNonSPDX bool
Expand Down Expand Up @@ -60,10 +59,17 @@ func (p Policy) IsDenied(license License, pkg *Package) (bool, *Rule) {
}

toMatch = strings.ToLower(toMatch)
// TODO: write tests for this section
// If there is a match and the content to match is not an empty string
if rule.Glob.Match(toMatch) && toMatch != "" {
var returnVal bool
// set the return value based on the rule mode
if rule.Mode == Allow {
returnVal = false
} else {
returnVal = true
}
if pkg == nil {
return true, &rule
return returnVal, &rule
}
for _, exception := range rule.Exceptions {
if exception.Match(pkg.Name) {
Expand Down
136 changes: 136 additions & 0 deletions grant/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,139 @@ func Test_Policy_IsDenied(t *testing.T) {
})
}
}

func Test_Policy_Exceptions(t *testing.T) {
tests := []struct {
name string
p Policy
want struct {
denied bool
rule *Rule
}
}{
{
name: "Policy Default Deny All denies all licenses",
p: Policy{
Rules: Rules{Rule{
Name: "default-deny-all",
Glob: glob.MustCompile("*"),
Exceptions: []glob.Glob{glob.MustCompile("MIT")},
Mode: Deny,
Reason: "grant by default will deny all licenses",
}},
MatchNonSPDX: false,
},
want: struct {
denied bool
rule *Rule
}{
denied: false,
rule: &Rule{
Name: "default-deny-all",
Glob: glob.MustCompile("*"),
Exceptions: []glob.Glob{glob.MustCompile("MIT")},
Mode: Deny,
Reason: "grant by default will deny all licenses",
},
},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
denied, rule := tc.p.IsDenied(License{LicenseID: "MIT", SPDXExpression: "MIT"}, &Package{ID: "MIT", Name: "MIT"})
if denied != tc.want.denied {
t.Errorf("Expected %t, got %t", tc.want.denied, denied)
}
if diff := cmp.Diff(tc.want.rule, rule); diff != "" {
t.Errorf("IsDenied() mismatch (-want +got):\n%s", diff)
}
})
}
}

func Test_Policy_Allow(t *testing.T) {
tests := []struct {
name string
p Policy
want struct {
denied bool
rule *Rule
}
}{
{
name: "Policy Allow MIT",
p: Policy{
Rules: Rules{Rule{
Name: "allow MIT",
Glob: glob.MustCompile("mit"),
Exceptions: []glob.Glob{},
Mode: Allow,
Reason: "grant allow MIT",
}, Rule{
Name: "deny gpl",
Glob: glob.MustCompile("gpl"),
Exceptions: []glob.Glob{},
Mode: Deny,
Reason: "grant deny gpl",
}},
MatchNonSPDX: false,
},
want: struct {
denied bool
rule *Rule
}{
denied: false,
rule: &Rule{
Name: "allow MIT",
Glob: glob.MustCompile("mit"),
Exceptions: []glob.Glob{},
Mode: Allow,
Reason: "grant allow MIT",
},
},
},
{
name: "Policy Deny MIT",
p: Policy{
Rules: Rules{Rule{
Name: "deny MIT",
Glob: glob.MustCompile("mit"),
Exceptions: []glob.Glob{},
Mode: Deny,
Reason: "grant deny MIT",
}, Rule{
Name: "allow gpl",
Glob: glob.MustCompile("gpl"),
Exceptions: []glob.Glob{},
Mode: Allow,
Reason: "grant allow gpl",
}},
MatchNonSPDX: false,
},
want: struct {
denied bool
rule *Rule
}{
denied: true,
rule: &Rule{
Name: "deny MIT",
Glob: glob.MustCompile("mit"),
Exceptions: []glob.Glob{},
Mode: Deny,
Reason: "grant deny MIT",
},
},
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
denied, rule := tc.p.IsDenied(License{LicenseID: "MIT", SPDXExpression: "MIT"}, nil)
if denied != tc.want.denied {
t.Errorf("Expected %t, got %t", tc.want.denied, denied)
}
if diff := cmp.Diff(tc.want.rule, rule); diff != "" {
t.Errorf("IsDenied() mismatch (-want +got):\n%s", diff)
}
})
}
}

0 comments on commit 629ab9d

Please sign in to comment.