コード例 #1
0
  /**
   * {@inheritDoc} <br>
   * <br>
   * Performs processing of <em>presence</em> packets and calls different methods for particular
   * {@link PresenceType}
   */
  @SuppressWarnings({"unchecked", "fallthrough"})
  @Override
  public void process(
      final Packet packet,
      final XMPPResourceConnection session,
      final NonAuthUserRepository repo,
      final Queue<Packet> results,
      final Map<String, Object> settings)
      throws XMPPException {
    if (session == null) {
      if (log.isLoggable(Level.FINE)) {
        log.log(Level.FINE, "Session is null, ignoring packet: {0}", packet);
      }

      return;
    } // end of if (session == null)
    if (!session.isAuthorized()) {
      if (log.isLoggable(Level.FINE)) {
        log.log(Level.FINE, "Session is not authorized, ignoring packet: {0}", packet);
      }

      return;
    }

    // Synchronization to avoid conflict with login/logout events
    // processed in the SessionManager asynchronously
    synchronized (session) {
      try {
        RosterAbstract.PresenceType pres_type = roster_util.getPresenceType(session, packet);

        if (pres_type == null) {
          log.log(Level.INFO, "Invalid presence found: {0}", packet);

          return;
        } // end of if (type == null)
        if (log.isLoggable(Level.FINEST)) {
          log.log(
              Level.FINEST,
              "{0} | {1} presence found: {2}",
              new Object[] {session.getBareJID().toString(), pres_type, packet});
        }

        // All 'in' subscription presences must have a valid from address
        switch (pres_type) {
          case in_unsubscribe:
          case in_subscribe:
          case in_unsubscribed:
          case in_subscribed:
            if (packet.getStanzaFrom() == null) {
              if (log.isLoggable(Level.FINE)) {
                log.fine(
                    "'in' subscription presence without valid 'from' address, "
                        + "dropping packet: "
                        + packet);
              }

              return;
            }
            if (session.isUserId(packet.getStanzaFrom().getBareJID())) {
              if (log.isLoggable(Level.FINE)) {
                log.log(
                    Level.FINE,
                    "''in'' subscription to myself, not allowed, returning "
                        + "error for packet: "
                        + "{0}",
                    packet);
              }
              results.offer(
                  Authorization.NOT_ALLOWED.getResponseMessage(
                      packet, "You can not subscribe to yourself.", false));

              return;
            }

            // as per http://xmpp.org/rfcs/rfc6121.html#sub
            // Implementation Note: When a server processes or generates an outbound
            // presence stanza of type "subscribe", "subscribed", "unsubscribe",
            // or "unsubscribed", the server MUST stamp the outgoing presence
            // stanza with the bare JID <localpart@domainpart> of the sending entity,
            // not the full JID <localpart@domainpart/resourcepart>.
            //
            // we enforce this rule also for incomming presence subscirption packets
            packet.initVars(
                packet.getStanzaFrom().copyWithoutResource(),
                session.getJID().copyWithoutResource());

            break;

          case out_subscribe:
          case out_unsubscribe:
          case out_subscribed:
          case out_unsubscribed:

            // Check wheher the destination address is correct to prevent
            // broken/corrupted roster entries:
            if ((packet.getStanzaTo() == null) || packet.getStanzaTo().toString().isEmpty()) {
              results.offer(
                  Authorization.JID_MALFORMED.getResponseMessage(
                      packet, "The destination address is incorrect.", false));

              return;
            }

            // According to RFC 3921 draft bis-3, both source and destination
            // addresses must be BareJIDs, handled by initVars(...)
            packet.initVars(
                session.getJID().copyWithoutResource(), packet.getStanzaTo().copyWithoutResource());

            break;

          default:
            break;
        }
        switch (pres_type) {
          case out_subscribe:
          case out_unsubscribe:
            processOutSubscribe(packet, session, results, settings, pres_type);

            break;

          case out_subscribed:
          case out_unsubscribed:
            processOutSubscribed(packet, session, results, settings, pres_type);

            break;

          case in_subscribe:
            processInSubscribe(packet, session, results, settings, pres_type);

            break;

          case in_unsubscribe:
            processInUnsubscribe(packet, session, results, settings, pres_type);

            break;

          case in_subscribed:
            processInSubscribed(packet, session, results, settings, pres_type);

            break;

          case in_unsubscribed:
            processInUnsubscribed(packet, session, results, settings, pres_type);

            break;

          default:
            results.offer(
                Authorization.BAD_REQUEST.getResponseMessage(
                    packet, "Request type is incorrect", false));

            break;
        } // end of switch (type)
      } catch (NotAuthorizedException e) {
        log.log(
            Level.INFO,
            "Can not access user Roster, user session is not authorized yet: {0}",
            packet);
        log.log(Level.FINEST, "presence problem...", e);
      } catch (TigaseDBException e) {
        log.log(Level.WARNING, "Error accessing database for presence data: {0}", e);
      } // end of try-catch
    }
  }