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 }