github.com/justincormack/cli@v0.0.0-20201215022714-831ebeae9675/cli/command/trust/signer_add_test.go (about)

     1  package trust
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"runtime"
     9  	"testing"
    10  
    11  	"github.com/docker/cli/cli/config"
    12  	"github.com/docker/cli/internal/test"
    13  	notaryfake "github.com/docker/cli/internal/test/notary"
    14  	"github.com/theupdateframework/notary"
    15  	"gotest.tools/v3/assert"
    16  	is "gotest.tools/v3/assert/cmp"
    17  )
    18  
    19  func TestTrustSignerAddErrors(t *testing.T) {
    20  	testCases := []struct {
    21  		name          string
    22  		args          []string
    23  		expectedError string
    24  	}{
    25  		{
    26  			name:          "not-enough-args",
    27  			expectedError: "requires at least 2 argument",
    28  		},
    29  		{
    30  			name:          "no-key",
    31  			args:          []string{"foo", "bar"},
    32  			expectedError: "path to a public key must be provided using the `--key` flag",
    33  		},
    34  		{
    35  			name:          "reserved-releases-signer-add",
    36  			args:          []string{"releases", "my-image", "--key", "/path/to/key"},
    37  			expectedError: "releases is a reserved keyword, please use a different signer name",
    38  		},
    39  		{
    40  			name:          "disallowed-chars",
    41  			args:          []string{"ali/ce", "my-image", "--key", "/path/to/key"},
    42  			expectedError: "signer name \"ali/ce\" must start with lowercase alphanumeric characters and can include \"-\" or \"_\" after the first character",
    43  		},
    44  		{
    45  			name:          "no-upper-case",
    46  			args:          []string{"Alice", "my-image", "--key", "/path/to/key"},
    47  			expectedError: "signer name \"Alice\" must start with lowercase alphanumeric characters and can include \"-\" or \"_\" after the first character",
    48  		},
    49  		{
    50  			name:          "start-with-letter",
    51  			args:          []string{"_alice", "my-image", "--key", "/path/to/key"},
    52  			expectedError: "signer name \"_alice\" must start with lowercase alphanumeric characters and can include \"-\" or \"_\" after the first character",
    53  		},
    54  	}
    55  	tmpDir, err := ioutil.TempDir("", "docker-sign-test-")
    56  	assert.NilError(t, err)
    57  	defer os.RemoveAll(tmpDir)
    58  	config.SetDir(tmpDir)
    59  
    60  	for _, tc := range testCases {
    61  		cli := test.NewFakeCli(&fakeClient{})
    62  		cli.SetNotaryClient(notaryfake.GetOfflineNotaryRepository)
    63  		cmd := newSignerAddCommand(cli)
    64  		cmd.SetArgs(tc.args)
    65  		cmd.SetOut(ioutil.Discard)
    66  		assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
    67  	}
    68  }
    69  
    70  func TestSignerAddCommandNoTargetsKey(t *testing.T) {
    71  	tmpDir, err := ioutil.TempDir("", "docker-sign-test-")
    72  	assert.NilError(t, err)
    73  	defer os.RemoveAll(tmpDir)
    74  	config.SetDir(tmpDir)
    75  
    76  	tmpfile, err := ioutil.TempFile("", "pemfile")
    77  	assert.NilError(t, err)
    78  	defer os.Remove(tmpfile.Name())
    79  
    80  	cli := test.NewFakeCli(&fakeClient{})
    81  	cli.SetNotaryClient(notaryfake.GetEmptyTargetsNotaryRepository)
    82  	cmd := newSignerAddCommand(cli)
    83  	cmd.SetArgs([]string{"--key", tmpfile.Name(), "alice", "alpine", "linuxkit/alpine"})
    84  
    85  	cmd.SetOut(ioutil.Discard)
    86  	assert.Error(t, cmd.Execute(), fmt.Sprintf("could not parse public key from file: %s: no valid public key found", tmpfile.Name()))
    87  }
    88  
    89  func TestSignerAddCommandBadKeyPath(t *testing.T) {
    90  	tmpDir, err := ioutil.TempDir("", "docker-sign-test-")
    91  	assert.NilError(t, err)
    92  	defer os.RemoveAll(tmpDir)
    93  	config.SetDir(tmpDir)
    94  
    95  	cli := test.NewFakeCli(&fakeClient{})
    96  	cli.SetNotaryClient(notaryfake.GetEmptyTargetsNotaryRepository)
    97  	cmd := newSignerAddCommand(cli)
    98  	cmd.SetArgs([]string{"--key", "/path/to/key.pem", "alice", "alpine"})
    99  
   100  	cmd.SetOut(ioutil.Discard)
   101  	expectedError := "unable to read public key from file: open /path/to/key.pem: no such file or directory"
   102  	if runtime.GOOS == "windows" {
   103  		expectedError = "unable to read public key from file: open /path/to/key.pem: The system cannot find the path specified."
   104  	}
   105  	assert.Error(t, cmd.Execute(), expectedError)
   106  }
   107  
   108  func TestSignerAddCommandInvalidRepoName(t *testing.T) {
   109  	tmpDir, err := ioutil.TempDir("", "docker-sign-test-")
   110  	assert.NilError(t, err)
   111  	defer os.RemoveAll(tmpDir)
   112  	config.SetDir(tmpDir)
   113  
   114  	pubKeyDir, err := ioutil.TempDir("", "key-load-test-pubkey-")
   115  	assert.NilError(t, err)
   116  	defer os.RemoveAll(pubKeyDir)
   117  	pubKeyFilepath := filepath.Join(pubKeyDir, "pubkey.pem")
   118  	assert.NilError(t, ioutil.WriteFile(pubKeyFilepath, pubKeyFixture, notary.PrivNoExecPerms))
   119  
   120  	cli := test.NewFakeCli(&fakeClient{})
   121  	cli.SetNotaryClient(notaryfake.GetUninitializedNotaryRepository)
   122  	cmd := newSignerAddCommand(cli)
   123  	imageName := "870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd"
   124  	cmd.SetArgs([]string{"--key", pubKeyFilepath, "alice", imageName})
   125  
   126  	cmd.SetOut(ioutil.Discard)
   127  	assert.Error(t, cmd.Execute(), "Failed to add signer to: 870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd")
   128  	expectedErr := fmt.Sprintf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings\n\n", imageName)
   129  
   130  	assert.Check(t, is.Equal(expectedErr, cli.ErrBuffer().String()))
   131  }
   132  
   133  func TestIngestPublicKeys(t *testing.T) {
   134  	// Call with a bad path
   135  	_, err := ingestPublicKeys([]string{"foo", "bar"})
   136  	expectedError := "unable to read public key from file: open foo: no such file or directory"
   137  	if runtime.GOOS == "windows" {
   138  		expectedError = "unable to read public key from file: open foo: The system cannot find the file specified."
   139  	}
   140  	assert.Error(t, err, expectedError)
   141  	// Call with real file path
   142  	tmpfile, err := ioutil.TempFile("", "pemfile")
   143  	assert.NilError(t, err)
   144  	defer os.Remove(tmpfile.Name())
   145  	_, err = ingestPublicKeys([]string{tmpfile.Name()})
   146  	assert.Error(t, err, fmt.Sprintf("could not parse public key from file: %s: no valid public key found", tmpfile.Name()))
   147  }