Skip to content

Commit 9840ba5

Browse files
authored
Support slugs and defaults in prov subcommand (#225)
* Fix panic when commit string is blank Signed-off-by: Adolfo Garcia Veytia (puerco) <[email protected]> * provenance support slugs, defaults Signed-off-by: Adolfo Garcia Veytia (puerco) <[email protected]> * Use actual sha1 stringz in tests Signed-off-by: Adolfo Garcia Veytia (puerco) <[email protected]> --------- Signed-off-by: Adolfo Garcia Veytia (puerco) <[email protected]>
1 parent c17c1c1 commit 9840ba5

File tree

6 files changed

+46
-17
lines changed

6 files changed

+46
-17
lines changed

sourcetool/internal/cmd/prov.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,36 @@ func (po *provOptions) AddFlags(cmd *cobra.Command) {
3636
cmd.PersistentFlags().StringVar(&po.prevCommit, "prev_commit", "", "The commit prior to 'commit'.")
3737
}
3838

39-
// provCmd represents the prov command
39+
//nolint:dupl
4040
func addProv(parentCmd *cobra.Command) {
4141
opts := provOptions{}
4242
provCmd := &cobra.Command{
4343
Use: "prov",
4444
Short: "Creates provenance for the given commit, but does not check policy.",
45+
PreRunE: func(cmd *cobra.Command, args []string) error {
46+
if len(args) > 0 {
47+
if err := opts.ParseLocator(args[0]); err != nil {
48+
return err
49+
}
50+
}
51+
52+
// Validate the repo opts here to provide a useful error
53+
// when checking defaults
54+
if err := opts.repoOptions.Validate(); err != nil {
55+
return err
56+
}
57+
58+
// Ensure we operate on the latest commit and the default
59+
// branch if not spcified
60+
if err := opts.EnsureDefaults(); err != nil {
61+
return err
62+
}
63+
return nil
64+
},
4565
RunE: func(cmd *cobra.Command, args []string) error {
66+
if err := opts.Validate(); err != nil {
67+
return fmt.Errorf("validating options: %w", err)
68+
}
4669
return doProv(&opts)
4770
},
4871
}

sourcetool/internal/cmd/verifycommit.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func (vco *verifyCommitOptions) AddFlags(cmd *cobra.Command) {
3636
)
3737
}
3838

39+
//nolint:dupl
3940
func addVerifyCommit(cmd *cobra.Command) {
4041
opts := verifyCommitOptions{}
4142
verifyCommitCmd := &cobra.Command{

sourcetool/pkg/attest/provenance_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/google/go-github/v69/github"
1010
"github.com/migueleliasweb/go-github-mock/src/mock"
11+
"github.com/stretchr/testify/require"
1112

1213
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/ghcontrol"
1314
"github.com/slsa-framework/slsa-source-poc/sourcetool/pkg/slsa"
@@ -40,9 +41,8 @@ func createTestProv(t *testing.T, repoUri, ref, commit string) string {
4041
}
4142

4243
statementBytes, err := json.Marshal(&stmt)
43-
if err != nil {
44-
t.Fatalf("failure marshalling statement: %v", err)
45-
}
44+
require.NoError(t, err, "failure marshalling statement: %v", err)
45+
4646
return string(statementBytes)
4747
}
4848

@@ -129,7 +129,7 @@ func assertTagProvPredsEqual(t *testing.T, actual, expected *TagProvenancePred)
129129
}
130130

131131
func TestReadProvSuccess(t *testing.T) {
132-
testProv := createTestProv(t, "https://github.com/owner/repo", "main", "abc123")
132+
testProv := createTestProv(t, "https://github.com/owner/repo", "main", "73f0a864c2c9af12e03dae433a6ff5f5e719d7aa")
133133
ghc := newTestGhConnection("owner", "repo", "branch",
134134
// We just need _some_ rulesets response, we don't care what.
135135
newTagHygieneRulesetsResponse(123, github.RulesetTargetTag,
@@ -138,7 +138,7 @@ func TestReadProvSuccess(t *testing.T) {
138138
verifier := testsupport.NewMockVerifier()
139139

140140
pa := NewProvenanceAttestor(ghc, verifier)
141-
readStmt, readPred, err := pa.GetProvenance(t.Context(), "abc123", "main")
141+
readStmt, readPred, err := pa.GetProvenance(t.Context(), "73f0a864c2c9af12e03dae433a6ff5f5e719d7aa", "main")
142142
if err != nil {
143143
t.Fatalf("error finding prov: %v", err)
144144
}
@@ -148,7 +148,7 @@ func TestReadProvSuccess(t *testing.T) {
148148
}
149149

150150
func TestReadProvFailure(t *testing.T) {
151-
testProv := createTestProv(t, "foo", "main", "abc123")
151+
testProv := createTestProv(t, "foo", "main", "73f0a864c2c9af12e03dae433a6ff5f5e719d7aa")
152152
ghc := newTestGhConnection("owner", "repo", "branch",
153153
// We just need _some_ rulesets response, we don't care what.
154154
newTagHygieneRulesetsResponse(456, github.RulesetTargetBranch,
@@ -157,7 +157,7 @@ func TestReadProvFailure(t *testing.T) {
157157
verifier := testsupport.NewMockVerifier()
158158

159159
pa := NewProvenanceAttestor(ghc, verifier)
160-
_, readPred, err := pa.GetProvenance(t.Context(), "abc123", "main")
160+
_, readPred, err := pa.GetProvenance(t.Context(), "73f0a864c2c9af12e03dae433a6ff5f5e719d7aa", "main")
161161
if err != nil {
162162
t.Fatalf("error finding prov: %v", err)
163163
}
@@ -167,7 +167,7 @@ func TestReadProvFailure(t *testing.T) {
167167
}
168168

169169
func TestCreateTagProvenance(t *testing.T) {
170-
testVsa := createTestVsa(t, "https://github.com/owner/repo", "refs/some/ref", "abc123", slsa.SourceVerifiedLevels{"TEST_LEVEL"})
170+
testVsa := createTestVsa(t, "https://github.com/owner/repo", "refs/some/ref", "73f0a864c2c9af12e03dae433a6ff5f5e719d7aa", slsa.SourceVerifiedLevels{"TEST_LEVEL"})
171171

172172
ghc := newTestGhConnection("owner", "repo", "branch",
173173
newTagHygieneRulesetsResponse(123, github.RulesetTargetTag,
@@ -177,7 +177,7 @@ func TestCreateTagProvenance(t *testing.T) {
177177

178178
pa := NewProvenanceAttestor(ghc, verifier)
179179

180-
stmt, err := pa.CreateTagProvenance(t.Context(), "abc123", "refs/tags/v1", "the-tag-pusher")
180+
stmt, err := pa.CreateTagProvenance(t.Context(), "73f0a864c2c9af12e03dae433a6ff5f5e719d7aa", "refs/tags/v1", "the-tag-pusher")
181181
if err != nil {
182182
t.Fatalf("error creating tag prov %v", err)
183183
}
@@ -190,8 +190,8 @@ func TestCreateTagProvenance(t *testing.T) {
190190
t.Errorf("statement pred type %v does not match expected %v", stmt.GetPredicateType(), TagProvPredicateType)
191191
}
192192

193-
if !DoesSubjectIncludeCommit(stmt, "abc123") {
194-
t.Errorf("statement subject %v does not match expected %v", stmt.GetSubject(), "abc123")
193+
if !DoesSubjectIncludeCommit(stmt, "73f0a864c2c9af12e03dae433a6ff5f5e719d7aa") {
194+
t.Errorf("statement subject %v does not match expected %v", stmt.GetSubject(), "73f0a864c2c9af12e03dae433a6ff5f5e719d7aa")
195195
}
196196

197197
tagPred, err := GetTagProvPred(stmt)

sourcetool/pkg/attest/vsa_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ func createTestVsaWithIdAndResult(t *testing.T, repoUri, ref, commit, id, result
3030
}
3131

3232
func TestReadVsaSuccess(t *testing.T) {
33-
testVsa := createTestVsa(t, "https://github.com/owner/repo", "refs/some/ref", "abc123", slsa.SourceVerifiedLevels{"TEST_LEVEL"})
33+
testVsa := createTestVsa(t, "https://github.com/owner/repo", "refs/some/ref", "de9395302d14b24c0a42685cf27315d93c88ff79", slsa.SourceVerifiedLevels{"TEST_LEVEL"})
3434
ghc := newTestGhConnection("owner", "repo", "branch",
3535
// We just need _some_ rulesets response, we don't care what.
3636
newTagHygieneRulesetsResponse(123, github.RulesetTargetTag,
3737
github.RulesetEnforcementActive, rulesetOldTime),
3838
newNotesContent(testVsa))
3939
verifier := testsupport.NewMockVerifier()
4040

41-
readStmt, readPred, err := GetVsa(t.Context(), ghc, verifier, "abc123", "refs/some/ref")
41+
readStmt, readPred, err := GetVsa(t.Context(), ghc, verifier, "de9395302d14b24c0a42685cf27315d93c88ff79", "refs/some/ref")
4242
if err != nil {
4343
t.Fatalf("error finding vsa: %v", err)
4444
}
@@ -54,7 +54,7 @@ func TestReadVsaSuccess(t *testing.T) {
5454
func TestReadVsaInvalidVsas(t *testing.T) {
5555
goodRepo := "https://github.com/org/foo"
5656
goodRef := "refs/heads/main"
57-
goodCommit := "abc123"
57+
goodCommit := "73f0a864c2c9af12e03dae433a6ff5f5e719d7aa"
5858

5959
// We want to make sure invalid VSAs aren't returned.
6060
tests := []struct {
@@ -91,7 +91,7 @@ func TestReadVsaInvalidVsas(t *testing.T) {
9191
newNotesContent(tt.vsa))
9292
verifier := testsupport.NewMockVerifier()
9393

94-
_, readPred, err := GetVsa(t.Context(), ghc, verifier, "abc123", "refs/heads/main")
94+
_, readPred, err := GetVsa(t.Context(), ghc, verifier, "73f0a864c2c9af12e03dae433a6ff5f5e719d7aa", "refs/heads/main")
9595
if err != nil {
9696
t.Fatalf("error finding vsa: %v", err)
9797
}

sourcetool/pkg/ghcontrol/notes.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ func (ghc *GitHubConnection) GetNotesForCommit(ctx context.Context, commit strin
1616
// They'll be in the path <co/mmit> within ref `refs/notes/commits`
1717
// where the first two characters of the commit sha are separated from the
1818
// rest with a slash, eg e5/73149ab3e574abc2e5a151a04acfaf2a59b453.
19+
if len(commit) != 40 {
20+
return "", fmt.Errorf("invalid commit string")
21+
}
22+
1923
path := commit[0:2] + "/" + commit[2:]
2024
contents, _, resp, err := ghc.Client().Repositories.GetContents(
2125
ctx, ghc.Owner(), ghc.Repo(), path, &github.RepositoryContentGetOptions{Ref: "refs/notes/commits"})

sourcetool/pkg/ghcontrol/notes_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ func TestGetNotesForCommit(t *testing.T) {
2323
mustErr bool
2424
}{
2525
{name: "success", owner: "slsa-framework", repo: "slsa-source-poc", commit: "e573149ab3e574abc2e5a151a04acfaf2a59b453", mustBeEmpty: false, mustErr: false},
26-
{name: "non-existent", owner: "kjsdhi373iuh", repo: "lksjdhfk3773", commit: "invalid", mustBeEmpty: true, mustErr: false},
26+
{name: "invalida-commit", owner: "kjsdhi373iuh", repo: "lksjdhfk3773", commit: "invalid", mustBeEmpty: true, mustErr: true},
27+
{name: "non-existent", owner: "kjsdhi373iuh", repo: "lksjdhfk3773", commit: "de9395302d14b24c0a42685cf27315d93c88ff79", mustBeEmpty: true, mustErr: false},
2728
} {
2829
t.Run(tc.name, func(t *testing.T) {
2930
t.Parallel()

0 commit comments

Comments
 (0)