/** * Remove the roster item from the sender's roster (and possibly the recipient's). Actual roster * removal is done in the removeItem(Roster,RosterItem) method. * * @param roster The sender's roster. * @param sender The JID of the sender of the removal request * @param item The removal item element */ private void removeItem( org.jivesoftware.openfire.roster.Roster roster, JID sender, org.xmpp.packet.Roster.Item item) throws SharedGroupException { JID recipient = item.getJID(); // Remove recipient from the sender's roster roster.deleteRosterItem(item.getJID(), true); // Forward set packet to the subscriber if (localServer.isLocal(recipient)) { // Recipient is local so let's handle it here try { Roster recipientRoster = userManager.getUser(recipient.getNode()).getRoster(); recipientRoster.deleteRosterItem(sender, true); } catch (UserNotFoundException e) { // Do nothing } } else { // Recipient is remote so we just forward the packet to them String serverDomain = localServer.getServerInfo().getXMPPDomain(); // Check if the recipient may be hosted by this server if (!recipient.getDomain().contains(serverDomain)) { // TODO Implete when s2s is implemented } else { Packet removePacket = createRemoveForward(sender, recipient); router.route(removePacket); } } }
/** * 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; }
private static RosterItem.AskType getAskStatus(org.xmpp.packet.Roster.Item item) { if (item.getAsk() == org.xmpp.packet.Roster.Ask.subscribe) { return RosterItem.ASK_SUBSCRIBE; } else if (item.getAsk() == org.xmpp.packet.Roster.Ask.unsubscribe) { return RosterItem.ASK_UNSUBSCRIBE; } else { return RosterItem.ASK_NONE; } }
/** * Create a roster item from the data in another one. * * @param item Item that contains the info of the roster item. */ public RosterItem(org.xmpp.packet.Roster.Item item) { this( item.getJID(), getSubType(item), getAskStatus(item), RosterItem.RECV_NONE, item.getName(), new LinkedList<String>(item.getGroups())); }
private static RosterItem.SubType getSubType(org.xmpp.packet.Roster.Item item) { if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.to) { return RosterItem.SUB_TO; } else if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.from) { return RosterItem.SUB_FROM; } else if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.both) { return RosterItem.SUB_BOTH; } else if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.remove) { return RosterItem.SUB_REMOVE; } else { return RosterItem.SUB_NONE; } }
/** * 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); } }
/** * Update the cached item as a copy of the given item. * * <p> * * <p>A convenience for getting the item and setting each attribute. * * @param item The item who's settings will be copied into the cached copy * @throws org.jivesoftware.openfire.SharedGroupException if trying to remove shared group. */ public void setAsCopyOf(org.xmpp.packet.Roster.Item item) throws SharedGroupException { setGroups(new LinkedList<String>(item.getGroups())); setNickname(item.getName()); }