model_wireguard_test.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package model
  2. import (
  3. "encoding/json"
  4. "reflect"
  5. "strings"
  6. "testing"
  7. )
  8. func TestClientToRecordRoundTripWireGuard(t *testing.T) {
  9. c := &Client{
  10. Email: "[email protected]",
  11. Enable: true,
  12. PrivateKey: "cGVlci1wcml2YXRlLWtleS1iYXNlNjQtMzJieXRlcw==",
  13. PublicKey: "cGVlci1wdWJsaWMta2V5LWJhc2U2NC0zMmJ5dGVzISE=",
  14. AllowedIPs: []string{"10.0.0.2/32", "fd00::2/128"},
  15. PreSharedKey: "cHNrLWJhc2U2NC0zMmJ5dGVzLXBsYWNlaG9sZGVyISE=",
  16. KeepAlive: KeepAlivePtr(25),
  17. }
  18. rec := c.ToRecord()
  19. if rec.AllowedIPs != "10.0.0.2/32,fd00::2/128" {
  20. t.Fatalf("AllowedIPs CSV = %q, want %q", rec.AllowedIPs, "10.0.0.2/32,fd00::2/128")
  21. }
  22. got := rec.ToClient()
  23. for _, f := range []struct {
  24. name string
  25. a, b any
  26. }{
  27. {"PrivateKey", c.PrivateKey, got.PrivateKey},
  28. {"PublicKey", c.PublicKey, got.PublicKey},
  29. {"PreSharedKey", c.PreSharedKey, got.PreSharedKey},
  30. {"KeepAlive", c.KeepAliveSeconds(), got.KeepAliveSeconds()},
  31. } {
  32. if f.a != f.b {
  33. t.Errorf("%s round-trip = %v, want %v", f.name, f.b, f.a)
  34. }
  35. }
  36. if !reflect.DeepEqual(got.AllowedIPs, c.AllowedIPs) {
  37. t.Errorf("AllowedIPs round-trip = %v, want %v", got.AllowedIPs, c.AllowedIPs)
  38. }
  39. }
  40. // ToClient feeds the settings JSON of every protocol, not just the tunnels, and
  41. // that JSON reaches xray-core verbatim through GenXrayInboundConfig.
  42. func TestClientToClientOmitsUnsetKeepAlive(t *testing.T) {
  43. rec := &ClientRecord{Email: "[email protected]", UUID: "11111111-2222-3333-4444-555555555555", Enable: true}
  44. if got := rec.ToClient().KeepAlive; got != nil {
  45. t.Fatalf("KeepAlive for a record that never set one = %d, want nil", *got)
  46. }
  47. blob, err := json.Marshal(map[string][]Client{"clients": {*rec.ToClient()}})
  48. if err != nil {
  49. t.Fatalf("marshal settings payload: %v", err)
  50. }
  51. if strings.Contains(string(blob), "keepAlive") {
  52. t.Fatalf("settings payload carries keepAlive for a non-tunnel client: %s", blob)
  53. }
  54. }
  55. func TestClientRecordEmptyAllowedIPs(t *testing.T) {
  56. rec := &ClientRecord{Email: "[email protected]", AllowedIPs: ""}
  57. if got := rec.ToClient().AllowedIPs; got != nil {
  58. t.Fatalf("empty CSV → AllowedIPs = %v, want nil", got)
  59. }
  60. rec.AllowedIPs = " 10.0.0.5/32 , ,"
  61. if got := rec.ToClient().AllowedIPs; !reflect.DeepEqual(got, []string{"10.0.0.5/32"}) {
  62. t.Fatalf("trimmed CSV → AllowedIPs = %v, want [10.0.0.5/32]", got)
  63. }
  64. }
  65. func TestMergeClientRecordWireGuardKeysPreserved(t *testing.T) {
  66. existing := &ClientRecord{
  67. Email: "[email protected]",
  68. PrivateKey: "existing-private",
  69. PublicKey: "existing-public",
  70. AllowedIPs: "10.0.0.7/32",
  71. UpdatedAt: 100,
  72. }
  73. incomingEmpty := &ClientRecord{Email: "[email protected]", UpdatedAt: 200}
  74. MergeClientRecord(existing, incomingEmpty)
  75. if existing.PrivateKey != "existing-private" || existing.PublicKey != "existing-public" {
  76. t.Fatalf("empty incoming wiped keys: priv=%q pub=%q", existing.PrivateKey, existing.PublicKey)
  77. }
  78. if existing.AllowedIPs != "10.0.0.7/32" {
  79. t.Fatalf("empty incoming wiped allowedIPs: %q", existing.AllowedIPs)
  80. }
  81. incomingNewer := &ClientRecord{
  82. Email: "[email protected]",
  83. AllowedIPs: "10.0.0.8/32",
  84. UpdatedAt: 300,
  85. }
  86. MergeClientRecord(existing, incomingNewer)
  87. if existing.AllowedIPs != "10.0.0.8/32" {
  88. t.Fatalf("newer allowedIPs not applied: %q", existing.AllowedIPs)
  89. }
  90. }