Java Code Examples for org.xmpp.packet.JID#getResource()

The following examples show how to use org.xmpp.packet.JID#getResource() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SessionManager.java    From Openfire with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the session responsible for this JID data. The returned Session may have never sent
 * an available presence (thus not have a route) or could be a Session that hasn't
 * authenticated yet (i.e. preAuthenticatedSessions).
 *
 * @param from the sender of the packet.
 * @return the <code>Session</code> associated with the JID.
 */
public ClientSession getSession(JID from) {
    // Return null if the JID is null or belongs to a foreign server. If the server is
    // shutting down then serverName will be null so answer null too in this case.
    if (from == null || serverName == null || !serverName.equals(from.getDomain())) {
        return null;
    }

    // Initially Check preAuthenticated Sessions
    if (from.getResource() != null) {
        ClientSession session = localSessionManager.getPreAuthenticatedSessions().get(from.getResource());
        if (session != null) {
            return session;
        }
    }

    if (from.getResource() == null || from.getNode() == null) {
        return null;
    }

    return routingTable.getClientRoute(from);
}
 
Example 2
Source File: RoutingTableImpl.java    From Openfire with Apache License 2.0 6 votes vote down vote up
/**
 * Returns true if the specified packet must only be route to available client sessions.
 *
 * @param packet the packet to route.
 * @param fromServer true if the packet was created by the server.
 * @return true if the specified packet must only be route to available client sessions.
 */
private boolean routeOnlyAvailable(Packet packet, boolean fromServer) {
    if (fromServer) {
        // Packets created by the server (no matter their FROM value) must always be delivered no
        // matter the available presence of the user
        return false;
    }
    boolean onlyAvailable = true;
    JID from = packet.getFrom();
    boolean hasSender = from != null;
    if (packet instanceof IQ) {
        onlyAvailable = hasSender && !(serverName.equals(from.getDomain()) && from.getResource() == null) &&
                !componentsCache.containsKey(from.getDomain());
    }
    else if (packet instanceof Message || packet instanceof Presence) {
        onlyAvailable = !hasSender ||
                (!serverName.equals(from.toString()) && !componentsCache.containsKey(from.getDomain()));
    }
    return onlyAvailable;
}
 
Example 3
Source File: Node.java    From Openfire with Apache License 2.0 5 votes vote down vote up
/**
 * Returns true if the specified user is allowed to administer the node. Node
 * administrator are allowed to retrieve the node configuration, change the node
 * configuration, purge the node, delete the node and get the node affiliations and
 * subscriptions.
 *
 * @param user the user to check if he is an admin.
 * @return true if the specified user is allowed to administer the node.
 */
public boolean isAdmin(JID user) {
    if (getOwners().contains(user) || getService().isServiceAdmin(user)) {
        return true;
    }
    // Check if we should try again but using the bare JID
    if (user.getResource() != null) {
        user = user.asBareJID();
        return isAdmin(user);
    }
    return false;
}
 
Example 4
Source File: Node.java    From Openfire with Apache License 2.0 5 votes vote down vote up
/**
 * Sends an event notification to the specified subscriber. The event notification may
 * include information about the affected subscriptions.
 *
 * @param subscriberJID the subscriber JID that will get the notification.
 * @param notification the message to send to the subscriber.
 * @param subIDs the list of affected subscription IDs or null when node does not
 *        allow multiple subscriptions.
 */
protected void sendEventNotification(JID subscriberJID, Message notification,
        Collection<String> subIDs) {
    Element headers = null;
    if (subIDs != null) {
        // Notate the event notification with the ID of the affected subscriptions
        headers = notification.addChildElement("headers", "http://jabber.org/protocol/shim");
        for (String subID : subIDs) {
            Element header = headers.addElement("header");
            header.addAttribute("name", "SubID");
            header.setText(subID);
        }
    }
    
    // Verify that the subscriber JID is currently available to receive notification
    // messages. This is required because the message router will deliver packets via 
    // the bare JID if a session for the full JID is not available. The "isActiveRoute"
    // condition below will prevent inadvertent delivery of multiple copies of each
    // event notification to the user, possibly multiple times (e.g. route.all-resources). 
    // (Refer to http://issues.igniterealtime.org/browse/OF-14 for more info.)
    //
    // This approach is informed by the following XEP-0060 implementation guidelines:
    //   12.2 "Intended Recipients for Notifications" - only deliver to subscriber JID
    //   12.4 "Not Routing Events to Offline Storage" - no offline storage for notifications
    //
    // Note however that this may be somewhat in conflict with the following:
    //   12.3 "Presence-Based Delivery of Events" - automatically detect user's presence
    //
    if (subscriberJID.getResource() == null ||
        SessionManager.getInstance().getSession(subscriberJID) != null) {
        getService().sendNotification(this, notification, subscriberJID);
    }

    if (headers != null) {
        // Remove the added child element that includes subscription IDs information
        notification.getElement().remove(headers);
    }
}
 
Example 5
Source File: SessionManager.java    From Openfire with Apache License 2.0 5 votes vote down vote up
/**
 * Sends a message with a given subject and body to one or more user sessions related to the
 * specified address. If address is null or the address's node is null then the message will be
 * sent to all the user sessions. But if the address includes a node but no resource then
 * the message will be sent to all the user sessions of the requeted user (defined by the node).
 * Finally, if the address is a full JID then the message will be sent to the session associated
 * to the full JID. If no session is found then the message is not sent.
 *
 * @param address the address that defines the sessions that will receive the message.
 * @param subject the subject to broadcast.
 * @param body    the body to broadcast.
 */
public void sendServerMessage(JID address, String subject, String body) {
    Message packet = createServerMessage(subject, body);
    if (address == null || address.getNode() == null || !userManager.isRegisteredUser(address)) {
        broadcast(packet);
    }
    else if (address.getResource() == null || address.getResource().length() < 1) {
        userBroadcast(address.getNode(), packet);
    }
    else {
        routingTable.routePacket(address, packet, true);
    }
}
 
Example 6
Source File: Group.java    From Openfire with Apache License 2.0 5 votes vote down vote up
/**
 * Returns true if the provided JID belongs to a user that is part of the group.
 *
 * @param user the JID address of the user to check.
 * @return true if the specified user is a group user.
 */
public boolean isUser(JID user) {
    // Make sure that we are always checking bare JIDs
    if (user != null && user.getResource() != null) {
        user = user.asBareJID();
    }
    return user != null && (members.contains(user) || administrators.contains(user));
}
 
Example 7
Source File: GroupJID.java    From Openfire with Apache License 2.0 5 votes vote down vote up
@Override
public int compareTo(JID jid) {
    // Comparison order is domain, node, resource.
    int compare = getDomain().compareTo(jid.getDomain());
    if (compare == 0) {
        String otherNode = jid.getNode();
        compare = otherNode == null ? 1 : getGroupName().compareTo(otherNode);
    }
    if (compare == 0) {
        compare = jid.getResource() == null ? 0 : -1;
    }
    return compare;
}
 
Example 8
Source File: GroupJID.java    From Openfire with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a JID from the given JID. If the JID represents a group,
 * returns an instance of this class. Otherwise returns the given JID.
 *
 * @param jid A JID, possibly representing a group
 * @return A new GroupJID if the given JID represents a group, or the given JID
 */
public static JID fromJID(JID jid) {
    if (jid instanceof GroupJID || jid.getResource() == null || jid.getNode() == null) {
        return jid;
    } else {
        return (isGroup(jid)) ? new GroupJID(jid) : jid;
    }
}
 
Example 9
Source File: RoutingTableImpl.java    From Openfire with Apache License 2.0 5 votes vote down vote up
@Override
public boolean isAnonymousRoute(JID jid) {
    if ( jid.getResource() != null ) {
        // Check if there's a anonymous route for the JID.
        return anonymousUsersCache.containsKey( jid.toString() );
    } else {
        // Anonymous routes are mapped by full JID. if there's no full JID, check for any route for the node-part.
        return anonymousUsersCache.keySet().stream().anyMatch( key -> key.startsWith( jid.toString() ) );
    }
}
 
Example 10
Source File: SocketPacketWriteHandler.java    From Openfire with Apache License 2.0 5 votes vote down vote up
@Override
 public void process(Packet packet) throws UnauthorizedException, PacketException {
    try {
        JID recipient = packet.getTo();
        // Check if the target domain belongs to a remote server or a component
        if (server.matchesComponent(recipient) || server.isRemote(recipient)) {
            routingTable.routePacket(recipient, packet, false);
        }
        // The target domain belongs to the local server
        else if (recipient == null || (recipient.getNode() == null && recipient.getResource() == null)) {
            // no TO was found so send back the packet to the sender
            routingTable.routePacket(packet.getFrom(), packet, false);
        }
        else if (recipient.getResource() != null || !(packet instanceof Presence)) {
            // JID is of the form <user@domain/resource>
            routingTable.routePacket(recipient, packet, false);
        }
        else {
            // JID is of the form <user@domain>
            for (JID route : routingTable.getRoutes(recipient, null)) {
                routingTable.routePacket(route, packet, false);
            }
        }
    }
    catch (Exception e) {
        Log.error(LocaleUtils.getLocalizedString("admin.error.deliver") + "\n" + packet.toString(), e);
    }
}
 
Example 11
Source File: InternalComponentManager.java    From Openfire with Apache License 2.0 5 votes vote down vote up
/**
 * Returns true if a component is associated to the specified address. Components
 * registered with this JVM or other cluster nodes are going to be considered.
 *
 * @param componentJID the address of the component. This is the complete domain.
 * @return true if a component is associated to the specified address.
 */
public boolean hasComponent(JID componentJID) {
    synchronized (routables) {
        if (componentJID.getNode() != null || componentJID.getResource() != null) {
            return false;
        }
//        if (componentJID.getDomain().lastIndexOf("." + serverDomain) == -1) {
//            componentJID = new JID(componentJID.getDomain() + "." + serverDomain);
//        }
        return routingTable.hasComponentRoute(componentJID);
    }
}
 
Example 12
Source File: MessageRouter.java    From Openfire with Apache License 2.0 4 votes vote down vote up
/**
 * Notification message indicating that a packet has failed to be routed to the recipient.
 *
 * @param recipient address of the entity that failed to receive the packet.
 * @param packet    Message packet that failed to be sent to the recipient.
 */
public void routingFailed( JID recipient, Packet packet )
{
    log.debug( "Message sent to unreachable address: " + packet.toXML() );
    final Message msg = (Message) packet;

    if ( msg.getType().equals( Message.Type.chat ) && serverName.equals( recipient.getDomain() ) && recipient.getResource() != null ) {
        // Find an existing AVAILABLE session with non-negative priority.
        for (JID address : routingTable.getRoutes(recipient.asBareJID(), packet.getFrom())) {
            ClientSession session = routingTable.getClientRoute(address);
            if (session != null && session.isInitialized()) {
                if (session.getPresence().getPriority() >= 0) {
                    // If message was sent to an unavailable full JID of a user then retry using the bare JID.
                    routingTable.routePacket( recipient.asBareJID(), packet, false );
                    return;
                }
            }
        }
    }

    if ( serverName.equals( recipient.getDomain() ) )
    {
        // Delegate to offline message strategy, which will either bounce or ignore the message depending on user settings.
        log.trace( "Delegating to offline message strategy." );
        messageStrategy.storeOffline( (Message) packet );
    }
    else
    {
        // Recipient is not a local user. Bounce the message.
        // Note: this is similar, but not equal, to handling of message handling to local users in OfflineMessageStrategy.

        // 8.5.2.  localpart@domainpart
        // 8.5.2.2.  No Available or Connected Resources
        if (recipient.getResource() == null) {
            if (msg.getType() == Message.Type.headline || msg.getType() == Message.Type.error) {
                // For a message stanza of type "headline" or "error", the server MUST silently ignore the message.
                log.trace( "Not bouncing a message stanza to a bare JID of non-local user, of type {}", msg.getType() );
                return;
            }
        } else {
            // 8.5.3.  localpart@domainpart/resourcepart
            // 8.5.3.2.1.  Message

            // For a message stanza of type "error", the server MUST silently ignore the stanza.
            if (msg.getType() == Message.Type.error) {
                log.trace( "Not bouncing a message stanza to a full JID of non-local user, of type {}", msg.getType() );
                return;
            }
        }

        bounce( msg );
    }
}
 
Example 13
Source File: RoutingTableImpl.java    From Openfire with Apache License 2.0 4 votes vote down vote up
/**
 * Routes packets that are sent to the XMPP domain itself (excluding subdomains).
 * 
 * @param jid
 *            the recipient of the packet to route.
 * @param packet
 *            the packet to route.
 * @param fromServer
 *            true if the packet was created by the server. This packets
 *            should always be delivered
 * @throws PacketException
 *             thrown if the packet is malformed (results in the sender's
 *             session being shutdown).
 * @return {@code true} if the packet was routed successfully,
 *         {@code false} otherwise.
 */
private boolean routeToLocalDomain(JID jid, Packet packet,
        boolean fromServer) {
    boolean routed = false;
    Element privateElement = packet.getElement().element(QName.get("private", Received.NAMESPACE));
    boolean isPrivate = privateElement != null;
    // The receiving server and SHOULD remove the <private/> element before delivering to the recipient.
    packet.getElement().remove(privateElement);

    if (jid.getResource() == null) {
        // Packet sent to a bare JID of a user
        if (packet instanceof Message) {
            // Find best route of local user
            routed = routeToBareJID(jid, (Message) packet, isPrivate);
        }
        else {
            throw new PacketException("Cannot route packet of type IQ or Presence to bare JID: " + packet.toXML());
        }
    }
    else {
        // Packet sent to local user (full JID)
        ClientRoute clientRoute = getClientRouteForLocalUser(jid);
        if (clientRoute != null) {
            if (!clientRoute.isAvailable() && routeOnlyAvailable(packet, fromServer) &&
              !presenceUpdateHandler.hasDirectPresence(packet.getTo(), packet.getFrom())
                    && !PresenceUpdateHandler.isPresenceUpdateReflection( packet )) {
                Log.debug("Unable to route packet. Packet should only be sent to available sessions and the route is not available. {} ", packet.toXML());
                routed = false;
            } else {
                if (localRoutingTable.isLocalRoute(jid)) {
                    if (!isPrivate && packet instanceof Message) {
                        ccMessage(jid, (Message) packet);
                    }

                    // This is a route to a local user hosted in this node
                    try {
                        localRoutingTable.getRoute(jid).process(packet);
                        routed = true;
                    } catch (UnauthorizedException e) {
                        Log.error("Unable to route packet " + packet.toXML(), e);
                    }
                }
                else {
                    // This is a route to a local user hosted in other node
                    if (remotePacketRouter != null) {
                        routed = remotePacketRouter
                                .routePacket(clientRoute.getNodeID().toByteArray(), jid, packet);
                        if (!routed) {
                            removeClientRoute(jid); // drop invalid client route
                        }
                    }
                }
            }
        }
    }
    return routed;
}
 
Example 14
Source File: OfflineMessageStrategy.java    From Openfire with Apache License 2.0 4 votes vote down vote up
public void storeOffline(Message message) {
    if (message != null) {
        // Do nothing if the message was sent to the server itself, an anonymous user or a non-existent user
        // Also ignore message carbons
        JID recipientJID = message.getTo();
        if (recipientJID == null || serverAddress.equals(recipientJID) ||
                recipientJID.getNode() == null ||
                message.getExtension("received", "urn:xmpp:carbons:2") != null ||
                !UserManager.getInstance().isRegisteredUser(recipientJID.getNode())) {
            return;
        }

        // Do not store messages if communication is blocked
        PrivacyList list =
                PrivacyListManager.getInstance().getDefaultPrivacyList(recipientJID.getNode());
        if (list != null && list.shouldBlockPacket(message)) {
            Message result = message.createCopy();
            result.setTo(message.getFrom());
            result.setFrom(message.getTo());
            result.setError(PacketError.Condition.service_unavailable);
            XMPPServer.getInstance().getRoutingTable().routePacket(message.getFrom(), result, true);
            return;
        }

        // 8.5.2.  localpart@domainpart
        // 8.5.2.2.  No Available or Connected Resources
        if (recipientJID.getResource() == null) {
            if (message.getType() == Message.Type.headline || message.getType() == Message.Type.error) {
                // For a message stanza of type "headline" or "error", the server MUST silently ignore the message.
                return;
            }
            // // For a message stanza of type "groupchat", the server MUST return an error to the sender, which SHOULD be <service-unavailable/>.
            else if (message.getType() == Message.Type.groupchat) {
                bounce(message);
                return;
            }
        } else {
            // 8.5.3.  localpart@domainpart/resourcepart
            // 8.5.3.2.1.  Message

            // For a message stanza of type "normal", "groupchat", or "headline", the server MUST either (a) silently ignore the stanza
            // or (b) return an error stanza to the sender, which SHOULD be <service-unavailable/>.
            if (message.getType() == Message.Type.normal || message.getType() == Message.Type.groupchat || message.getType() == Message.Type.headline) {
                // Depending on the OfflineMessageStragey, we may silently ignore or bounce
                if (type == Type.bounce) {
                    bounce(message);
                }
                // Either bounce or silently ignore, never store such messages
                return;
            }
            // For a message stanza of type "error", the server MUST silently ignore the stanza.
            else if (message.getType() == Message.Type.error) {
                return;
            }
        }

        switch (type) {
        case bounce:
            bounce(message);
            break;
        case store:
            store(message);
            break;
        case store_and_bounce:
            if (underQuota(message)) {
                store(message);
            }
            else {
                Log.debug( "Unable to store, as user is over storage quota. Bouncing message instead: " + message.toXML() );
                bounce(message);
            }
            break;
        case store_and_drop:
            if (underQuota(message)) {
                store(message);
            } else {
                Log.debug( "Unable to store, as user is over storage quota. Silently dropping message: " + message.toXML() );
            }
            break;
        case drop:
            // Drop essentially means silently ignore/do nothing
            break;
        }
    }
}
 
Example 15
Source File: GroupJID.java    From Openfire with Apache License 2.0 2 votes vote down vote up
/**
 * Construct a JID representing a Group from a regular JID. This constructor is
 * private because it is used only from within this class after the source JID
 * has been validated.
 * 
 * @param source A full JID representing a group
 * @see GroupJID#fromString
 */
private GroupJID(JID source) {
    // skip stringprep for the new group JID, since it has already been parsed
    super(source.getNode(), source.getDomain(), source.getResource(), true);
}