Commit 2ade78e7 authored by Dave Cridland's avatar Dave Cridland

Merge pull request #428 from sco0ter/of982

Fix XEP-0012 logic.
parents 49a6d144 1fbab5fe
......@@ -98,7 +98,7 @@ public interface PresenceManager {
* Returns true if the the prober is allowed to see the presence of the probee.
*
* @param prober the user that is trying to probe the presence of another user.
* @param probee the username of the uset that is being probed.
* @param probee the username of the user that is being probed.
* @return true if the the prober is allowed to see the presence of the probee.
* @throws UserNotFoundException If the probee does not exist in the local server or the prober
* is not present in the roster of the probee.
......
......@@ -22,8 +22,6 @@ import org.jivesoftware.openfire.PresenceManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
import org.jivesoftware.openfire.roster.RosterItem;
import org.jivesoftware.openfire.roster.RosterManager;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
......@@ -43,28 +41,29 @@ import java.util.Iterator;
*/
public class IQLastActivityHandler extends IQHandler implements ServerFeaturesProvider {
private IQHandlerInfo info;
private static final String NAMESPACE = "jabber:iq:last";
private final IQHandlerInfo info;
private PresenceManager presenceManager;
private RosterManager rosterManager;
public IQLastActivityHandler() {
super("XMPP Last Activity Handler");
info = new IQHandlerInfo("query", "jabber:iq:last");
info = new IQHandlerInfo("query", NAMESPACE);
}
@Override
public IQ handleIQ(IQ packet) throws UnauthorizedException {
IQ reply = IQ.createResultIQ(packet);
Element lastActivity = reply.setChildElement("query", "jabber:iq:last");
Element lastActivity = reply.setChildElement("query", NAMESPACE);
String sender = packet.getFrom().getNode();
String username = packet.getTo() == null ? null : packet.getTo().getNode();
// Check if any of the usernames is null
if (sender == null) {
reply.setError(PacketError.Condition.forbidden);
return reply;
}
if (username == null) {
if (packet.getTo() != null && packet.getTo().getNode() == null && XMPPServer.getInstance().isLocal(packet.getTo())) {
// http://xmpp.org/extensions/xep-0012.html#server
// When the last activity query is sent to a server or component (i.e., to a JID of the form <domain.tld>),
// the information contained in the IQ reply reflects the uptime of the JID sending the reply.
......@@ -75,34 +74,36 @@ public class IQLastActivityHandler extends IQHandler implements ServerFeaturesPr
return reply;
}
// If the 'to' attribute is null, treat the IQ on behalf of the account from which received the stanza
// in accordance with RFC 6120 § 10.3.3.
String username = packet.getTo() == null ? packet.getFrom().getNode() : packet.getTo().getNode();
try {
RosterItem item = rosterManager.getRoster(username).getRosterItem(packet.getFrom());
// Check that the user requesting this information is subscribed to the user's presence
if (item.getSubStatus() == RosterItem.SUB_FROM ||
item.getSubStatus() == RosterItem.SUB_BOTH) {
if (sessionManager.getSessions(username).isEmpty()) {
User user = UserManager.getInstance().getUser(username);
// The user is offline so answer the user's "last available time and the
// status message of the last unavailable presence received from the user"
long lastActivityTime = presenceManager.getLastActivity(user);
if (lastActivityTime > -1) {
// Convert it to seconds
lastActivityTime = lastActivityTime / 1000;
if (username != null) {
// Check that the user requesting this information is subscribed to the user's presence
if (presenceManager.canProbePresence(packet.getFrom(), username)) {
if (sessionManager.getSessions(username).isEmpty()) {
User user = UserManager.getInstance().getUser(username);
// The user is offline so answer the user's "last available time and the
// status message of the last unavailable presence received from the user"
long lastActivityTime = presenceManager.getLastActivity(user);
if (lastActivityTime > -1) {
// Convert it to seconds
lastActivityTime = lastActivityTime / 1000;
}
lastActivity.addAttribute("seconds", String.valueOf(lastActivityTime));
String lastStatus = presenceManager.getLastPresenceStatus(user);
if (lastStatus != null && lastStatus.length() > 0) {
lastActivity.setText(lastStatus);
}
} else {
// The user is online so answer seconds=0
lastActivity.addAttribute("seconds", "0");
}
lastActivity.addAttribute("seconds", String.valueOf(lastActivityTime));
String lastStatus = presenceManager.getLastPresenceStatus(user);
if (lastStatus != null && lastStatus.length() > 0) {
lastActivity.setText(lastStatus);
}
}
else {
// The user is online so answer seconds=0
lastActivity.addAttribute("seconds", "0");
} else {
reply.setError(PacketError.Condition.forbidden);
}
}
else {
reply.setError(PacketError.Condition.forbidden);
}
}
catch (UserNotFoundException e) {
reply.setError(PacketError.Condition.forbidden);
......@@ -117,13 +118,12 @@ public class IQLastActivityHandler extends IQHandler implements ServerFeaturesPr
@Override
public Iterator<String> getFeatures() {
return Collections.singleton("jabber:iq:last").iterator();
return Collections.singleton(NAMESPACE).iterator();
}
@Override
public void initialize(XMPPServer server) {
super.initialize(server);
presenceManager = server.getPresenceManager();
rosterManager = server.getRosterManager();
}
}
\ No newline at end of file
......@@ -337,6 +337,9 @@ public class PresenceManagerImpl extends BasicModule implements PresenceManager,
@Override
public boolean canProbePresence(JID prober, String probee) throws UserNotFoundException {
if (probee.equals(prober.getNode()) && XMPPServer.getInstance().isLocal(prober)) {
return true;
}
RosterItem item = rosterManager.getRoster(probee).getRosterItem(prober);
return item.getSubStatus() == RosterItem.SUB_FROM
|| item.getSubStatus() == RosterItem.SUB_BOTH;
......
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