From e725cf1f613a89339bb4e24255344314a6a86967 Mon Sep 17 00:00:00 2001 From: thibaud-leclere Date: Fri, 10 Apr 2026 10:21:22 +0200 Subject: [PATCH] feat: add credential serialization helpers --- internal/secretstore/codec.go | 23 ++++++++++++++++ internal/secretstore/codec_test.go | 42 ++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 internal/secretstore/codec.go create mode 100644 internal/secretstore/codec_test.go diff --git a/internal/secretstore/codec.go b/internal/secretstore/codec.go new file mode 100644 index 0000000..bf956de --- /dev/null +++ b/internal/secretstore/codec.go @@ -0,0 +1,23 @@ +package secretstore + +import "encoding/json" + +func MarshalCredential(cred Credential) ([]byte, error) { + if err := cred.Validate(); err != nil { + return nil, err + } + + return json.Marshal(cred) +} + +func UnmarshalCredential(data []byte) (Credential, error) { + var cred Credential + if err := json.Unmarshal(data, &cred); err != nil { + return Credential{}, err + } + if err := cred.Validate(); err != nil { + return Credential{}, err + } + + return cred, nil +} diff --git a/internal/secretstore/codec_test.go b/internal/secretstore/codec_test.go new file mode 100644 index 0000000..686c182 --- /dev/null +++ b/internal/secretstore/codec_test.go @@ -0,0 +1,42 @@ +package secretstore + +import "testing" + +func TestMarshalCredentialRoundTrip(t *testing.T) { + input := Credential{ + Host: "imap.example.com", + Username: "alice", + Password: "secret", + } + + data, err := MarshalCredential(input) + if err != nil { + t.Fatalf("MarshalCredential returned error: %v", err) + } + + output, err := UnmarshalCredential(data) + if err != nil { + t.Fatalf("UnmarshalCredential returned error: %v", err) + } + + if output != input { + t.Fatalf("round-trip mismatch: got %#v want %#v", output, input) + } +} + +func TestMarshalCredentialRejectsInvalidCredential(t *testing.T) { + _, err := MarshalCredential(Credential{ + Host: "imap.example.com", + Username: "alice", + }) + if err == nil { + t.Fatal("expected MarshalCredential to reject incomplete credential") + } +} + +func TestUnmarshalCredentialRejectsInvalidCredential(t *testing.T) { + _, err := UnmarshalCredential([]byte(`{"host":"imap.example.com","username":"alice"}`)) + if err == nil { + t.Fatal("expected UnmarshalCredential to reject incomplete credential") + } +}