Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/compose/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (s *composeService) publish(ctx context.Context, project *types.Project, re
return err
}
if !accept {
return nil
return api.ErrCanceled
}
err = s.Push(ctx, project, api.PushOptions{IgnoreFailures: true, ImageMandatory: true})
if err != nil {
Expand Down
63 changes: 63 additions & 0 deletions pkg/compose/publish_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package compose

import (
"errors"
"os"
"slices"
"testing"

Expand Down Expand Up @@ -100,3 +102,64 @@ services:
return !slices.Contains([]string{".Data", ".Digest", ".Size"}, path.String())
}, cmp.Ignore()))
}

func Test_preChecks_sensitive_data_detected_decline(t *testing.T) {
dir := t.TempDir()
envPath := dir + "/secrets.env"
secretData := `AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"`
err := os.WriteFile(envPath, []byte(secretData), 0o600)
assert.NilError(t, err)

project := &types.Project{
Services: types.Services{
"web": {
Name: "web",
Image: "nginx",
EnvFiles: []types.EnvFile{
{Path: envPath, Required: true},
},
},
},
}

declined := func(message string, defaultValue bool) (bool, error) {
return false, nil
}
svc := &composeService{
prompt: declined,
}

accept, err := svc.preChecks(t.Context(), project, api.PublishOptions{})
assert.NilError(t, err)
assert.Equal(t, accept, false)
}

func Test_publish_decline_returns_ErrCanceled(t *testing.T) {
project := &types.Project{
Services: types.Services{
"web": {
Name: "web",
Image: "nginx",
Volumes: []types.ServiceVolumeConfig{
{
Type: types.VolumeTypeBind,
Source: "/host/path",
Target: "/container/path",
},
},
},
},
}

declined := func(message string, defaultValue bool) (bool, error) {
return false, nil
}
svc := &composeService{
prompt: declined,
events: &ignore{},
}

err := svc.publish(t.Context(), project, "docker.io/myorg/myapp:latest", api.PublishOptions{})
assert.Assert(t, errors.Is(err, api.ErrCanceled),
"expected api.ErrCanceled when user declines, got: %v", err)
}
4 changes: 2 additions & 2 deletions pkg/e2e/publish_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ or remove sensitive data from your Compose configuration
"-p", projectName, "publish", "test/test", "--dry-run")
cmd.Stdin = strings.NewReader("n\n")
res := icmd.RunCmd(cmd)
res.Assert(t, icmd.Expected{ExitCode: 0})
res.Assert(t, icmd.Expected{ExitCode: 130})
out := res.Combined()
assert.Assert(t, strings.Contains(out, "you are about to publish bind mounts declaration within your OCI artifact."), out)
assert.Assert(t, strings.Contains(out, "e2e/fixtures/publish:/user-data"), out)
Expand Down Expand Up @@ -111,7 +111,7 @@ or remove sensitive data from your Compose configuration
"-p", projectName, "publish", "test/test", "--with-env", "--dry-run")
cmd.Stdin = strings.NewReader("n\n")
res := icmd.RunCmd(cmd)
res.Assert(t, icmd.Expected{ExitCode: 0})
res.Assert(t, icmd.Expected{ExitCode: 130})

output := res.Combined()
assert.Assert(t, strings.Contains(output, "you are about to publish sensitive data within your OCI artifact.\n"), output)
Expand Down
Loading