Skip to content
Snippets Groups Projects
Unverified Commit 770e8bf1 authored by dlorenc's avatar dlorenc Committed by GitHub
Browse files

Refactor helm type to remove intermediate state. (#575)


This should be the actual last one :)

Signed-off-by: default avatarDan Lorenc <lorenc.d@gmail.com>
parent f86fc3eb
No related branches found
No related tags found
No related merge requests found
...@@ -33,7 +33,6 @@ import ( ...@@ -33,7 +33,6 @@ import (
"github.com/go-openapi/swag" "github.com/go-openapi/swag"
"github.com/sigstore/rekor/pkg/generated/models" "github.com/sigstore/rekor/pkg/generated/models"
"github.com/sigstore/rekor/pkg/log" "github.com/sigstore/rekor/pkg/log"
"github.com/sigstore/rekor/pkg/pki"
"github.com/sigstore/rekor/pkg/pki/pgp" "github.com/sigstore/rekor/pkg/pki/pgp"
"github.com/sigstore/rekor/pkg/types" "github.com/sigstore/rekor/pkg/types"
"github.com/sigstore/rekor/pkg/types/helm" "github.com/sigstore/rekor/pkg/types/helm"
...@@ -52,10 +51,7 @@ func init() { ...@@ -52,10 +51,7 @@ func init() {
} }
type V001Entry struct { type V001Entry struct {
HelmObj models.HelmV001Schema HelmObj models.HelmV001Schema
keyObj pki.PublicKey
sigObj pki.Signature
provenanceObj *helm.Provenance
} }
func (v V001Entry) APIVersion() string { func (v V001Entry) APIVersion() string {
...@@ -69,16 +65,26 @@ func NewEntry() types.EntryImpl { ...@@ -69,16 +65,26 @@ func NewEntry() types.EntryImpl {
func (v V001Entry) IndexKeys() ([]string, error) { func (v V001Entry) IndexKeys() ([]string, error) {
var result []string var result []string
key, err := v.keyObj.CanonicalValue() keyObj, err := pgp.NewPublicKey(bytes.NewReader(v.HelmObj.PublicKey.Content))
if err != nil {
return nil, err
}
provenance := helm.Provenance{}
if err := provenance.Unmarshal(bytes.NewReader(v.HelmObj.Chart.Provenance.Content)); err != nil {
return nil, err
}
key, err := keyObj.CanonicalValue()
if err != nil { if err != nil {
return nil, err return nil, err
} }
keyHash := sha256.Sum256(key) keyHash := sha256.Sum256(key)
result = append(result, strings.ToLower(hex.EncodeToString(keyHash[:]))) result = append(result, strings.ToLower(hex.EncodeToString(keyHash[:])))
result = append(result, v.keyObj.EmailAddresses()...) result = append(result, keyObj.EmailAddresses()...)
algorithm, chartHash, err := v.provenanceObj.GetChartAlgorithmHash() algorithm, chartHash, err := provenance.GetChartAlgorithmHash()
if err != nil { if err != nil {
log.Logger.Error(err) log.Logger.Error(err)
...@@ -121,11 +127,7 @@ func (v V001Entry) hasExternalEntities() bool { ...@@ -121,11 +127,7 @@ func (v V001Entry) hasExternalEntities() bool {
return false return false
} }
func (v *V001Entry) fetchExternalEntities(ctx context.Context) error { func (v *V001Entry) fetchExternalEntities(ctx context.Context) (*helm.Provenance, *pgp.PublicKey, *pgp.Signature, error) {
if err := v.validate(); err != nil {
return types.ValidationError(err)
}
g, ctx := errgroup.WithContext(ctx) g, ctx := errgroup.WithContext(ctx)
provenanceR, provenanceW := io.Pipe() provenanceR, provenanceW := io.Pipe()
...@@ -160,7 +162,7 @@ func (v *V001Entry) fetchExternalEntities(ctx context.Context) error { ...@@ -160,7 +162,7 @@ func (v *V001Entry) fetchExternalEntities(ctx context.Context) error {
} }
defer keyReadCloser.Close() defer keyReadCloser.Close()
v.keyObj, err = pgp.NewPublicKey(keyReadCloser) keyObj, err := pgp.NewPublicKey(keyReadCloser)
if err != nil { if err != nil {
return closePipesOnError(types.ValidationError(err)) return closePipesOnError(types.ValidationError(err))
} }
...@@ -168,25 +170,28 @@ func (v *V001Entry) fetchExternalEntities(ctx context.Context) error { ...@@ -168,25 +170,28 @@ func (v *V001Entry) fetchExternalEntities(ctx context.Context) error {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
case keyResult <- v.keyObj.(*pgp.PublicKey): case keyResult <- keyObj:
return nil return nil
} }
}) })
var key *pgp.PublicKey
provenance := &helm.Provenance{}
var sig *pgp.Signature
g.Go(func() error { g.Go(func() error {
provenance := helm.Provenance{}
if err := provenance.Unmarshal(provenanceR); err != nil { if err := provenance.Unmarshal(provenanceR); err != nil {
return closePipesOnError(types.ValidationError(err)) return closePipesOnError(types.ValidationError(err))
} }
key := <-keyResult key = <-keyResult
if key == nil { if key == nil {
return closePipesOnError(errors.New("error processing public key")) return closePipesOnError(errors.New("error processing public key"))
} }
// Set signature // Set signature
sig, err := pgp.NewSignature(provenance.Block.ArmoredSignature.Body) var err error
sig, err = pgp.NewSignature(provenance.Block.ArmoredSignature.Body)
if err != nil { if err != nil {
return closePipesOnError(types.ValidationError(err)) return closePipesOnError(types.ValidationError(err))
} }
...@@ -196,9 +201,6 @@ func (v *V001Entry) fetchExternalEntities(ctx context.Context) error { ...@@ -196,9 +201,6 @@ func (v *V001Entry) fetchExternalEntities(ctx context.Context) error {
return closePipesOnError(types.ValidationError(err)) return closePipesOnError(types.ValidationError(err))
} }
v.sigObj = sig
v.provenanceObj = &provenance
select { select {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
...@@ -208,27 +210,26 @@ func (v *V001Entry) fetchExternalEntities(ctx context.Context) error { ...@@ -208,27 +210,26 @@ func (v *V001Entry) fetchExternalEntities(ctx context.Context) error {
}) })
if err := g.Wait(); err != nil { if err := g.Wait(); err != nil {
return err return nil, nil, nil, err
} }
return nil return provenance, key, sig, nil
} }
func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) { func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) {
if err := v.fetchExternalEntities(ctx); err != nil { provenanceObj, keyObj, sigObj, err := v.fetchExternalEntities(ctx)
if err != nil {
return nil, err return nil, err
} }
if v.keyObj == nil { if keyObj == nil {
return nil, errors.New("key object not initialized before canonicalization") return nil, errors.New("key object not initialized before canonicalization")
} }
canonicalEntry := models.HelmV001Schema{} canonicalEntry := models.HelmV001Schema{}
var err error
canonicalEntry.PublicKey = &models.HelmV001SchemaPublicKey{} canonicalEntry.PublicKey = &models.HelmV001SchemaPublicKey{}
keyContent, err := v.keyObj.CanonicalValue() keyContent, err := keyObj.CanonicalValue()
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -237,7 +238,7 @@ func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) { ...@@ -237,7 +238,7 @@ func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) {
canonicalEntry.Chart = &models.HelmV001SchemaChart{} canonicalEntry.Chart = &models.HelmV001SchemaChart{}
algorithm, chartHash, err := v.provenanceObj.GetChartAlgorithmHash() algorithm, chartHash, err := provenanceObj.GetChartAlgorithmHash()
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -250,7 +251,7 @@ func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) { ...@@ -250,7 +251,7 @@ func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) {
canonicalEntry.Chart.Provenance = &models.HelmV001SchemaChartProvenance{} canonicalEntry.Chart.Provenance = &models.HelmV001SchemaChartProvenance{}
canonicalEntry.Chart.Provenance.Signature = &models.HelmV001SchemaChartProvenanceSignature{} canonicalEntry.Chart.Provenance.Signature = &models.HelmV001SchemaChartProvenanceSignature{}
sigContent, err := v.sigObj.CanonicalValue() sigContent, err := sigObj.CanonicalValue()
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -350,7 +351,7 @@ func (v V001Entry) CreateFromArtifactProperties(ctx context.Context, props types ...@@ -350,7 +351,7 @@ func (v V001Entry) CreateFromArtifactProperties(ctx context.Context, props types
} }
if re.hasExternalEntities() { if re.hasExternalEntities() {
if err := re.fetchExternalEntities(ctx); err != nil { if _, _, _, err := re.fetchExternalEntities(ctx); err != nil {
return nil, fmt.Errorf("error retrieving external entities: %v", err) return nil, fmt.Errorf("error retrieving external entities: %v", err)
} }
} }
......
...@@ -218,50 +218,50 @@ func TestCrossFieldValidation(t *testing.T) { ...@@ -218,50 +218,50 @@ func TestCrossFieldValidation(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
if err := tc.entry.validate(); (err == nil) != tc.expectUnmarshalSuccess { t.Run(tc.caseDesc, func(t *testing.T) {
t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err)
}
v := &V001Entry{} if err := tc.entry.validate(); (err == nil) != tc.expectUnmarshalSuccess {
r := models.Helm{ t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err)
APIVersion: swag.String(tc.entry.APIVersion()),
Spec: tc.entry.HelmObj,
}
unmarshalAndValidate := func() error {
if err := v.Unmarshal(&r); err != nil {
return err
} }
if err := v.validate(); err != nil {
return err v := &V001Entry{}
r := models.Helm{
APIVersion: swag.String(tc.entry.APIVersion()),
Spec: tc.entry.HelmObj,
} }
return nil
}
if err := unmarshalAndValidate(); (err == nil) != tc.expectUnmarshalSuccess { if err := v.Unmarshal(&r); (err == nil) != tc.expectUnmarshalSuccess {
t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err) t.Errorf("unexpected result in '%v': %v", tc.caseDesc, err)
} }
if tc.entry.hasExternalEntities() != tc.hasExtEntities { if !tc.expectUnmarshalSuccess {
t.Errorf("unexpected result from HasExternalEntities for '%v'", tc.caseDesc) return
} }
if err := v.validate(); err != nil {
return
}
b, err := v.Canonicalize(context.TODO()) if tc.entry.hasExternalEntities() != tc.hasExtEntities {
if (err == nil) != tc.expectCanonicalizeSuccess { t.Errorf("unexpected result from HasExternalEntities for '%v'", tc.caseDesc)
t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err)
} else if err != nil {
if _, ok := err.(types.ValidationError); !ok {
t.Errorf("canonicalize returned an unexpected error that isn't of type types.ValidationError: %v", err)
} }
}
if b != nil { b, err := v.Canonicalize(context.TODO())
pe, err := models.UnmarshalProposedEntry(bytes.NewReader(b), runtime.JSONConsumer()) if (err == nil) != tc.expectCanonicalizeSuccess {
if err != nil { t.Errorf("unexpected result from Canonicalize for '%v': %v", tc.caseDesc, err)
t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tc.caseDesc, err) } else if err != nil {
if _, ok := err.(types.ValidationError); !ok {
t.Errorf("canonicalize returned an unexpected error that isn't of type types.ValidationError: %v", err)
}
} }
if _, err := types.NewEntry(pe); err != nil { if b != nil {
t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tc.caseDesc, err) pe, err := models.UnmarshalProposedEntry(bytes.NewReader(b), runtime.JSONConsumer())
if err != nil {
t.Errorf("unexpected err from Unmarshalling canonicalized entry for '%v': %v", tc.caseDesc, err)
}
if _, err := types.NewEntry(pe); err != nil {
t.Errorf("unexpected err from type-specific unmarshalling for '%v': %v", tc.caseDesc, err)
}
} }
} })
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment