diff --git a/internal/subsonic/auth_test.go b/internal/subsonic/auth_test.go new file mode 100644 index 00000000..e2d0f3a1 --- /dev/null +++ b/internal/subsonic/auth_test.go @@ -0,0 +1,44 @@ +package subsonic + +import ( + "crypto/md5" + "encoding/hex" + "testing" +) + +func TestDecodePasswordEnc(t *testing.T) { + out, err := decodePassword("enc:68656c6c6f") + if err != nil { + t.Fatalf("decode: %v", err) + } + if out != "hello" { + t.Errorf("decode = %q, want hello", out) + } +} + +func TestDecodePasswordPlain(t *testing.T) { + out, err := decodePassword("hunter2") + if err != nil || out != "hunter2" { + t.Errorf("plain passthrough = %q, %v", out, err) + } +} + +func TestDecodePasswordBadHex(t *testing.T) { + if _, err := decodePassword("enc:zzzz"); err == nil { + t.Error("expected error for malformed enc: prefix") + } +} + +// TestTokenMD5Derivation documents the t = md5(password + salt) construction +// so regressions in the auth path surface as a failing checksum rather than a +// 40/wrong-credentials response that could be mistaken for bad inputs. +func TestTokenMD5Derivation(t *testing.T) { + password := "hunter2" + salt := "NaClz" + sum := md5.Sum([]byte(password + salt)) + want := hex.EncodeToString(sum[:]) + const expected = "91b894c3c9af9c16bec1b3f771e31462" + if want != expected { + t.Errorf("md5(password+salt) = %s, want %s", want, expected) + } +}