Beispiel #1
0
func (s *SessionXmppSuite) Test_WatchStanzas_iq_set_roster_setsExistingRosterItem(c *C) {
	mockIn := &mockConnIOReaderWriter{read: []byte("<client:iq xmlns:client='jabber:client' type='set' to='cde'><query xmlns='jabber:iq:roster'>" +
		"<item jid='*****@*****.**' name='Romeo' subscription='both'>" +
		"<group>Friends</group>" +
		"</item>" +
		"</query></client:iq>")}
	conn := xmpp.NewConn(
		xml.NewDecoder(mockIn),
		mockIn,
		"[email protected]/foo",
	)

	called := 0

	sess := &Session{
		Config: &config.ApplicationConfig{},
		accountConfig: &config.Account{
			Account: "*****@*****.**",
		},
		R:          roster.New(),
		connStatus: DISCONNECTED,
	}
	sess.Conn = conn

	sess.R.AddOrReplace(roster.PeerFrom(xmpp.RosterEntry{Jid: "*****@*****.**", Subscription: "both", Name: "Jill", Group: []string{"Foes"}}, sess.GetConfig()))
	sess.R.AddOrReplace(roster.PeerFrom(xmpp.RosterEntry{Jid: "*****@*****.**", Subscription: "both", Name: "Mo", Group: []string{"Foes"}}, sess.GetConfig()))

	sess.watchStanzas()

	c.Assert(called, Equals, 0)
	c.Assert(sess.R.ToSlice(), DeepEquals, []*roster.Peer{
		roster.PeerFrom(xmpp.RosterEntry{Jid: "*****@*****.**", Subscription: "both", Name: "Jill", Group: []string{"Foes"}}, sess.GetConfig()),
		roster.PeerFrom(xmpp.RosterEntry{Jid: "*****@*****.**", Subscription: "both", Name: "Romeo", Group: []string{"Friends"}}, sess.GetConfig()),
	})
}
Beispiel #2
0
func (s *SessionXmppSuite) Test_WatchStanzas_iq_set_roster_removesRosterItems(c *C) {
	mockIn := &mockConnIOReaderWriter{read: []byte("<client:iq xmlns:client='jabber:client' type='set' to='cde'><query xmlns='jabber:iq:roster'>" +
		"<item jid='*****@*****.**' name='Romeo' subscription='remove'>" +
		"<group>Friends</group>" +
		"</item>" +
		"</query></client:iq>")}
	conn := xmpp.NewConn(
		xml.NewDecoder(mockIn),
		mockIn,
		"[email protected]/foo",
	)

	sess := &Session{
		Config: &config.ApplicationConfig{},
		accountConfig: &config.Account{
			Account: "*****@*****.**",
		},
		R:          roster.New(),
		connStatus: DISCONNECTED,
	}
	sess.Conn = conn

	sess.R.AddOrReplace(roster.PeerFrom(xmpp.RosterEntry{Jid: "*****@*****.**", Subscription: "both", Name: "Mo", Group: []string{"Foes"}}, sess.GetConfig()))
	sess.R.AddOrReplace(roster.PeerFrom(xmpp.RosterEntry{Jid: "*****@*****.**", Subscription: "both", Name: "Jill", Group: []string{"Foes"}}, sess.GetConfig()))
	sess.R.AddOrReplace(roster.PeerFrom(xmpp.RosterEntry{Jid: "*****@*****.**", Subscription: "both", Name: "Mo", Group: []string{"Foes"}}, sess.GetConfig()))

	observer := make(chan interface{}, 1)
	sess.Subscribe(observer)

	sess.watchStanzas()

	c.Assert(sess.R.ToSlice(), DeepEquals, []*roster.Peer{
		roster.PeerFrom(xmpp.RosterEntry{Jid: "*****@*****.**", Subscription: "both", Name: "Jill", Group: []string{"Foes"}}, sess.GetConfig()),
	})

	select {
	case ev := <-observer:
		switch ev.(type) {
		case PeerEvent:
			c.Error("Received peer event")
			return
		default:
			// ignore
		}
	case <-time.After(1 * time.Millisecond):
		return
	}
}
Beispiel #3
0
func peerFrom(entry data.RosterEntry, c *config.Account) *roster.Peer {
	belongsTo := c.ID()
	var nickname string
	p, ok := c.GetPeer(entry.Jid)
	if ok {
		nickname = p.Nickname
	}
	return roster.PeerFrom(entry, belongsTo, nickname)
}
Beispiel #4
0
func peerFrom(entry data.RosterEntry, c *config.Account) *roster.Peer {
	belongsTo := c.ID()

	var nickname string
	var groups []string
	if p, ok := c.GetPeer(entry.Jid); ok {
		nickname = p.Nickname
		groups = p.Groups
	}

	return roster.PeerFrom(entry, belongsTo, nickname, groups)
}
Beispiel #5
0
func (s *Session) requestRoster() bool {
	if !s.IsConnected() {
		return false
	}

	s.info("Fetching roster")

	delim, err := s.Conn.GetRosterDelimiter()
	if err != nil || delim == "" {
		delim = defaultDelimiter
	}
	s.GroupDelimiter = delim

	rosterReply, _, err := s.Conn.RequestRoster()
	if err != nil {
		s.alert("Failed to request roster: " + err.Error())
		return true
	}

	rosterStanza, ok := <-rosterReply
	if !ok {
		//TODO: should we retry the request in such case?
		log.Println("session: roster request cancelled or timedout")
		return true
	}

	rst, err := xmpp.ParseRoster(rosterStanza)
	if err != nil {
		s.alert("Failed to parse roster: " + err.Error())
		return true
	}

	for _, rr := range rst {
		s.R.AddOrMerge(roster.PeerFrom(rr, s.GetConfig().ID()))
	}

	s.rosterReceived()
	s.info("Roster received")

	return true
}
Beispiel #6
0
func (s *Session) receivedIQRosterQuery(stanza *xmpp.ClientIQ) (ret interface{}, ignore bool) {
	// TODO: we should deal with "ask" attributes here

	if len(stanza.From) > 0 && !s.GetConfig().Is(stanza.From) {
		s.warn("Ignoring roster IQ from bad address: " + stanza.From)
		return nil, true
	}
	var rst xmpp.Roster
	if err := xml.NewDecoder(bytes.NewBuffer(stanza.Query)).Decode(&rst); err != nil || len(rst.Item) == 0 {
		s.warn("Failed to parse roster push IQ")
		return nil, false
	}

	for _, entry := range rst.Item {
		if entry.Subscription == "remove" {
			s.R.Remove(entry.Jid)
		} else if s.R.AddOrMerge(roster.PeerFrom(entry, s.GetConfig().ID())) {
			s.iqReceived(entry.Jid)
		}
	}

	return xmpp.EmptyReply{}, false
}