Example #1
0
 /**
  * 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);
     }
   }
 }
Example #2
0
 public void initialize(XMPPServer server) {
   super.initialize(server);
   messageStrategy = server.getOfflineMessageStrategy();
   routingTable = server.getRoutingTable();
   sessionManager = server.getSessionManager();
   serverName = server.getServerInfo().getName();
 }
Example #3
0
 /**
  * Forwards the received message to the list of users defined in the property
  * <b>xmpp.forward.admins</b>. The property may include bare JIDs or just usernames separated by
  * commas or white spaces. When using bare JIDs the target user may belong to a remote server.
  *
  * <p>If the property <b>xmpp.forward.admins</b> was not defined then the message will be sent to
  * all the users allowed to enter the admin console.
  *
  * @param packet the message to forward.
  */
 private void sendMessageToAdmins(Message packet) {
   String jids = JiveGlobals.getProperty("xmpp.forward.admins");
   if (jids != null && jids.trim().length() > 0) {
     // Forward the message to the users specified in the "xmpp.forward.admins" property
     StringTokenizer tokenizer = new StringTokenizer(jids, ", ");
     while (tokenizer.hasMoreTokens()) {
       String username = tokenizer.nextToken();
       Message forward = packet.createCopy();
       if (username.contains("@")) {
         // Use the specified bare JID address as the target address
         forward.setTo(username);
       } else {
         forward.setTo(username + "@" + serverName);
       }
       route(forward);
     }
   } else {
     // Forward the message to the users allowed to log into the admin console
     for (JID jid : XMPPServer.getInstance().getAdmins()) {
       Message forward = packet.createCopy();
       forward.setTo(jid);
       route(forward);
     }
   }
 }
Example #4
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;
  }
  /**
   * Adds a message to this message store. Messages will be stored and made available for later
   * delivery.
   *
   * @param message the message to store.
   */
  public void addMessage(Message message) {
    if (message == null) {
      return;
    }
    if (!shouldStoreMessage(message)) {
      return;
    }
    JID recipient = message.getTo();
    String username = recipient.getNode();
    // If the username is null (such as when an anonymous user), don't store.
    if (username == null || !UserManager.getInstance().isRegisteredUser(recipient)) {
      return;
    } else if (!XMPPServer.getInstance()
        .getServerInfo()
        .getXMPPDomain()
        .equals(recipient.getDomain())) {
      // Do not store messages sent to users of remote servers
      return;
    }

    long messageID = SequenceManager.nextID(JiveConstants.OFFLINE);

    // Get the message in XML format.
    String msgXML = message.getElement().asXML();

    Connection con = null;
    PreparedStatement pstmt = null;
    try {
      con = DbConnectionManager.getConnection();
      pstmt = con.prepareStatement(INSERT_OFFLINE);
      pstmt.setString(1, username);
      pstmt.setLong(2, messageID);
      pstmt.setString(3, StringUtils.dateToMillis(new java.util.Date()));
      pstmt.setInt(4, msgXML.length());
      pstmt.setString(5, msgXML);
      pstmt.executeUpdate();
    } catch (Exception e) {
      Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
    } finally {
      DbConnectionManager.closeConnection(pstmt, con);
    }

    // Update the cached size if it exists.
    if (sizeCache.containsKey(username)) {
      int size = sizeCache.get(username);
      size += msgXML.length();
      sizeCache.put(username, size);
    }
  }
 /**
  * Returns the offline message of the specified user with the given creation date. The returned
  * message will NOT be deleted from the database.
  *
  * @param username the username of the user who's message you'd like to receive.
  * @param creationDate the date when the offline message was stored in the database.
  * @return the offline message of the specified user with the given creation stamp.
  */
 public OfflineMessage getMessage(String username, Date creationDate) {
   OfflineMessage message = null;
   Connection con = null;
   PreparedStatement pstmt = null;
   ResultSet rs = null;
   SAXReader xmlReader = null;
   try {
     // Get a sax reader from the pool
     xmlReader = xmlReaders.take();
     con = DbConnectionManager.getConnection();
     pstmt = con.prepareStatement(LOAD_OFFLINE_MESSAGE);
     pstmt.setString(1, username);
     pstmt.setString(2, StringUtils.dateToMillis(creationDate));
     rs = pstmt.executeQuery();
     while (rs.next()) {
       String msgXML = rs.getString(1);
       message =
           new OfflineMessage(
               creationDate, xmlReader.read(new StringReader(msgXML)).getRootElement());
       // Add a delayed delivery (XEP-0203) element to the message.
       Element delay = message.addChildElement("delay", "urn:xmpp:delay");
       delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
       delay.addAttribute("stamp", XMPPDateTimeFormat.format(creationDate));
     }
   } catch (Exception e) {
     Log.error(
         "Error retrieving offline messages of username: "******" creationDate: "
             + creationDate,
         e);
   } finally {
     // Return the sax reader to the pool
     if (xmlReader != null) {
       xmlReaders.add(xmlReader);
     }
     DbConnectionManager.closeConnection(rs, pstmt, con);
   }
   return message;
 }
Example #7
0
 public void initialize(XMPPServer server) {
   super.initialize(server);
   localServer = server;
   userManager = server.getUserManager();
   router = server.getPacketRouter();
 }
 /**
  * Returns the instance of <tt>OfflineMessageStore</tt> being used by the XMPPServer.
  *
  * @return the instance of <tt>OfflineMessageStore</tt> being used by the XMPPServer.
  */
 public static OfflineMessageStore getInstance() {
   return XMPPServer.getInstance().getOfflineMessageStore();
 }
  /**
   * Returns a Collection of all messages in the store for a user. Messages may be deleted after
   * being selected from the database depending on the delete param.
   *
   * @param username the username of the user who's messages you'd like to receive.
   * @param delete true if the offline messages should be deleted.
   * @return An iterator of packets containing all offline messages.
   */
  public Collection<OfflineMessage> getMessages(String username, boolean delete) {
    List<OfflineMessage> messages = new ArrayList<>();
    SAXReader xmlReader = null;
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
      // Get a sax reader from the pool
      xmlReader = xmlReaders.take();
      con = DbConnectionManager.getConnection();
      pstmt = con.prepareStatement(LOAD_OFFLINE);
      pstmt.setString(1, username);
      rs = pstmt.executeQuery();
      while (rs.next()) {
        String msgXML = rs.getString(1);
        Date creationDate = new Date(Long.parseLong(rs.getString(2).trim()));
        OfflineMessage message;
        try {
          message =
              new OfflineMessage(
                  creationDate, xmlReader.read(new StringReader(msgXML)).getRootElement());
        } catch (DocumentException e) {
          // Try again after removing invalid XML chars (e.g. &#12;)
          Matcher matcher = pattern.matcher(msgXML);
          if (matcher.find()) {
            msgXML = matcher.replaceAll("");
          }
          try {
            message =
                new OfflineMessage(
                    creationDate, xmlReader.read(new StringReader(msgXML)).getRootElement());
          } catch (DocumentException de) {
            Log.error("Failed to route packet (offline message): " + msgXML, de);
            continue; // skip and process remaining offline messages
          }
        }

        // if there is already a delay stamp, we shouldn't add another.
        Element delaytest = message.getChildElement("delay", "urn:xmpp:delay");
        if (delaytest == null) {
          // Add a delayed delivery (XEP-0203) element to the message.
          Element delay = message.addChildElement("delay", "urn:xmpp:delay");
          delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
          delay.addAttribute("stamp", XMPPDateTimeFormat.format(creationDate));
        }
        messages.add(message);
      }
      // Check if the offline messages loaded should be deleted, and that there are
      // messages to delete.
      if (delete && !messages.isEmpty()) {
        PreparedStatement pstmt2 = null;
        try {
          pstmt2 = con.prepareStatement(DELETE_OFFLINE);
          pstmt2.setString(1, username);
          pstmt2.executeUpdate();
          removeUsernameFromSizeCache(username);
        } catch (Exception e) {
          Log.error("Error deleting offline messages of username: "******"Error retrieving offline messages of username: " + username, e);
    } finally {
      DbConnectionManager.closeConnection(rs, pstmt, con);
      // Return the sax reader to the pool
      if (xmlReader != null) {
        xmlReaders.add(xmlReader);
      }
    }
    return messages;
  }