Skip to content

Commit

Permalink
Changes to create new evidence
Browse files Browse the repository at this point in the history
  • Loading branch information
davidlesfrog committed May 30, 2024
1 parent 6a04384 commit b87efc9
Show file tree
Hide file tree
Showing 17 changed files with 197 additions and 419 deletions.
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
SHELL := /bin/bash

.DEFAULT_GOAL = build

GOCMD = go
GOOS = $(shell go env GOOS)
GOARCH = $(shell go env GOARCH)

utest:
$(GOCMD) list ./... | grep "evidence" | grep -v "/${MODULE_NAME}/service/test" | xargs $(GOCMD) test $(TEST_TAGS) -timeout=1m -count=1 $(TEST_ARGS)

test: utest
60 changes: 9 additions & 51 deletions evidence/cli/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ package cli
import (
"errors"
"github.com/jfrog/jfrog-cli-artifactory/evidence"
"github.com/jfrog/jfrog-cli-artifactory/evidence/cli/docs/attest"
"github.com/jfrog/jfrog-cli-artifactory/evidence/cli/docs/verify"
"github.com/jfrog/jfrog-cli-artifactory/evidence/cli/docs/create"
commonCliUtils "github.com/jfrog/jfrog-cli-core/v2/common/cliutils"
"github.com/jfrog/jfrog-cli-core/v2/common/commands"
pluginsCommon "github.com/jfrog/jfrog-cli-core/v2/plugins/common"
Expand All @@ -18,26 +17,18 @@ func GetCommands() []components.Command {
return []components.Command{
{
Name: "create-evidence",
Aliases: []string{"attest", "att"},
Aliases: []string{"create"},
Flags: GetCommandFlags(CreateEvidence),
Description: attest.GetDescription(),
Arguments: attest.GetArguments(),
Description: create.GetDescription(),
Arguments: create.GetArguments(),
Action: createEvidence,
},
{
Name: "verify-evidence",
Aliases: []string{"verify", "v"},
Flags: GetCommandFlags(VerifyEvidence),
Description: verify.GetDescription(),
Arguments: verify.GetArguments(),
Action: verifyEvidence,
},
}
}

func platformToEvidenceUrls(rtDetails *coreConfig.ServerDetails) {
rtDetails.ArtifactoryUrl = utils.AddTrailingSlashIfNeeded(rtDetails.Url) + "artifactory/"
rtDetails.LifecycleUrl = utils.AddTrailingSlashIfNeeded(rtDetails.Url) + "lifecycle/"
rtDetails.EvidenceUrl = utils.AddTrailingSlashIfNeeded(rtDetails.Url) + "evidence/"
}

func createEvidence(c *components.Context) error {
Expand All @@ -54,45 +45,12 @@ func createEvidence(c *components.Context) error {
SetServerDetails(artifactoryClient).
SetPredicateFilePath(c.GetStringFlagValue(EvdPredicate)).
SetPredicateType(c.GetStringFlagValue(EvdPredicateType)).
SetSubjects(c.GetStringFlagValue(EvdSubjects)).
SetSubject(c.GetStringFlagValue(EvdSubject)).
SetKey(c.GetStringFlagValue(EvdKey)).
SetKeyId(c.GetStringFlagValue(EvdKeyId)).
SetEvidenceName(c.GetStringFlagValue(EvdName)).
SetOverride(c.GetBoolFlagValue(EvdOverride))
SetKeyId(c.GetStringFlagValue(EvdKeyId))
return commands.Exec(createCmd)
}

func verifyEvidence(c *components.Context) error {
if err := validateVerifyEvidenceContext(c); err != nil {
return err
}

artifactoryClient, err := evidenceDetailsByFlags(c)
if err != nil {
return err
}

verifyCmd := evidence.NewEvidenceVerifyCommand().
SetServerDetails(artifactoryClient).
SetKey(c.GetStringFlagValue(EvdKey)).
SetEvidenceName(c.GetStringFlagValue(EvdName))
return commands.Exec(verifyCmd)
}

func validateVerifyEvidenceContext(c *components.Context) error {
if show, err := pluginsCommon.ShowCmdHelpIfNeeded(c, c.Arguments); show || err != nil {
return err
}
if !c.IsFlagSet(EvdKey) || assertValueProvided(c, EvdKey) != nil {
return errorutils.CheckErrorf("'key' is a mandatory field for creating a custom evidence: --%s", EvdKey)
}
if !c.IsFlagSet(EvdName) || assertValueProvided(c, EvdName) != nil {
return errorutils.CheckErrorf("'key' is a mandatory field for creating a custom evidence: --%s", EvdName)
}

return nil
}

func evidenceDetailsByFlags(c *components.Context) (*coreConfig.ServerDetails, error) {
artifactoryClient, err := pluginsCommon.CreateServerDetailsWithConfigOffer(c, true, commonCliUtils.Platform)
if err != nil {
Expand Down Expand Up @@ -120,8 +78,8 @@ func validateCreateEvidenceContext(c *components.Context) error {
if !c.IsFlagSet(EvdPredicateType) || assertValueProvided(c, EvdPredicateType) != nil {
return errorutils.CheckErrorf("'predicate' is a mandatory field for creating a custom evidence: --%s", EvdPredicateType)
}
if !c.IsFlagSet(EvdSubjects) || assertValueProvided(c, EvdSubjects) != nil {
return errorutils.CheckErrorf("'subjects' is a mandatory field for creating a custom evidence: --%s", EvdSubjects)
if !c.IsFlagSet(EvdSubject) || assertValueProvided(c, EvdSubject) != nil {
return errorutils.CheckErrorf("'subjects' is a mandatory field for creating a custom evidence: --%s", EvdSubject)
}
if !c.IsFlagSet(EvdKey) || assertValueProvided(c, EvdKey) != nil {
return errorutils.CheckErrorf("'key' is a mandatory field for creating a custom evidence: --%s", EvdKey)
Expand Down
11 changes: 0 additions & 11 deletions evidence/cli/docs/attest/help.go

This file was deleted.

17 changes: 17 additions & 0 deletions evidence/cli/docs/create/help.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package create

import "github.com/jfrog/jfrog-cli-core/v2/plugins/components"

func GetDescription() string {
return "Create a custom evidence and save it to a repository. Add a predicate, predicate-type, subject, key, and key-name."
}

func GetArguments() []components.Argument {
return []components.Argument{
{Name: "predicate", Optional: false, Description: "Path to the predicate, arbitrary JSON."},
{Name: "predicate-type", Optional: false, Description: "Type of the predicate."},
{Name: "subject", Optional: false, Description: "Full path to some subjects' location, an artifact."},
{Name: "key", Optional: false, Description: "Path to a private key that will sign the DSSE. Supported keys: 'ecdsa','rsa' and 'ed25519'."},
{Name: "key-name", Optional: true, Description: "Keyid."},
}
}
11 changes: 0 additions & 11 deletions evidence/cli/docs/verify/help.go

This file was deleted.

36 changes: 14 additions & 22 deletions evidence/cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
const (
// Evidence commands keys
CreateEvidence = "create-evidence"
VerifyEvidence = "verify"
)

const (
Expand All @@ -23,37 +22,30 @@ const (
evidencePrefix = "evd-"
EvdPredicate = "predicate"
EvdPredicateType = "predicate-type"
EvdSubjects = "subjects"
EvdSubject = "subject"
EvdKey = "key"
EvdKeyId = "key-name"
EvdName = "name"
EvdOverride = "override"
)

// Security Flag keys mapped to their corresponding components.Flag definition.
// Flag keys mapped to their corresponding components.Flag definition.
var flagsMap = map[string]components.Flag{
// Common commands flags
ServerId: components.NewStringFlag(ServerId, "Server ID configured using the config command."),
url: components.NewStringFlag(url, "JFrog Platform URL."),
user: components.NewStringFlag(user, "JFrog username."),
password: components.NewStringFlag(password, "JFrog password."),
accessToken: components.NewStringFlag(accessToken, "JFrog access token."),

EvdPredicate: components.NewStringFlag(EvdPredicate, "[Mandatory] Path for a file containing the predicate. The file should contain a valid JSON predicate."),
EvdPredicateType: components.NewStringFlag(EvdPredicateType, "[Mandatory] The type of the predicate."),
EvdSubjects: components.NewStringFlag(EvdSubjects, "[Mandatory] Path for a file containing the subject."),
EvdKey: components.NewStringFlag(EvdKey, "[Mandatory] Path for a key pair (pk, puk)."),
EvdKeyId: components.NewStringFlag(EvdKeyId, "[Optional] KeyId"),
EvdName: components.NewStringFlag(EvdName, "[Optional] The name of the evidence to be created."),
EvdOverride: components.NewBoolFlag(EvdOverride, "[Default: false] Set to true to override evidence, if exists, in Artifactory."),
ServerId: components.NewStringFlag(ServerId, "Server ID configured using the config command.", func(f *components.StringFlag) { f.Mandatory = false }),
url: components.NewStringFlag(url, "JFrog Platform URL.", func(f *components.StringFlag) { f.Mandatory = false }),
user: components.NewStringFlag(user, "JFrog username.", func(f *components.StringFlag) { f.Mandatory = false }),
password: components.NewStringFlag(password, "JFrog password.", func(f *components.StringFlag) { f.Mandatory = false }),
accessToken: components.NewStringFlag(accessToken, "JFrog access token.", func(f *components.StringFlag) { f.Mandatory = false }),

EvdPredicate: components.NewStringFlag(EvdPredicate, "Path for a file containing the predicate. The file should contain a valid JSON predicate.", func(f *components.StringFlag) { f.Mandatory = true }),
EvdPredicateType: components.NewStringFlag(EvdPredicateType, "The type of the predicate.", func(f *components.StringFlag) { f.Mandatory = true }),
EvdSubject: components.NewStringFlag(EvdSubject, "Path for a file containing the subject.", func(f *components.StringFlag) { f.Mandatory = true }),
EvdKey: components.NewStringFlag(EvdKey, "Private key.", func(f *components.StringFlag) { f.Mandatory = true }),
EvdKeyId: components.NewStringFlag(EvdKeyId, "KeyId", func(f *components.StringFlag) { f.Mandatory = false }),
}

var commandFlags = map[string][]string{
CreateEvidence: {
url, user, password, accessToken, ServerId, EvdPredicate, EvdPredicateType, EvdSubjects, EvdKey, EvdKeyId, EvdName, EvdOverride,
},
VerifyEvidence: {
EvdKey, EvdName,
url, user, password, accessToken, ServerId, EvdPredicate, EvdPredicateType, EvdSubject, EvdKey, EvdKeyId,
},
}

Expand Down
102 changes: 19 additions & 83 deletions evidence/attest.go → evidence/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,21 @@ import (
"github.com/jfrog/jfrog-cli-artifactory/evidence/cryptox"
"github.com/jfrog/jfrog-cli-artifactory/evidence/dsse"
"github.com/jfrog/jfrog-cli-artifactory/evidence/intoto"
"github.com/jfrog/jfrog-client-go/artifactory"
"os"
"strings"

"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-client-go/artifactory/services"
rtServicesUtils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
evidenceService "github.com/jfrog/jfrog-client-go/evidence/services"
clientlog "github.com/jfrog/jfrog-client-go/utils/log"
"os"
"strings"
)

type EvidenceCreateCommand struct {
serverDetails *config.ServerDetails
predicateFilePath string
predicateType string
subjects string
subject string
key string
keyId string
evidenceName string
override bool
}

func NewEvidenceCreateCommand() *EvidenceCreateCommand {
Expand All @@ -48,8 +42,8 @@ func (ec *EvidenceCreateCommand) SetPredicateType(predicateType string) *Evidenc
return ec
}

func (ec *EvidenceCreateCommand) SetSubjects(subjects string) *EvidenceCreateCommand {
ec.subjects = subjects
func (ec *EvidenceCreateCommand) SetSubject(subject string) *EvidenceCreateCommand {
ec.subject = subject
return ec
}

Expand All @@ -63,16 +57,6 @@ func (ec *EvidenceCreateCommand) SetKeyId(keyId string) *EvidenceCreateCommand {
return ec
}

func (ec *EvidenceCreateCommand) SetEvidenceName(evidenceName string) *EvidenceCreateCommand {
ec.evidenceName = evidenceName
return ec
}

func (ec *EvidenceCreateCommand) SetOverride(override bool) *EvidenceCreateCommand {
ec.override = override
return ec
}

func (ec *EvidenceCreateCommand) CommandName() string {
return "create-evidence"
}
Expand All @@ -98,8 +82,9 @@ func (ec *EvidenceCreateCommand) Run() error {
return err
}

intotoStatement := intoto.NewStatement(predicate, ec.predicateType)
err = intotoStatement.SetSubject(servicesManager, ec.subjects)
// Create intoto statement
intotoStatement := intoto.NewStatement(predicate, ec.predicateType, ec.serverDetails.User)
err = intotoStatement.SetSubject(servicesManager, ec.subject)
if err != nil {
return err
}
Expand All @@ -118,10 +103,8 @@ func (ec *EvidenceCreateCommand) Run() error {
if err != nil {
return err
}
// If keyId is provided, use it to the single key in the privateKeys slice
if ec.keyId != "" {
privateKey.KeyID = ec.keyId
}

privateKey.KeyID = ec.keyId

signers, err := createSigners(privateKey)
if err != nil {
Expand All @@ -140,70 +123,23 @@ func (ec *EvidenceCreateCommand) Run() error {
return err
}

// create tmp dir for create evidencecore file and save dsse there
tempDirPath, err := fileutils.CreateTempDir()
if err != nil {
return err
}
// Cleanup the temp working directory at the end.
defer func() {
err = errors.Join(err, fileutils.RemoveTempDir(tempDirPath))
}()

// Create the evidence file.
evdName := "/evidence.json.evd"
if ec.evidenceName != "" {
evdName = "/" + ec.evidenceName + ".json.evd"
}
localEvidenceFilePath := tempDirPath + evdName
evidenceFile, err := os.Create(localEvidenceFilePath)
if err != nil {
return err
}
defer func() {
err = errors.Join(err, errorutils.CheckError(evidenceFile.Close()))
}()

// Encode signedEnvelope into a byte slice
envelopeBytes, err := json.Marshal(signedEnvelope)
if err != nil {
return err
}

// Write the encoded byte slice to the file
_, err = evidenceFile.Write(envelopeBytes)
if err != nil {
return err
}
evidenceManager, err := utils.CreateEvidenceServiceManager(serverDetails, false)

Check failure on line 132 in evidence/create.go

View workflow job for this annotation

GitHub Actions / Static-Check

ineffectual assignment to err (ineffassign)

// Verify if the file already exists in artifactory
rtEvidencePath := strings.Split(intotoStatement.Subject[0].Uri, "/")
err = ec.shouldOverrideExistingEvidence(rtEvidencePath, evdName, servicesManager)
evidenceDetails := evidenceService.EvidenceDetails{
SubjectUri: strings.Split(ec.subject, "@")[0],
DSSEFileRaw: envelopeBytes,
}
_, err = evidenceManager.UploadEvidence(evidenceDetails)
if err != nil {
return err
}

// Upload evidencecore file to artifactory
commonParams := rtServicesUtils.CommonParams{
Pattern: localEvidenceFilePath,
Target: rtEvidencePath[0] + "/",
}
var uploadParamsArray []services.UploadParams
uploadParamsArray = append(uploadParamsArray, services.UploadParams{
CommonParams: &commonParams,
Flat: true,
})
_, _, err = servicesManager.UploadFiles(uploadParamsArray...)

return err
}

func (ec *EvidenceCreateCommand) shouldOverrideExistingEvidence(rtEvidencePath []string, evdName string, servicesManager artifactory.ArtifactoryServicesManager) error {
filePath := strings.Join(rtEvidencePath[:len(rtEvidencePath)-1], "/") + evdName
remoteFile, _ := servicesManager.FileInfo(filePath)
if remoteFile != nil && !ec.override {
return errors.New("file is already exists, use --override to override")
}
clientlog.Output("Evidence is successfully created")
return nil
}

Expand Down
1 change: 0 additions & 1 deletion evidence/cryptox/ecdsa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ func TestECDSASignerVerifierWithMetablockFileAndPEMKey(t *testing.T) {
assert.NoError(t, json.Unmarshal(metadataBytes, &mb))

assert.Equal(t, "304502201fbb03c0937504182a48c66f9218bdcb2e99a07ada273e92e5e543867f98c8d7022100dbfa7bbf74fd76d76c1d08676419cba85bbd81dfb000f3ac6a786693ddc508f5", mb.Signatures[0].Sig)
assert.Equal(t, sv.keyID, mb.Signatures[0].KeyID)

encodedBytes, err := cjson.EncodeCanonical(mb.Signed)
if err != nil {
Expand Down
1 change: 0 additions & 1 deletion evidence/cryptox/ed25519_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ func TestED25519SignerVerifierWithMetablockFileAndPEMKey(t *testing.T) {
}

assert.Equal(t, "4c8b7605a9195d4ddba54493bbb5257a9836c1d16056a027fd77e97b95a4f3e36f8bc3c9c9960387d68187760b3072a30c44f992c5bf8f7497c303a3b0a32403", mb.Signatures[0].Sig)
assert.Equal(t, sv.keyID, mb.Signatures[0].KeyID)

encodedBytes, err := cjson.EncodeCanonical(mb.Signed)
if err != nil {
Expand Down
Loading

0 comments on commit b87efc9

Please sign in to comment.