Search in sources :

Example 21 with RosterItem

use of org.jivesoftware.openfire.roster.RosterItem in project Openfire by igniterealtime.

the class IQRosterHandler method manageRoster.

/**
     * 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) {
            returnPacket = IQ.createResultIQ(packet);
            // The <query/> element contains more than one <item/> child element.
            if (packet.getItems().size() > 1) {
                returnPacket.setError(new PacketError(PacketError.Condition.bad_request, PacketError.Type.modify, "Query contains more than one item"));
            } else {
                for (org.xmpp.packet.Roster.Item item : packet.getItems()) {
                    if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.remove) {
                        if (removeItem(cachedRoster, packet.getFrom(), item) == null) {
                            // RFC 6121 2.5.3.  Error Cases: If the value of the 'jid' attribute specifies an item that is not in the roster, then the server MUST return an <item-not-found/> stanza error.
                            returnPacket.setError(PacketError.Condition.item_not_found);
                        }
                    } else {
                        PacketError error = checkGroups(item.getGroups());
                        if (error != null) {
                            returnPacket.setError(error);
                        } 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);
                            }
                        }
                    }
                }
            }
        }
    } catch (UserNotFoundException e) {
        throw new UnauthorizedException(e);
    }
    return returnPacket;
}
Also used : UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) RosterItem(org.jivesoftware.openfire.roster.RosterItem) RosterItem(org.jivesoftware.openfire.roster.RosterItem) JID(org.xmpp.packet.JID) Roster(org.jivesoftware.openfire.roster.Roster) IQ(org.xmpp.packet.IQ) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) PacketError(org.xmpp.packet.PacketError)

Example 22 with RosterItem

use of org.jivesoftware.openfire.roster.RosterItem in project Openfire by igniterealtime.

the class PresenceSubscribeHandler method manageSub.

/**
     * Manage the subscription request. This method updates a user's roster
     * state, storing any changes made, and updating the roster owner if changes
     * occured.
     *
     * @param target    The roster target's jid (the item's jid to be changed)
     * @param isSending True if the request is being sent by the owner
     * @param type      The subscription change type (subscribe, unsubscribe, etc.)
     * @param roster    The Roster that is updated.
     * @return <tt>true</tt> if the subscription state has changed.
     */
private boolean manageSub(JID target, boolean isSending, Presence.Type type, Roster roster) throws UserAlreadyExistsException, SharedGroupException {
    RosterItem item = null;
    RosterItem.AskType oldAsk;
    RosterItem.SubType oldSub = null;
    RosterItem.RecvType oldRecv;
    boolean newItem = false;
    try {
        if (roster.isRosterItem(target)) {
            item = roster.getRosterItem(target);
        } else {
            if (Presence.Type.unsubscribed == type || Presence.Type.unsubscribe == type || Presence.Type.subscribed == type) {
                // subscription approval from an unknown user
                return false;
            }
            item = roster.createRosterItem(target, false, true);
            newItem = true;
        }
        // Get a snapshot of the item state
        oldAsk = item.getAskStatus();
        oldSub = item.getSubStatus();
        oldRecv = item.getRecvStatus();
        // Update the item state based in the received presence type
        updateState(item, type, isSending);
        // Update the roster IF the item state has changed
        if (oldAsk != item.getAskStatus() || oldSub != item.getSubStatus() || oldRecv != item.getRecvStatus()) {
            roster.updateRosterItem(item);
        } else if (newItem) {
            // Do not push items with a state of "None + Pending In"
            if (item.getSubStatus() != RosterItem.SUB_NONE || item.getRecvStatus() != RosterItem.RECV_SUBSCRIBE) {
                roster.broadcast(item, false);
            }
        }
    } catch (UserNotFoundException e) {
        // Should be there because we just checked that it's an item
        Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
    }
    return oldSub != item.getSubStatus();
}
Also used : UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) RosterItem(org.jivesoftware.openfire.roster.RosterItem)

Example 23 with RosterItem

use of org.jivesoftware.openfire.roster.RosterItem in project Openfire by igniterealtime.

the class PresenceUpdateHandler method directedPresenceSent.

/**
     * Notification method sent to this handler when a user has sent a directed
     * presence to an entity. If the sender of the presence is local (to this server)
     * and the target entity does not belong to the user's roster then update the
     * registry of sent directed presences by the user.
     *
     * @param update  the directed Presence sent by the user to an entity.
     * @param handlerJID the JID of the handler that will receive/handle/process the sent packet.
     * @param jid     the receipient specified in the packet to handle.
     */
public void directedPresenceSent(Presence update, JID handlerJID, String jid) {
    if (update.getFrom() == null) {
        return;
    }
    if (localServer.isLocal(update.getFrom())) {
        boolean keepTrack = false;
        String name = update.getFrom().getNode();
        if (name != null && !"".equals(name)) {
            // Keep track of all directed presences if roster service is disabled
            if (!RosterManager.isRosterServiceEnabled()) {
                keepTrack = true;
            } else {
                try {
                    Roster roster = rosterManager.getRoster(name);
                    // If the directed presence was sent to an entity that is not in the user's
                    // roster, keep a registry of this so that when the user goes offline we
                    // will be able to send the unavailable presence to the entity
                    RosterItem rosterItem = null;
                    try {
                        rosterItem = roster.getRosterItem(update.getTo());
                    } catch (UserNotFoundException e) {
                    // Ignore
                    }
                    if (rosterItem == null || RosterItem.SUB_NONE == rosterItem.getSubStatus() || RosterItem.SUB_TO == rosterItem.getSubStatus()) {
                        keepTrack = true;
                    }
                } catch (UserNotFoundException e) {
                    Log.warn("Presence being sent from unknown user " + name, e);
                } catch (PacketException e) {
                    Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
                }
            }
        } else if (update.getFrom().getResource() != null) {
            // Keep always track of anonymous users directed presences
            keepTrack = true;
        }
        if (keepTrack) {
            String sender = update.getFrom().toString();
            Lock lock = CacheFactory.getLock(sender, directedPresencesCache);
            try {
                lock.lock();
                Collection<DirectedPresence> directedPresences = directedPresencesCache.get(sender);
                if (Presence.Type.unavailable.equals(update.getType())) {
                    if (directedPresences != null) {
                        // It's a directed unavailable presence
                        if (routingTable.hasClientRoute(handlerJID)) {
                            // address of the session) so remove the handler from the map
                            for (DirectedPresence directedPresence : directedPresences) {
                                if (directedPresence.getHandler().equals(handlerJID)) {
                                    directedPresences.remove(directedPresence);
                                    break;
                                }
                            }
                        } else {
                            // unavailable presence
                            for (DirectedPresence directedPresence : directedPresences) {
                                if (directedPresence.getHandler().equals(handlerJID)) {
                                    directedPresence.removeReceiver(jid);
                                    if (directedPresence.isEmpty()) {
                                        directedPresences.remove(directedPresence);
                                    }
                                    break;
                                }
                            }
                        }
                        if (directedPresences.isEmpty()) {
                            // Remove the user from the registry since the list of directed
                            // presences is empty
                            directedPresencesCache.remove(sender);
                            localDirectedPresences.remove(sender);
                        } else {
                            directedPresencesCache.put(sender, directedPresences);
                            localDirectedPresences.put(sender, directedPresences);
                        }
                    }
                } else {
                    if (directedPresences == null) {
                        // We are using a set to avoid duplicate jids in case the user
                        // sends several directed presences to the same handler. The Map also
                        // ensures that if the user sends several presences to the same handler
                        // we will have only one entry in the Map
                        directedPresences = new ConcurrentLinkedQueue<>();
                    }
                    // Add the handler to the list of handler that processed the directed
                    // presence sent by the user. This handler will be used to send
                    // the unavailable presence when the user goes offline
                    DirectedPresence affectedDirectedPresence = null;
                    for (DirectedPresence directedPresence : directedPresences) {
                        if (directedPresence.getHandler().equals(handlerJID)) {
                            affectedDirectedPresence = directedPresence;
                            break;
                        }
                    }
                    if (affectedDirectedPresence == null) {
                        affectedDirectedPresence = new DirectedPresence(handlerJID);
                        directedPresences.add(affectedDirectedPresence);
                    }
                    affectedDirectedPresence.addReceiver(jid);
                    directedPresencesCache.put(sender, directedPresences);
                    localDirectedPresences.put(sender, directedPresences);
                }
            } finally {
                lock.unlock();
            }
        }
    }
}
Also used : UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) RosterItem(org.jivesoftware.openfire.roster.RosterItem) Roster(org.jivesoftware.openfire.roster.Roster) PacketException(org.jivesoftware.openfire.PacketException) Lock(java.util.concurrent.locks.Lock)

Example 24 with RosterItem

use of org.jivesoftware.openfire.roster.RosterItem in project Openfire by igniterealtime.

the class IQDiscoItemsHandler method getUserItems.

@Override
public Iterator<Element> getUserItems(String name, JID senderJID) {
    List<Element> answer = new ArrayList<>();
    try {
        User user = UserManager.getInstance().getUser(name);
        RosterItem item = user.getRoster().getRosterItem(senderJID);
        // answer the user's "available resources"
        if (item.getSubStatus() == RosterItem.SUB_FROM || item.getSubStatus() == RosterItem.SUB_BOTH) {
            for (Session session : SessionManager.getInstance().getSessions(name)) {
                Element element = DocumentHelper.createElement("item");
                element.addAttribute("jid", session.getAddress().toString());
                answer.add(element);
            }
        }
        return answer.iterator();
    } catch (UserNotFoundException e) {
        return answer.iterator();
    }
}
Also used : UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) RosterItem(org.jivesoftware.openfire.roster.RosterItem) User(org.jivesoftware.openfire.user.User) DefaultElement(org.dom4j.tree.DefaultElement) Element(org.dom4j.Element) Session(org.jivesoftware.openfire.session.Session)

Example 25 with RosterItem

use of org.jivesoftware.openfire.roster.RosterItem in project Openfire by igniterealtime.

the class OpenfireExporter method exportUsers.

/* (non-Javadoc)
   * @see org.jivesoftware.openfire.plugin.Exporter#exportUsers()
   */
@Override
public Document exportUsers() {
    Log.debug("exportUsers");
    Document document = DocumentHelper.createDocument();
    Element root = document.addElement("Openfire");
    Collection<User> users = userManager.getUsers();
    for (User user : users) {
        Element userElement = root.addElement("User");
        String userName = user.getUsername();
        userElement.addElement("Username").addText(userName);
        try {
            String pw = AuthFactory.getPassword(user.getUsername());
            userElement.addElement("Password").addText(pw);
        } catch (UserNotFoundException e) {
            Log.info("User " + userName + " not found, setting their password to their username");
            userElement.addElement("Password").addText(userName);
        } catch (UnsupportedOperationException e) {
            Log.info("Unable to retrieve " + userName + " password, setting their password to their username");
            userElement.addElement("Password").addText(userName);
        }
        userElement.addElement("Email").addText(user.getEmail() == null ? "" : user.getEmail());
        String name = user.getName();
        userElement.addElement("Name").addText(name == null ? "" : name);
        //creation and modified date are not used as part of the import process but are exported
        //for historical purposes, should they be formatted differently?
        userElement.addElement("CreationDate").addText(String.valueOf(user.getCreationDate().getTime()));
        userElement.addElement("ModifiedDate").addText(String.valueOf(user.getModificationDate().getTime()));
        Element rosterElement = userElement.addElement("Roster");
        Collection<RosterItem> roster = user.getRoster().getRosterItems();
        for (RosterItem ri : roster) {
            Element itemElement = rosterElement.addElement("Item");
            itemElement.addAttribute("jid", ri.getJid().toBareJID());
            itemElement.addAttribute("askstatus", String.valueOf(ri.getAskStatus().getValue()));
            itemElement.addAttribute("recvstatus", String.valueOf(ri.getRecvStatus().getValue()));
            itemElement.addAttribute("substatus", String.valueOf(ri.getSubStatus().getValue()));
            itemElement.addAttribute("name", ri.getNickname());
            List<String> groups = ri.getGroups();
            for (String group : groups) {
                if (group != null && group.trim().length() > 0) {
                    itemElement.addElement("Group").addText(group);
                }
            }
        }
    }
    return document;
}
Also used : UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) RosterItem(org.jivesoftware.openfire.roster.RosterItem) User(org.jivesoftware.openfire.user.User) Element(org.dom4j.Element) Document(org.dom4j.Document)

Aggregations

RosterItem (org.jivesoftware.openfire.roster.RosterItem)37 Roster (org.jivesoftware.openfire.roster.Roster)27 UserNotFoundException (org.jivesoftware.openfire.user.UserNotFoundException)26 JID (org.xmpp.packet.JID)18 UserAlreadyExistsException (org.jivesoftware.openfire.user.UserAlreadyExistsException)11 ArrayList (java.util.ArrayList)10 Element (org.dom4j.Element)8 SharedGroupException (org.jivesoftware.openfire.SharedGroupException)6 User (org.jivesoftware.openfire.user.User)5 StringTokenizer (java.util.StringTokenizer)4 IQ (org.xmpp.packet.IQ)4 StringprepException (gnu.inet.encoding.StringprepException)3 ServiceException (org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException)3 ParseException (java.text.ParseException)2 Email (net.sf.jml.Email)2 DefaultElement (org.dom4j.tree.DefaultElement)2 XMPPServer (org.jivesoftware.openfire.XMPPServer)2 Group (org.jivesoftware.openfire.group.Group)2 PacketRejectedException (org.jivesoftware.openfire.interceptor.PacketRejectedException)2 UserManager (org.jivesoftware.openfire.user.UserManager)2