From 3e39507f5a1f527b9a098fe657ecf4450e61454d Mon Sep 17 00:00:00 2001 From: Martin/Geno Date: Thu, 15 Feb 2018 22:03:49 +0100 Subject: [PATCH] improve JID struct --- client/auth.go | 6 +- client/connect.go | 2 +- daemon/tester/bot.go | 11 ++-- daemon/tester/output.go | 8 +-- daemon/tester/status.go | 4 +- daemon/tester/tester.go | 20 +++--- database/main.go | 10 +-- model/account.go | 10 +-- server/toclient/connect.go | 4 +- server/toclient/register.go | 20 +++--- xmpp/base/jid.go | 66 ++++++++++--------- xmpp/base/jid_is.go | 24 +++++++ xmpp/base/jid_is_test.go | 123 ++++++++++++++++++++++++++++++++++++ xmpp/base/jid_test.go | 62 ++++++++++++------ 14 files changed, 275 insertions(+), 95 deletions(-) create mode 100644 xmpp/base/jid_is.go create mode 100644 xmpp/base/jid_is_test.go diff --git a/client/auth.go b/client/auth.go index 24b0914..0e5fc5a 100644 --- a/client/auth.go +++ b/client/auth.go @@ -61,8 +61,8 @@ func (client *Client) auth(password string) error { cnonceStr := cnonce() digestURI := "xmpp/" + client.JID.Domain nonceCount := fmt.Sprintf("%08x", 1) - digest := saslDigestResponse(client.JID.Node, realm, password, nonce, cnonceStr, "AUTHENTICATE", digestURI, nonceCount) - message := "username=\"" + client.JID.Node + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", cnonce=\"" + cnonceStr + + digest := saslDigestResponse(client.JID.Local, realm, password, nonce, cnonceStr, "AUTHENTICATE", digestURI, nonceCount) + message := "username=\"" + client.JID.Local + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", cnonce=\"" + cnonceStr + "\", nc=" + nonceCount + ", qop=" + qop + ", digest-uri=\"" + digestURI + "\", response=" + digest + ", charset=" + charset response.Body = base64.StdEncoding.EncodeToString([]byte(message)) @@ -72,7 +72,7 @@ func (client *Client) auth(password string) error { if m == "PLAIN" { mechanism = m // Plain authentication: send base64-encoded \x00 user \x00 password. - raw := "\x00" + client.JID.Node + "\x00" + password + raw := "\x00" + client.JID.Local + "\x00" + password enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw))) base64.StdEncoding.Encode(enc, []byte(raw)) client.Send(&xmpp.SASLAuth{ diff --git a/client/connect.go b/client/connect.go index 0841601..c708a9d 100644 --- a/client/connect.go +++ b/client/connect.go @@ -120,7 +120,7 @@ func (client *Client) connect(password string) error { if bind == nil { return errors.New("bind is nil") } else if bind.JID != nil { - client.JID.Node = bind.JID.Node + client.JID.Local = bind.JID.Local client.JID.Domain = bind.JID.Domain client.JID.Resource = bind.JID.Resource client.Logging.Infof("set jid by server bind '%s'", bind.JID.Full()) diff --git a/daemon/tester/bot.go b/daemon/tester/bot.go index e714724..26231ee 100644 --- a/daemon/tester/bot.go +++ b/daemon/tester/bot.go @@ -110,21 +110,22 @@ func (t *Tester) StartBot(status *Status) { first := true allAdmins := "" isAdmin := false + fromBare := msg.From for _, jid := range botAllowed(t.Admins, status.account.Admins) { if first { first = false - allAdmins += jid.Bare() } else { - allAdmins += ", " + jid.Bare() + allAdmins += ", " } - if jid.Bare() == msg.From.Bare() { + allAdmins += jid.Bare().String() + if jid.Bare().IsEqual(fromBare) { isAdmin = true - status.client.Send(xmpp.MessageClient{Type: msg.Type, To: jid, Body: "last message, disconnect requested by " + msg.From.Bare()}) + status.client.Send(xmpp.MessageClient{Type: msg.Type, To: jid, Body: "last message, disconnect requested by " + fromBare.String()}) } } if isAdmin { - status.Disconnect(fmt.Sprintf("disconnect by admin '%s'", msg.From.Bare())) + status.Disconnect(fmt.Sprintf("disconnect by admin '%s'", fromBare.String())) return } status.client.Send(xmpp.MessageClient{Type: msg.Type, To: msg.From, Body: "not allowed, ask " + allAdmins}) diff --git a/daemon/tester/output.go b/daemon/tester/output.go index e50d3a9..53599df 100644 --- a/daemon/tester/output.go +++ b/daemon/tester/output.go @@ -57,17 +57,17 @@ func (t *Tester) Output() *Output { toJID := xmppbase.NewJID(to) link := &Link{ Source: status.JID.Domain, - SourceJID: status.JID.Bare(), + SourceJID: status.JID.Bare().String(), Target: toJID.Domain, - TargetJID: toJID.Bare(), + TargetJID: toJID.Bare().String(), FromSource: linkOK, FromTarget: false, } if switchSourceTarget { link.Source = toJID.Domain - link.SourceJID = toJID.Bare() + link.SourceJID = toJID.Bare().String() link.Target = status.JID.Domain - link.TargetJID = status.JID.Bare() + link.TargetJID = status.JID.Bare().String() link.FromSource = false link.FromTarget = linkOK } diff --git a/daemon/tester/status.go b/daemon/tester/status.go index 60d50d6..3a302b9 100644 --- a/daemon/tester/status.go +++ b/daemon/tester/status.go @@ -59,7 +59,7 @@ func (s *Status) Update(timeout time.Duration) { } c := &client.Client{ - JID: xmppbase.NewJID(s.account.JID.Bare()), + JID: s.account.JID.Bare(), Protocol: "tcp4", Logging: s.client.Logging, Timeout: timeout / 2, @@ -72,7 +72,7 @@ func (s *Status) Update(timeout time.Duration) { s.IPv4 = false } - c.JID = xmppbase.NewJID(s.account.JID.Bare()) + c.JID = s.account.JID.Bare() c.Protocol = "tcp6" if err := c.Connect(s.account.Password); err == nil { diff --git a/daemon/tester/tester.go b/daemon/tester/tester.go index 11969e1..c40798a 100644 --- a/daemon/tester/tester.go +++ b/daemon/tester/tester.go @@ -44,7 +44,7 @@ func (t *Tester) Start(mainClient *client.Client, password string) { t.mux.Lock() defer t.mux.Unlock() - t.Status[mainClient.JID.Bare()] = status + t.Status[mainClient.JID.Bare().String()] = status go t.StartBot(status) for _, acc := range t.Accounts { @@ -58,11 +58,12 @@ func (t *Tester) Close() { } func (t *Tester) Connect(acc *Account) { - logCTX := log.WithField("jid", acc.JID.Full()) - status, ok := t.Status[acc.JID.Bare()] + logCTX := log.WithField("jid", acc.JID.Full().String()) + bare := acc.JID.Bare().String() + status, ok := t.Status[bare] if !ok { status = NewStatus(t.mainClient, acc) - t.Status[acc.JID.Bare()] = status + t.Status[bare] = status } else if status.JID == nil { status.JID = acc.JID } @@ -99,19 +100,20 @@ func (t *Tester) UpdateConnectionStatus(from, to *xmppbase.JID, recvmsg string) t.mux.Lock() defer t.mux.Unlock() - status, ok := t.Status[from.Bare()] + status, ok := t.Status[from.Bare().String()] if !ok { logCTX.Warn("recv msg without receiver") return } - msg, ok := status.MessageForConnection[to.Bare()] + toBare := to.Bare().String() + msg, ok := status.MessageForConnection[toBare] logCTX = logCTX.WithField("msg-send", msg) if !ok || msg != recvmsg || msg == "" || recvmsg == "" { logCTX.Warn("recv wrong msg") return } - delete(status.MessageForConnection, to.Bare()) - status.Connections[to.Bare()] = true + delete(status.MessageForConnection, toBare) + status.Connections[toBare] = true logCTX.Info("recv msg") } @@ -163,7 +165,7 @@ func (t *Tester) CheckStatus() { Type: xmpp.MessageTypeChat, To: s.JID, }) - own.MessageForConnection[s.JID.Bare()] = msg + own.MessageForConnection[s.JID.Bare().String()] = msg logCTXTo.Debug("test send") send++ } diff --git a/database/main.go b/database/main.go index b0579ef..310010c 100644 --- a/database/main.go +++ b/database/main.go @@ -16,7 +16,7 @@ type State struct { } func (s *State) AddAccount(a *model.Account) error { - if a.Node == "" { + if a.Local == "" { return errors.New("No localpart exists in account") } if d := a.Domain; d != nil { @@ -39,11 +39,11 @@ func (s *State) AddAccount(a *model.Account) error { if domain.Accounts == nil { domain.Accounts = make(map[string]*model.Account) } - _, ok = domain.Accounts[a.Node] + _, ok = domain.Accounts[a.Local] if ok { return errors.New("exists already") } - domain.Accounts[a.Node] = a + domain.Accounts[a.Local] = a a.Domain = d return nil } @@ -54,7 +54,7 @@ func (s *State) Authenticate(jid *xmppbase.JID, password string) (bool, error) { logger := log.WithField("database", "auth") if domain, ok := s.Domains[jid.Domain]; ok { - if acc, ok := domain.Accounts[jid.Node]; ok { + if acc, ok := domain.Accounts[jid.Local]; ok { if acc.ValidatePassword(password) { return true, nil } else { @@ -73,7 +73,7 @@ func (s *State) GetAccount(jid *xmppbase.JID) *model.Account { logger := log.WithField("database", "get") if domain, ok := s.Domains[jid.Domain]; ok { - if acc, ok := domain.Accounts[jid.Node]; ok { + if acc, ok := domain.Accounts[jid.Local]; ok { return acc } else { logger.Debug("account not found") diff --git a/model/account.go b/model/account.go index d788e4a..4d64ce9 100644 --- a/model/account.go +++ b/model/account.go @@ -20,18 +20,18 @@ func (d *Domain) GetJID() *xmppbase.JID { } func (d *Domain) UpdateAccount(a *Account) error { - if a.Node == "" { + if a.Local == "" { return errors.New("No localpart exists in account") } d.Lock() - d.Accounts[a.Node] = a + d.Accounts[a.Local] = a d.Unlock() a.Domain = d return nil } type Account struct { - Node string `json:"-"` + Local string `json:"-"` Domain *Domain `json:"-"` Password string `json:"password"` Roster map[string]*Buddy `json:"roster"` @@ -43,7 +43,7 @@ func NewAccount(jid *xmppbase.JID, password string) *Account { return nil } return &Account{ - Node: jid.Node, + Local: jid.Local, Domain: &Domain{ FQDN: jid.Domain, }, @@ -54,7 +54,7 @@ func NewAccount(jid *xmppbase.JID, password string) *Account { func (a *Account) GetJID() *xmppbase.JID { return &xmppbase.JID{ Domain: a.Domain.FQDN, - Node: a.Node, + Local: a.Local, } } diff --git a/server/toclient/connect.go b/server/toclient/connect.go index 675c99f..955e5ce 100644 --- a/server/toclient/connect.go +++ b/server/toclient/connect.go @@ -76,7 +76,7 @@ func (state *TLSStream) Process() state.State { `, xmpp.CreateCookie(), xmpp.NSClient, xmpp.NSStream, - xmpp.NSSASL, xmppiq.NSFeaturesIQRegister) + xmpp.NSSASL, xmppiq.NSFeatureRegister) } else { fmt.Fprintf(state.Client.Conn, ` @@ -134,7 +134,7 @@ func (state *SASLAuth) Process() state.State { } info := strings.Split(string(data), "\x00") // should check that info[1] starts with state.Client.JID - state.Client.JID.Node = info[1] + state.Client.JID.Local = info[1] state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full()) success, err := state.database.Authenticate(state.Client.JID, info[2]) if err != nil { diff --git a/server/toclient/register.go b/server/toclient/register.go index 11b4c7e..f033425 100644 --- a/server/toclient/register.go +++ b/server/toclient/register.go @@ -44,7 +44,7 @@ func (state *RegisterFormRequest) Process() state.State { return state } - if msg.PrivateRegister == nil { + if msg.Register == nil { state.Client.Log.Warn("is no iq register") return nil } @@ -53,7 +53,7 @@ func (state *RegisterFormRequest) Process() state.State { To: state.Client.JID, From: xmppbase.NewJID(state.Client.JID.Domain), ID: msg.ID, - PrivateRegister: &xmppiq.IQPrivateRegister{ + Register: &xmppiq.Register{ Instructions: "Choose a username and password for use with this service.", Username: "", Password: "", @@ -98,22 +98,22 @@ func (state *RegisterRequest) Process() state.State { state.Client.Log.Warn("iq with error: ", msg.Error.Code) return state } - if msg.PrivateRegister == nil { + if msg.Register == nil { state.Client.Log.Warn("is no iq register: ", err) return nil } - state.Client.JID.Node = msg.PrivateRegister.Username + state.Client.JID.Local = msg.Register.Username state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full()) - account := model.NewAccount(state.Client.JID, msg.PrivateRegister.Password) + account := model.NewAccount(state.Client.JID, msg.Register.Password) err = state.database.AddAccount(account) if err != nil { state.Client.Out.Encode(&xmpp.IQClient{ - Type: xmpp.IQTypeResult, - To: state.Client.JID, - From: xmppbase.NewJID(state.Client.JID.Domain), - ID: msg.ID, - PrivateRegister: msg.PrivateRegister, + Type: xmpp.IQTypeResult, + To: state.Client.JID, + From: xmppbase.NewJID(state.Client.JID.Domain), + ID: msg.ID, + Register: msg.Register, Error: &xmpp.ErrorClient{ Code: "409", Type: "cancel", diff --git a/xmpp/base/jid.go b/xmpp/base/jid.go index 4384d04..d1e318e 100644 --- a/xmpp/base/jid.go +++ b/xmpp/base/jid.go @@ -11,9 +11,9 @@ func init() { jidRegex = regexp.MustCompile(`^(?:([^@/<>'\" ]+)@)?([^@/<>'\"]+)(?:/([^<>'\" ][^<>'\"]*))?$`) } -// JID struct +// JID implements RFC6122: XMPP - Address Format type JID struct { - Node string + Local string Domain string Resource string } @@ -28,49 +28,57 @@ func NewJID(jidString string) *JID { jidSplit := jidSplitTmp[0] return &JID{ - Node: jidSplit[1], + Local: jidSplit[1], Domain: jidSplit[2], Resource: jidSplit[3], } } -// Bare get the "bare" jid -func (jid *JID) Bare() string { - if jid == nil { - return "" +// Clone JID struct address/pointer +func (jid *JID) Clone() *JID { + if jid != nil { + return &JID{ + Local: jid.Local, + Domain: jid.Domain, + Resource: jid.Resource, + } } - if jid.Node != "" { - return jid.Node + "@" + jid.Domain - } - return jid.Domain -} - -// IsBare checks if jid has node and domain but no resource -func (jid *JID) IsBare() bool { - return jid != nil && jid.Node != "" && jid.Domain != "" && jid.Resource == "" + return nil } // Full get the "full" jid as string -func (jid *JID) Full() string { +func (jid *JID) Full() *JID { + return jid.Clone() +} + +// Bare get the "bare" jid +func (jid *JID) Bare() *JID { + if jid != nil { + return &JID{ + Local: jid.Local, + Domain: jid.Domain, + } + } + return nil +} + +func (jid *JID) String() string { if jid == nil { return "" } - if jid.Resource != "" { - return jid.Bare() + "/" + jid.Resource + str := jid.Domain + if jid.Local != "" { + str = jid.Local + "@" + str } - return jid.Bare() + if jid.Resource != "" { + str = str + "/" + jid.Resource + } + return str } -// IsFull checks if jid has all three parts of a JID -func (jid *JID) IsFull() bool { - return jid != nil && jid.Node != "" && jid.Domain != "" && jid.Resource != "" -} - -func (jid *JID) String() string { return jid.Bare() } - //MarshalText to bytearray func (jid JID) MarshalText() ([]byte, error) { - return []byte(jid.Full()), nil + return []byte(jid.String()), nil } // UnmarshalText from bytearray @@ -79,7 +87,7 @@ func (jid *JID) UnmarshalText(data []byte) (err error) { if newJID == nil { return errors.New("not a valid jid") } - jid.Node = newJID.Node + jid.Local = newJID.Local jid.Domain = newJID.Domain jid.Resource = newJID.Resource return nil diff --git a/xmpp/base/jid_is.go b/xmpp/base/jid_is.go new file mode 100644 index 0000000..332653d --- /dev/null +++ b/xmpp/base/jid_is.go @@ -0,0 +1,24 @@ +package xmppbase + +// IsDomain checks if jid has only domain but no local and resource +func (jid *JID) IsDomain() bool { + return jid != nil && jid.Local == "" && jid.Domain != "" && jid.Resource == "" +} + +// IsBare checks if jid has local and domain but no resource +func (jid *JID) IsBare() bool { + return jid != nil && jid.Local != "" && jid.Domain != "" && jid.Resource == "" +} + +// IsFull checks if jid has all three parts of a JID +func (jid *JID) IsFull() bool { + return jid != nil && jid.Local != "" && jid.Domain != "" && jid.Resource != "" +} + +// IsEqual to check if two jid has same values +func (a *JID) IsEqual(b *JID) bool { + if a == nil || b == nil { + return false + } + return a.Local == b.Local && a.Domain == b.Domain && a.Resource == b.Resource +} diff --git a/xmpp/base/jid_is_test.go b/xmpp/base/jid_is_test.go new file mode 100644 index 0000000..add69f4 --- /dev/null +++ b/xmpp/base/jid_is_test.go @@ -0,0 +1,123 @@ +package xmppbase + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestJIDIsDomain(t *testing.T) { + assert := assert.New(t) + var jid *JID + assert.False(jid.IsDomain()) + + jid = &JID{} + assert.False(jid.IsDomain()) + + jid = &JID{Local: "a"} + assert.False(jid.IsDomain()) + + jid = &JID{Domain: "a"} + assert.True(jid.IsDomain()) + + jid = &JID{Resource: "a"} + assert.False(jid.IsDomain()) + + jid = &JID{Local: "a", Domain: "b"} + assert.False(jid.IsDomain()) + + jid = &JID{Local: "a", Resource: "b"} + assert.False(jid.IsDomain()) + + jid = &JID{Domain: "a", Resource: "b"} + assert.False(jid.IsDomain()) + + jid = &JID{Local: "a", Domain: "b", Resource: "a"} + assert.False(jid.IsDomain()) +} + +func TestJIDIsBare(t *testing.T) { + assert := assert.New(t) + var jid *JID + assert.False(jid.IsBare()) + + jid = &JID{} + assert.False(jid.IsBare()) + + jid = &JID{Local: "a"} + assert.False(jid.IsBare()) + + jid = &JID{Domain: "a"} + assert.False(jid.IsBare()) + + jid = &JID{Resource: "a"} + assert.False(jid.IsBare()) + + jid = &JID{Local: "a", Domain: "b"} + assert.True(jid.IsBare()) + + jid = &JID{Local: "a", Resource: "b"} + assert.False(jid.IsBare()) + + jid = &JID{Domain: "a", Resource: "b"} + assert.False(jid.IsBare()) + + jid = &JID{Local: "a", Domain: "b", Resource: "a"} + assert.False(jid.IsBare()) +} + +func TestJIDIsFull(t *testing.T) { + assert := assert.New(t) + var jid *JID + assert.False(jid.IsFull()) + + jid = &JID{} + assert.False(jid.IsFull()) + + jid = &JID{Local: "a"} + assert.False(jid.IsFull()) + + jid = &JID{Domain: "a"} + assert.False(jid.IsFull()) + + jid = &JID{Resource: "a"} + assert.False(jid.IsFull()) + + jid = &JID{Local: "a", Domain: "b"} + assert.False(jid.IsFull()) + + jid = &JID{Local: "a", Resource: "b"} + assert.False(jid.IsFull()) + + jid = &JID{Domain: "a", Resource: "b"} + assert.False(jid.IsFull()) + + jid = &JID{Local: "a", Domain: "b", Resource: "a"} + assert.True(jid.IsFull()) +} + +func TestJIDIsEqual(t *testing.T) { + assert := assert.New(t) + + // just one null + var a *JID + b := &JID{} + assert.False(a.IsEqual(b)) + + a = &JID{} + // two empty JID + assert.True(a.IsEqual(b)) + + a.Local = "bot" + b.Local = "bot" + a.Domain = "example.org" + b.Domain = "example.org" + a.Resource = "notebook" + b.Resource = "notebook" + + assert.True(a.IsEqual(b)) + + b.Resource = "mobile" + assert.False(a.IsEqual(b)) + +} diff --git a/xmpp/base/jid_test.go b/xmpp/base/jid_test.go index 9a120c8..a99d28e 100644 --- a/xmpp/base/jid_test.go +++ b/xmpp/base/jid_test.go @@ -13,57 +13,57 @@ func TestNewJID(t *testing.T) { checkList := map[string]*JID{ "juliet@example.com": { - Node: "juliet", + Local: "juliet", Domain: "example.com", }, "juliet@example.com/foo": { - Node: "juliet", + Local: "juliet", Domain: "example.com", Resource: "foo", }, "juliet@example.com/foo bar": { - Node: "juliet", + Local: "juliet", Domain: "example.com", Resource: "foo bar", }, "juliet@example.com/foo@bar": { - Node: "juliet", + Local: "juliet", Domain: "example.com", Resource: "foo@bar", }, "foo\\20bar@example.com": { - Node: "foo\\20bar", + Local: "foo\\20bar", Domain: "example.com", }, "fussball@example.com": { - Node: "fussball", + Local: "fussball", Domain: "example.com", }, "fußball@example.com": { - Node: "fußball", + Local: "fußball", Domain: "example.com", }, "π@example.com": { - Node: "π", + Local: "π", Domain: "example.com", }, "Σ@example.com/foo": { - Node: "Σ", + Local: "Σ", Domain: "example.com", Resource: "foo", }, "σ@example.com/foo": { - Node: "σ", + Local: "σ", Domain: "example.com", Resource: "foo", }, "ς@example.com/foo": { - Node: "ς", + Local: "ς", Domain: "example.com", Resource: "foo", }, "king@example.com/♚": { - Node: "king", + Local: "king", Domain: "example.com", Resource: "♚", }, @@ -97,10 +97,10 @@ func TestNewJID(t *testing.T) { continue } - assert.Equal(jidValid.Node, jid.Node, "the local part was not right detectet:"+jidString) + assert.Equal(jidValid.Local, jid.Local, "the local part was not right detectet:"+jidString) assert.Equal(jidValid.Domain, jid.Domain, "the domain part was not right detectet:"+jidString) assert.Equal(jidValid.Resource, jid.Resource, "the resource part was not right detectet:"+jidString) - assert.Equal(jidValid.Full(), jidString, "the function full of jid did not work") + assert.Equal(jidValid.Full().String(), jidString, "the function full of jid did not work") } else { assert.Nil(jid, "this should not be a valid JID:"+jidString) } @@ -113,11 +113,11 @@ func TestJIDBare(t *testing.T) { checkList := map[string]*JID{ "aaa@example.com": { - Node: "aaa", + Local: "aaa", Domain: "example.com", }, "aab@example.com": { - Node: "aab", + Local: "aab", Domain: "example.com", Resource: "foo", }, @@ -127,10 +127,32 @@ func TestJIDBare(t *testing.T) { }, } for jidValid, jid := range checkList { - jidBase := jid.Bare() + jidBase := jid.Bare().String() assert.Equal(jidValid, jidBase) - } + // check nil value + var jid *JID + assert.Equal("", jid.Bare().String()) +} + +func TestClone(t *testing.T) { + assert := assert.New(t) + + var jid *JID + cloneJID := jid.Clone() + assert.Nil(jid) + assert.Nil(cloneJID) + + originString := "bot@example.org" + + jid = NewJID(originString) + cloneJID = jid.Clone() + cloneJID.Resource = "notebook" + + assert.Equal(originString, jid.String()) + assert.NotEqual(cloneJID.String(), jid.String()) + assert.Equal(cloneJID.Bare().String(), jid.String()) + } func TestMarshal(t *testing.T) { @@ -140,7 +162,7 @@ func TestMarshal(t *testing.T) { err := jid.UnmarshalText([]byte("juliet@example.com/foo")) assert.NoError(err) - assert.Equal(jid.Node, "juliet") + assert.Equal(jid.Local, "juliet") assert.Equal(jid.Domain, "example.com") assert.Equal(jid.Resource, "foo") @@ -149,7 +171,7 @@ func TestMarshal(t *testing.T) { assert.Error(err) jid = &JID{ - Node: "romeo", + Local: "romeo", Domain: "example.com", Resource: "bar", }