fix: harden DWH credential administration CLI
This commit is contained in:
@@ -214,6 +214,151 @@ func TestCreateRejectsInvalidExpiryWithoutWritingOutput(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetadataRejectsEmbeddedCanonicalCredentialBeforePersistence(t *testing.T) {
|
||||
material, err := credential.Generate(bytes.NewReader(bytes.Repeat([]byte{0x33}, 44)))
|
||||
if err != nil {
|
||||
t.Fatalf("Generate() error = %v", err)
|
||||
}
|
||||
sentinel := string(material.Value)
|
||||
root := t.TempDir()
|
||||
output := filepath.Join(t.TempDir(), "key")
|
||||
stdout, stderr, code := run(t, "--registry-root", root, "key", "create", "--installation-id", "embedded", "--description", "prefix-"+sentinel+"-suffix", "--output", output)
|
||||
if code != 2 || stdout != "" || stderr != "unsafe invocation\n" {
|
||||
t.Fatalf("embedded description result = (%d, %q, %q)", code, stdout, stderr)
|
||||
}
|
||||
if strings.Contains(stdout+stderr, sentinel) {
|
||||
t.Fatal("embedded credential appeared in create diagnostics")
|
||||
}
|
||||
if _, err := os.Stat(output); !errors.Is(err, os.ErrNotExist) {
|
||||
t.Fatalf("embedded description output stat error = %v, want absent", err)
|
||||
}
|
||||
|
||||
cleanOutput := filepath.Join(t.TempDir(), "clean-key")
|
||||
if code := runOnly(t, "--registry-root", root, "key", "create", "--installation-id", "embedded", "--output", cleanOutput); code != 0 {
|
||||
t.Fatalf("clean create exit = %d", code)
|
||||
}
|
||||
listOut, _, listCode := run(t, "--registry-root", root, "key", "list", "--json")
|
||||
if listCode != 0 || strings.Contains(listOut, sentinel) {
|
||||
t.Fatalf("list after rejected metadata = (%d, %q)", listCode, listOut)
|
||||
}
|
||||
var listed []registry.PublicRecord
|
||||
if err := json.Unmarshal([]byte(listOut), &listed); err != nil || len(listed) != 1 {
|
||||
t.Fatalf("list = %q, err=%v", listOut, err)
|
||||
}
|
||||
keyID := listed[0].KeyID
|
||||
stdout, stderr, code = run(t, "--registry-root", root, "key", "revoke", "--key-id", keyID, "--reason", "prefix-"+sentinel+"-suffix")
|
||||
if code != 2 || stdout != "" || stderr != "unsafe invocation\n" || strings.Contains(stdout+stderr, sentinel) {
|
||||
t.Fatalf("embedded reason result = (%d, %q, %q)", code, stdout, stderr)
|
||||
}
|
||||
statusOut, _, statusCode := run(t, "--registry-root", root, "key", "status", "--key-id", keyID, "--json")
|
||||
if statusCode != 0 || strings.Contains(statusOut, sentinel) {
|
||||
t.Fatalf("status after rejected reason = (%d, %q)", statusCode, statusOut)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetadataAndExpiryAreValidatedBeforeKeyGeneration(t *testing.T) {
|
||||
oldNow := nowUTC
|
||||
nowUTC = func() time.Time { return time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC) }
|
||||
t.Cleanup(func() { nowUTC = oldNow })
|
||||
cases := []struct {
|
||||
name string
|
||||
value string
|
||||
}{
|
||||
{name: "invalid utf8", value: string([]byte{0xc3, 0x28})},
|
||||
{name: "unicode control", value: "before\u0085after"},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
output := filepath.Join(t.TempDir(), "key")
|
||||
if code := runOnly(t, "--registry-root", t.TempDir(), "key", "create", "--installation-id", "client", "--description", tc.value, "--output", output); code != 2 {
|
||||
t.Fatalf("invalid metadata exit = %d, want 2", code)
|
||||
}
|
||||
if _, err := os.Stat(output); !errors.Is(err, os.ErrNotExist) {
|
||||
t.Fatalf("invalid metadata output stat error = %v, want absent", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
for _, expiry := range []string{"2025-12-31T23:59:59Z", "2026-01-01T00:00:00Z"} {
|
||||
t.Run("expiry "+expiry, func(t *testing.T) {
|
||||
output := filepath.Join(t.TempDir(), "key")
|
||||
if code := runOnly(t, "--registry-root", t.TempDir(), "key", "create", "--installation-id", "client", "--expires-at", expiry, "--output", output); code != 2 {
|
||||
t.Fatalf("invalid expiry exit = %d, want 2", code)
|
||||
}
|
||||
if _, err := os.Stat(output); !errors.Is(err, os.ErrNotExist) {
|
||||
t.Fatalf("invalid expiry output stat error = %v, want absent", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
output := filepath.Join(t.TempDir(), "future-key")
|
||||
if code := runOnly(t, "--registry-root", t.TempDir(), "key", "create", "--installation-id", "client", "--expires-at", "2026-01-01T00:00:01Z", "--output", output); code != 0 {
|
||||
t.Fatalf("future expiry exit = %d, want 0", code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeAcceptsOnlyExactTaskFourReservation(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
socket := filepath.Join(t.TempDir(), "verify.sock")
|
||||
stdout, stderr, code := run(t, "serve", "--registry-root", root, "--socket", socket)
|
||||
if code != 4 || stdout != "" || stderr != "serve is not available in this release\n" {
|
||||
t.Fatalf("valid serve reservation = (%d, %q, %q)", code, stdout, stderr)
|
||||
}
|
||||
invalid := [][]string{
|
||||
{"serve", "--registry-root", "relative", "--socket", socket},
|
||||
{"serve", "--registry-root", root},
|
||||
{"serve", "--registry-root", root, "--socket", "relative"},
|
||||
{"serve", "--registry-root", root, "--socket", socket, "--socket", socket},
|
||||
{"serve", "--socket", socket, "--registry-root", root},
|
||||
{"serve", "--registry-root", root, "--socket", socket, "--unknown", "x"},
|
||||
{"--registry-root", root, "serve", "--socket", socket},
|
||||
}
|
||||
for _, args := range invalid {
|
||||
stdout, stderr, code = run(t, args...)
|
||||
if code != 2 || stdout != "" || stderr != "unsafe invocation\n" {
|
||||
t.Errorf("invalid serve %q = (%d, %q, %q)", args, code, stdout, stderr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateCleansOnlyWhenFailedPublicationProvesKeyAbsent(t *testing.T) {
|
||||
oldAdd, oldClose := addRecord, closeStore
|
||||
t.Cleanup(func() { addRecord, closeStore = oldAdd, oldClose })
|
||||
root := t.TempDir()
|
||||
output := filepath.Join(t.TempDir(), "pre-publication")
|
||||
addRecord = func(*registry.Store, record.Record) error { return errors.New("synthetic add failure") }
|
||||
if code := runOnly(t, "--registry-root", root, "key", "create", "--installation-id", "client", "--output", output); code != 4 {
|
||||
t.Fatalf("pre-publication failure exit = %d, want 4", code)
|
||||
}
|
||||
if _, err := os.Stat(output); !errors.Is(err, os.ErrNotExist) {
|
||||
t.Fatalf("pre-publication output stat error = %v, want absent", err)
|
||||
}
|
||||
|
||||
output = filepath.Join(t.TempDir(), "post-publication")
|
||||
addRecord = func(store *registry.Store, value record.Record) error {
|
||||
if err := store.Add(value); err != nil {
|
||||
return err
|
||||
}
|
||||
return errors.New("synthetic ambiguous post-publication failure")
|
||||
}
|
||||
if code := runOnly(t, "--registry-root", root, "key", "create", "--installation-id", "client", "--output", output); code != 4 {
|
||||
t.Fatalf("post-publication failure exit = %d, want 4", code)
|
||||
}
|
||||
if _, err := os.Stat(output); err != nil {
|
||||
t.Fatalf("post-publication output stat error = %v, want retained: %v", err, err)
|
||||
}
|
||||
closeStore = func(store *registry.Store) error {
|
||||
_ = store.Close()
|
||||
return errors.New("synthetic close failure")
|
||||
}
|
||||
output = filepath.Join(t.TempDir(), "close-failure")
|
||||
addRecord = oldAdd
|
||||
if code := runOnly(t, "--registry-root", root, "key", "create", "--installation-id", "client-two", "--output", output); code != 4 {
|
||||
t.Fatalf("close failure exit = %d, want 4", code)
|
||||
}
|
||||
if _, err := os.Stat(output); err != nil {
|
||||
t.Fatalf("close-failure output stat error = %v, want retained: %v", err, err)
|
||||
}
|
||||
}
|
||||
|
||||
func run(t *testing.T, args ...string) (string, string, int) {
|
||||
t.Helper()
|
||||
var stdout, stderr bytes.Buffer
|
||||
|
||||
Reference in New Issue
Block a user