/**
   * Adds the new user to others roster.
   *
   * @param newUser the new user
   * @param otherItem the other item
   * @param currentUser the current user
   * @throws ServiceException the service exception
   */
  private static void addNewUserToOthersRoster(
      User newUser, RosterItem otherItem, String currentUser) throws ServiceException {
    otherItem.getJid();
    UserManager userManager = UserManager.getInstance();

    // Is this user registered with our OF server?
    String username = otherItem.getJid().getNode();
    if (username != null
        && username.length() > 0
        && userManager.isRegisteredUser(username)
        && XMPPServer.getInstance()
            .isLocal(XMPPServer.getInstance().createJID(currentUser, null))) {
      try {
        User otherUser = userManager.getUser(username);
        Roster otherRoster = otherUser.getRoster();
        RosterItem oldUserOnOthersRoster =
            otherRoster.getRosterItem(XMPPServer.getInstance().createJID(currentUser, null));

        try {
          if (!oldUserOnOthersRoster.isOnlyShared()) {

            RosterItem justCreated =
                otherRoster.createRosterItem(
                    XMPPServer.getInstance().createJID(newUser.getUsername(), null),
                    oldUserOnOthersRoster.getNickname(),
                    oldUserOnOthersRoster.getGroups(),
                    true,
                    true);
            justCreated.setAskStatus(oldUserOnOthersRoster.getAskStatus());
            justCreated.setRecvStatus(oldUserOnOthersRoster.getRecvStatus());
            justCreated.setSubStatus(oldUserOnOthersRoster.getSubStatus());
            otherRoster.updateRosterItem(justCreated);
          }
        } catch (UserAlreadyExistsException e) {
          throw new ServiceException(
              "Could not create roster item for user ",
              newUser.getUsername(),
              ExceptionType.USER_ALREADY_EXISTS_EXCEPTION,
              Response.Status.CONFLICT,
              e);
        } catch (SharedGroupException e) {
          throw new ServiceException(
              "Could not create roster item, because it is a contact from a shared group",
              newUser.getUsername(),
              ExceptionType.USER_ALREADY_EXISTS_EXCEPTION,
              Response.Status.BAD_REQUEST,
              e);
        }
      } catch (UserNotFoundException e) {
        throw new ServiceException(
            "Could not create roster item for user "
                + newUser.getUsername()
                + "  because it is a contact from a shared group.",
            newUser.getUsername(),
            ExceptionType.USER_NOT_FOUND_EXCEPTION,
            Response.Status.NOT_FOUND,
            e);
      }
    }
  }
示例#2
0
  /**
   * 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;
  }
  /**
   * Copy roster.
   *
   * @param currentUser the current user
   * @param newUser the new user
   * @param currentUserName the current user name
   * @throws ServiceException the service exception
   */
  private static void copyRoster(User currentUser, User newUser, String currentUserName)
      throws ServiceException {
    Roster newRoster = newUser.getRoster();
    Roster currentRoster = currentUser.getRoster();
    for (RosterItem item : currentRoster.getRosterItems()) {
      try {
        List<String> groups = item.getGroups();

        RosterItem justCreated =
            newRoster.createRosterItem(item.getJid(), item.getNickname(), groups, true, true);
        justCreated.setAskStatus(item.getAskStatus());
        justCreated.setRecvStatus(item.getRecvStatus());
        justCreated.setSubStatus(item.getSubStatus());

        for (Group gr : item.getSharedGroups()) {
          justCreated.addSharedGroup(gr);
        }

        for (Group gr : item.getInvisibleSharedGroups()) {
          justCreated.addInvisibleSharedGroup(gr);
        }
        newRoster.updateRosterItem(justCreated);
        addNewUserToOthersRoster(newUser, item, currentUserName);

      } catch (UserAlreadyExistsException e) {
        throw new ServiceException(
            "Could not create roster item for user ",
            newUser.getUsername(),
            ExceptionType.USER_ALREADY_EXISTS_EXCEPTION,
            Response.Status.CONFLICT,
            e);
      } catch (SharedGroupException e) {
        throw new ServiceException(
            "Could not create roster item, because it is a contact from a shared group",
            newUser.getUsername(),
            ExceptionType.USER_ALREADY_EXISTS_EXCEPTION,
            Response.Status.BAD_REQUEST,
            e);
      } catch (UserNotFoundException e) {
        throw new ServiceException(
            "Could not update roster item for user "
                + newUser.getUsername()
                + " because it was not properly created.",
            newUser.getUsername(),
            ExceptionType.USER_NOT_FOUND_EXCEPTION,
            Response.Status.NOT_FOUND,
            e);
      }
    }
  }
 /**
  * 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) {
         // Do not create a roster item when processing a confirmation of
         // an unsubscription or receiving an unsubscription request or a
         // 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();
 }