Commit 9237751d authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gaston

Presence and roster packets fixed according to the spec. Required for s2s and...

Presence and roster packets fixed according to the spec. Required for s2s and gateways. (work not finished yet)


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@1386 b35dd754-fafc-0310-a699-88a17e54d16e
parent 954ebad9
......@@ -12,6 +12,7 @@
package org.jivesoftware.messenger;
import org.jivesoftware.messenger.user.User;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Presence;
import org.xmpp.packet.JID;
......@@ -58,10 +59,10 @@ public interface PresenceManager {
/**
* Returns all presences for the user, or <tt>null</tt> if the user is unavailable.
*
* @param user the user.
* @param username the name of the user.
* @return the Presence packets for all the users's connected sessions.
*/
public Collection<Presence> getPresences(User user);
public Collection<Presence> getPresences(String username);
/**
* Probes the presence of the given XMPPAddress and attempts to send it to the given user.
......@@ -91,4 +92,14 @@ public interface PresenceManager {
* database.
*/
public void deleteLastUnavailablePresence(String username);
/**
* Handle a presence probe sent by a remote server. The logic to apply is the following: If
* the remote user is not in the local user's roster with a subscription state of "From", or
* "Both", then return a presence stanza of type "error" in response to the presence probe.
* Otherwise, answer the presence of the local user sessions or the last unavailable presence.
*
* @param packet the received probe presence from a remote server.
*/
void handleProbe(Presence packet) throws UnauthorizedException;
}
\ No newline at end of file
......@@ -35,6 +35,7 @@ public class PresenceRouter extends BasicModule {
private RoutingTable routingTable;
private PresenceUpdateHandler updateHandler;
private PresenceSubscribeHandler subscribeHandler;
private PresenceManager presenceManager;
private SessionManager sessionManager;
/**
......@@ -101,6 +102,10 @@ public class PresenceRouter extends BasicModule {
{
subscribeHandler.process(packet);
}
else if (Presence.Type.probe == type) {
// Handle a presence probe sent by a remote server
presenceManager.handleProbe(packet);
}
else {
// It's an unknown or ERROR type, just deliver it because there's nothing else to do with it
routingTable.getRoute(recipientJID).process(packet);
......@@ -127,6 +132,7 @@ public class PresenceRouter extends BasicModule {
routingTable = server.getRoutingTable();
updateHandler = server.getPresenceUpdateHandler();
subscribeHandler = server.getPresenceSubscribeHandler();
presenceManager = server.getPresenceManager();
sessionManager = server.getSessionManager();
}
}
......@@ -11,18 +11,19 @@
package org.jivesoftware.messenger.handler;
import org.jivesoftware.util.CacheManager;
import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.roster.Roster;
import org.jivesoftware.messenger.roster.RosterItem;
import org.jivesoftware.messenger.user.*;
import org.xmpp.packet.Presence;
import org.xmpp.packet.Packet;
import org.jivesoftware.messenger.user.UserAlreadyExistsException;
import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.util.CacheManager;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence;
import java.util.Hashtable;
import java.util.Map;
......@@ -76,6 +77,7 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand
private RoutingTable routingTable;
private XMPPServer localServer;
private PacketDeliverer deliverer;
private PresenceManager presenceManager;
public PresenceSubscribeHandler() {
super("Presence subscription handler");
......@@ -102,6 +104,12 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand
// then the packet will be delivered based on its recipient and sender.
ChannelHandler handler = routingTable.getRoute(recipientJID);
handler.process(presence.createCopy());
if (getRoster(recipientJID) == null && type == Presence.Type.subscribed) {
// Send the presence of the local user to the remote user. The remote user
// subscribed to the presence of the local user and the local user accepted
presenceManager.probePresence(recipientJID, senderJID);
}
}
catch (NoSuchRouteException e) {
deliverer.deliver(presence.createCopy());
......@@ -378,5 +386,6 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand
localServer = server;
routingTable = server.getRoutingTable();
deliverer = server.getPacketDeliverer();
presenceManager = server.getPresenceManager();
}
}
\ No newline at end of file
......@@ -11,20 +11,28 @@
package org.jivesoftware.messenger.spi;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.roster.Roster;
import org.jivesoftware.messenger.roster.RosterItem;
import org.jivesoftware.messenger.user.User;
import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.util.CacheManager;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.xmpp.component.Component;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence;
import org.xmpp.component.Component;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* Simple in memory implementation of the PresenceManager interface.
......@@ -77,18 +85,62 @@ public class PresenceManagerImpl extends BasicModule implements PresenceManager
return presence;
}
public Collection<Presence> getPresences(User user) {
if (user == null) {
public Collection<Presence> getPresences(String username) {
if (username == null) {
return null;
}
List<Presence> presences = new ArrayList<Presence>();
for (ClientSession session : sessionManager.getSessions(user.getUsername())) {
for (ClientSession session : sessionManager.getSessions(username)) {
presences.add(session.getPresence());
}
return Collections.unmodifiableCollection(presences);
}
public void handleProbe(Presence packet) throws UnauthorizedException {
String username = packet.getTo().getNode();
// Check for a cached roster:
Roster roster = (Roster)CacheManager.getCache("username2roster").get(username);
if (roster == null) {
synchronized(username.intern()) {
roster = (Roster)CacheManager.getCache("username2roster").get(username);
if (roster == null) {
// Not in cache so load a new one:
roster = new Roster(username);
CacheManager.getCache("username2roster").put(username, roster);
}
}
}
try {
RosterItem item = roster.getRosterItem(packet.getFrom());
if (item.getSubStatus() == RosterItem.SUB_FROM
|| item.getSubStatus() == RosterItem.SUB_BOTH) {
probePresence(packet.getFrom(), packet.getTo());
}
else {
PacketError.Condition error = PacketError.Condition.not_authorized;
if ((item.getSubStatus() == RosterItem.SUB_NONE &&
item.getRecvStatus() != RosterItem.RECV_SUBSCRIBE) ||
(item.getSubStatus() == RosterItem.SUB_TO &&
item.getRecvStatus() != RosterItem.RECV_SUBSCRIBE)) {
error = PacketError.Condition.forbidden;
}
Presence presenceToSend = new Presence();
presenceToSend.setError(error);
presenceToSend.setTo(packet.getFrom());
presenceToSend.setFrom(packet.getTo());
deliverer.deliver(presenceToSend);
}
}
catch (UserNotFoundException e) {
Presence presenceToSend = new Presence();
presenceToSend.setError(PacketError.Condition.forbidden);
presenceToSend.setTo(packet.getFrom());
presenceToSend.setFrom(packet.getTo());
deliverer.deliver(presenceToSend);
}
}
public void probePresence(JID prober, JID probee) {
try {
Component component = getPresenceComponent(probee);
......@@ -155,7 +207,13 @@ public class PresenceManagerImpl extends BasicModule implements PresenceManager
String serverDomain = server.getServerInfo().getName();
// Check if the probee may be hosted by this server
if (!probee.getDomain().contains(serverDomain)) {
// TODO Implete when s2s is implemented
// Send the probe presence to the remote server
Presence probePresence = new Presence();
probePresence.setType(Presence.Type.probe);
probePresence.setFrom(prober);
probePresence.setTo(probee.toBareJID());
// Send the probe presence
deliverer.deliver(probePresence);
}
else {
// The probee may be related to a component that has not yet been connected so
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment