/** * The packet is a typical 'set' or 'get' update targeted at the server. Notice that the set could * be a roster removal in which case we have to generate a local roster removal update as well as * a new roster removal to send to the the roster item's owner. * * @param packet The packet that triggered this update * @return Either a response to the roster update or null if the packet is corrupt and the session * was closed down */ private IQ manageRoster(org.xmpp.packet.Roster packet) throws UnauthorizedException, UserAlreadyExistsException, SharedGroupException { IQ returnPacket = null; JID sender = packet.getFrom(); IQ.Type type = packet.getType(); try { if ((sender.getNode() == null || !RosterManager.isRosterServiceEnabled() || !userManager.isRegisteredUser(sender.getNode())) && IQ.Type.get == type) { // If anonymous user asks for his roster or roster service is disabled then // return an empty roster IQ reply = IQ.createResultIQ(packet); reply.setChildElement("query", "jabber:iq:roster"); return reply; } if (!localServer.isLocal(sender)) { // Sender belongs to a remote server so discard this IQ request Log.warn("Discarding IQ roster packet of remote user: " + packet); return null; } Roster cachedRoster = userManager.getUser(sender.getNode()).getRoster(); if (IQ.Type.get == type) { returnPacket = cachedRoster.getReset(); returnPacket.setType(IQ.Type.result); returnPacket.setTo(sender); returnPacket.setID(packet.getID()); // Force delivery of the response because we need to trigger // a presence probe from all contacts deliverer.deliver(returnPacket); returnPacket = null; } else if (IQ.Type.set == type) { for (org.xmpp.packet.Roster.Item item : packet.getItems()) { if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.remove) { removeItem(cachedRoster, packet.getFrom(), item); } else { if (cachedRoster.isRosterItem(item.getJID())) { // existing item RosterItem cachedItem = cachedRoster.getRosterItem(item.getJID()); cachedItem.setAsCopyOf(item); cachedRoster.updateRosterItem(cachedItem); } else { // new item cachedRoster.createRosterItem(item); } } } returnPacket = IQ.createResultIQ(packet); } } catch (UserNotFoundException e) { throw new UnauthorizedException(e); } return returnPacket; }
/** * Remove a roster item. At this stage, this is recipient who has received a roster update. We * must check that it is a removal, and if so, remove the roster item based on the sender's id * rather than what is in the item listing itself. * * @param packet The packet suspected of containing a roster removal */ private void removeRosterItem(org.xmpp.packet.Roster packet) throws UnauthorizedException, SharedGroupException { JID recipientJID = packet.getTo(); JID senderJID = packet.getFrom(); try { for (org.xmpp.packet.Roster.Item packetItem : packet.getItems()) { if (packetItem.getSubscription() == org.xmpp.packet.Roster.Subscription.remove) { Roster roster = userManager.getUser(recipientJID.getNode()).getRoster(); RosterItem item = roster.getRosterItem(senderJID); roster.deleteRosterItem(senderJID, true); item.setSubStatus(RosterItem.SUB_REMOVE); item.setSubStatus(RosterItem.SUB_NONE); Packet itemPacket = packet.createCopy(); sessionManager.userBroadcast(recipientJID.getNode(), itemPacket); } } } catch (UserNotFoundException e) { throw new UnauthorizedException(e); } }