Commit 6335c1c0 authored by Dave Cridland's avatar Dave Cridland

Tidy XEP-0313 logic cases

* Use Session rather than LocalSession, which allows remote sessions to access
MAM archives if allowed. This is particularly important for the MUC case, but
is useful to do now.
* Add a Result PacketExtension to hold the Forwarded messages.
* Allow access to personal archives for Administrators.
parent 3dfc395c
...@@ -53,7 +53,6 @@ public class Forwarded extends PacketExtension { ...@@ -53,7 +53,6 @@ public class Forwarded extends PacketExtension {
// Set the Full JID as the "from" attribute // Set the Full JID as the "from" attribute
delayInfo.addAttribute("from", delayFrom.toString()); delayInfo.addAttribute("from", delayFrom.toString());
} }
element.add(delayInfo);
} }
element.add(copy); element.add(copy);
} }
......
...@@ -129,11 +129,13 @@ public class JdbcPersistenceManager implements PersistenceManager { ...@@ -129,11 +129,13 @@ public class JdbcPersistenceManager implements PersistenceManager {
+ "ofMessageArchive.toJID, " + "ofMessageArchive.sentDate, " + "ofMessageArchive.stanza, " + "ofMessageArchive.toJID, " + "ofMessageArchive.sentDate, " + "ofMessageArchive.stanza, "
+ "ofMessageArchive.messageID, " + "ofConParticipant.bareJID " + "ofMessageArchive.messageID, " + "ofConParticipant.bareJID "
+ "FROM ofMessageArchive " + "FROM ofMessageArchive "
+ "INNER JOIN ofConParticipant ON ofMessageArchive.conversationID = ofConParticipant.conversationID "; + "INNER JOIN ofConParticipant ON ofMessageArchive.conversationID = ofConParticipant.conversationID "
+ "WHERE ofMessageArchive.stanza != NULL OR ofMessageArchive.body != NULL";
public static final String COUNT_MESSAGES = "SELECT COUNT(DISTINCT ofMessageArchive.messageID) " public static final String COUNT_MESSAGES = "SELECT COUNT(DISTINCT ofMessageArchive.messageID) "
+ "FROM ofMessageArchive " + "FROM ofMessageArchive "
+ "INNER JOIN ofConParticipant ON ofMessageArchive.conversationID = ofConParticipant.conversationID "; + "INNER JOIN ofConParticipant ON ofMessageArchive.conversationID = ofConParticipant.conversationID "
+ "WHERE ofMessageArchive.stanza != NULL OR ofMessageArchive.body != NULL";
public boolean createMessage(ArchivedMessage message) { public boolean createMessage(ArchivedMessage message) {
/* read only */ /* read only */
......
...@@ -7,11 +7,12 @@ import java.util.Date; ...@@ -7,11 +7,12 @@ import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import org.dom4j.*; import org.dom4j.*;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.UnauthorizedException; import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.disco.ServerFeaturesProvider; import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
import org.jivesoftware.openfire.forward.Forwarded; import org.jivesoftware.openfire.forward.Forwarded;
import org.jivesoftware.openfire.handler.IQHandler; import org.jivesoftware.openfire.handler.IQHandler;
import org.jivesoftware.openfire.session.LocalClientSession; import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.XMPPDateTimeFormat; import org.jivesoftware.util.XMPPDateTimeFormat;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -41,7 +42,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements ...@@ -41,7 +42,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
public IQ handleIQ(IQ packet) throws UnauthorizedException { public IQ handleIQ(IQ packet) throws UnauthorizedException {
LocalClientSession session = (LocalClientSession) sessionManager.getSession(packet.getFrom()); Session session = sessionManager.getSession(packet.getFrom());
// If no session was found then answer with an error (if possible) // If no session was found then answer with an error (if possible)
if (session == null) { if (session == null) {
...@@ -53,17 +54,30 @@ abstract class IQQueryHandler extends AbstractIQHandler implements ...@@ -53,17 +54,30 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
} }
if(packet.getType().equals(IQ.Type.get)) { if(packet.getType().equals(IQ.Type.get)) {
sendSupportedFieldsResult(packet, session); return buildSupportedFieldsResult(packet, session);
return null;
} }
// Default to user's own archive // Default to user's own archive
JID archiveJid = packet.getFrom(); JID archiveJid = packet.getTo();
if (archiveJid == null) {
archiveJid = packet.getFrom().asBareJID();
}
Log.debug("Archive requested is {}", archiveJid);
// Now decide the type.
boolean muc = false;
if (!XMPPServer.getInstance().isLocal(archiveJid)) {
Log.debug("Archive is not local (user)");
return buildErrorResponse(packet);
}
JID requestor = packet.getFrom().asBareJID();
Log.debug("Requestor is {} for muc=={}", requestor, muc);
if(packet.getElement().attribute("to") != null) { // Auth checking.
archiveJid = new JID(packet.getElement().attribute("to").getStringValue()); if(!archiveJid.equals(requestor)) { // Not user's own
// Only allow queries to users own archives // ... disallow unless admin.
if(!archiveJid.toBareJID().equals(packet.getFrom().toBareJID())) { if (!XMPPServer.getInstance().getAdmins().contains(requestor)) {
return buildForbiddenResponse(packet); return buildForbiddenResponse(packet);
} }
} }
...@@ -82,11 +96,11 @@ abstract class IQQueryHandler extends AbstractIQHandler implements ...@@ -82,11 +96,11 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
return null; return null;
} }
protected void sendMidQuery(IQ packet, LocalClientSession session) { protected void sendMidQuery(IQ packet, Session session) {
// Default: Do nothing. // Default: Do nothing.
} }
protected abstract void sendEndQuery(IQ packet, LocalClientSession session, QueryRequest queryRequest); protected abstract void sendEndQuery(IQ packet, Session session, QueryRequest queryRequest);
/** /**
* Create error response to send to client * Create error response to send to client
...@@ -161,7 +175,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements ...@@ -161,7 +175,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
* @param packet Received query packet * @param packet Received query packet
* @param session Client session to respond to * @param session Client session to respond to
*/ */
private void sendAcknowledgementResult(IQ packet, LocalClientSession session) { private void sendAcknowledgementResult(IQ packet, Session session) {
IQ result = IQ.createResultIQ(packet); IQ result = IQ.createResultIQ(packet);
session.process(result); session.process(result);
} }
...@@ -171,7 +185,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements ...@@ -171,7 +185,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
* @param session Client session to respond to * @param session Client session to respond to
* @param queryRequest Received query request * @param queryRequest Received query request
*/ */
private void sendFinalMessage(LocalClientSession session, private void sendFinalMessage(Session session,
final QueryRequest queryRequest) { final QueryRequest queryRequest) {
Message finalMessage = new Message(); Message finalMessage = new Message();
...@@ -200,12 +214,18 @@ abstract class IQQueryHandler extends AbstractIQHandler implements ...@@ -200,12 +214,18 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
* @param archivedMessage Message to send to client * @param archivedMessage Message to send to client
* @return * @return
*/ */
private void sendMessageResult(LocalClientSession session, private void sendMessageResult(Session session,
QueryRequest queryRequest, ArchivedMessage archivedMessage) { QueryRequest queryRequest, ArchivedMessage archivedMessage) {
if(archivedMessage.getStanza() == null) { String stanzaText = archivedMessage.getStanza();
// Don't send legacy archived messages (that have no stanza) if(stanzaText == null || stanzaText.equals("")) {
return; // Try creating a fake one from the body.
if (archivedMessage.getBody() != null && !archivedMessage.getBody().equals("")) {
stanzaText = String.format("<message from=\"{}\" to=\"{}\" type=\"chat\"><body>{}</body>", archivedMessage.getWithJid(), archivedMessage.getWithJid(), archivedMessage.getBody());
} else {
// Don't send legacy archived messages (that have no stanza)
return;
}
} }
Message messagePacket = new Message(); Message messagePacket = new Message();
...@@ -214,7 +234,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements ...@@ -214,7 +234,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
Document stanza; Document stanza;
try { try {
stanza = DocumentHelper.parseText(archivedMessage.getStanza()); stanza = DocumentHelper.parseText(stanzaText);
fwd = new Forwarded(stanza.getRootElement(), archivedMessage.getTime(), null); fwd = new Forwarded(stanza.getRootElement(), archivedMessage.getTime(), null);
} catch (DocumentException e) { } catch (DocumentException e) {
Log.error("Failed to parse message stanza.", e); Log.error("Failed to parse message stanza.", e);
...@@ -233,7 +253,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements ...@@ -233,7 +253,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
* @param packet Incoming query (form field request) packet * @param packet Incoming query (form field request) packet
* @param session Session with client * @param session Session with client
*/ */
private void sendSupportedFieldsResult(IQ packet, LocalClientSession session) { private IQ buildSupportedFieldsResult(IQ packet, Session session) {
IQ result = IQ.createResultIQ(packet); IQ result = IQ.createResultIQ(packet);
...@@ -248,7 +268,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements ...@@ -248,7 +268,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
query.add(form.getElement()); query.add(form.getElement());
session.process(result); return result;
} }
@Override @Override
......
...@@ -3,6 +3,7 @@ package com.reucon.openfire.plugin.archive.xep0313; ...@@ -3,6 +3,7 @@ package com.reucon.openfire.plugin.archive.xep0313;
import org.dom4j.*; import org.dom4j.*;
import org.jivesoftware.openfire.handler.IQHandler; import org.jivesoftware.openfire.handler.IQHandler;
import org.jivesoftware.openfire.session.LocalClientSession; import org.jivesoftware.openfire.session.LocalClientSession;
import org.jivesoftware.openfire.session.Session;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.xmpp.packet.IQ; import org.xmpp.packet.IQ;
...@@ -21,12 +22,12 @@ class IQQueryHandler0 extends IQQueryHandler { ...@@ -21,12 +22,12 @@ class IQQueryHandler0 extends IQQueryHandler {
} }
@Override @Override
protected void sendMidQuery(IQ packet, LocalClientSession session) { protected void sendMidQuery(IQ packet, Session session) {
sendAcknowledgementResult(packet, session); sendAcknowledgementResult(packet, session);
} }
@Override @Override
protected void sendEndQuery(IQ packet, LocalClientSession session, QueryRequest queryRequest) { protected void sendEndQuery(IQ packet, Session session, QueryRequest queryRequest) {
sendFinalMessage(session, queryRequest); sendFinalMessage(session, queryRequest);
} }
...@@ -35,7 +36,7 @@ class IQQueryHandler0 extends IQQueryHandler { ...@@ -35,7 +36,7 @@ class IQQueryHandler0 extends IQQueryHandler {
* @param packet Received query packet * @param packet Received query packet
* @param session Client session to respond to * @param session Client session to respond to
*/ */
private void sendAcknowledgementResult(IQ packet, LocalClientSession session) { private void sendAcknowledgementResult(IQ packet, Session session) {
IQ result = IQ.createResultIQ(packet); IQ result = IQ.createResultIQ(packet);
session.process(result); session.process(result);
} }
...@@ -45,7 +46,7 @@ class IQQueryHandler0 extends IQQueryHandler { ...@@ -45,7 +46,7 @@ class IQQueryHandler0 extends IQQueryHandler {
* @param session Client session to respond to * @param session Client session to respond to
* @param queryRequest Received query request * @param queryRequest Received query request
*/ */
private void sendFinalMessage(LocalClientSession session, private void sendFinalMessage(Session session,
final QueryRequest queryRequest) { final QueryRequest queryRequest) {
Message finalMessage = new Message(); Message finalMessage = new Message();
......
...@@ -2,6 +2,7 @@ package com.reucon.openfire.plugin.archive.xep0313; ...@@ -2,6 +2,7 @@ package com.reucon.openfire.plugin.archive.xep0313;
import org.dom4j.*; import org.dom4j.*;
import org.jivesoftware.openfire.session.LocalClientSession; import org.jivesoftware.openfire.session.LocalClientSession;
import org.jivesoftware.openfire.session.Session;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.xmpp.packet.IQ; import org.xmpp.packet.IQ;
...@@ -19,7 +20,7 @@ class IQQueryHandler1 extends IQQueryHandler { ...@@ -19,7 +20,7 @@ class IQQueryHandler1 extends IQQueryHandler {
} }
@Override @Override
protected void sendEndQuery(IQ packet, LocalClientSession session, QueryRequest queryRequest) { protected void sendEndQuery(IQ packet, Session session, QueryRequest queryRequest) {
sendAcknowledgementResult(packet, session, queryRequest); sendAcknowledgementResult(packet, session, queryRequest);
} }
...@@ -28,7 +29,7 @@ class IQQueryHandler1 extends IQQueryHandler { ...@@ -28,7 +29,7 @@ class IQQueryHandler1 extends IQQueryHandler {
* @param packet Received query packet * @param packet Received query packet
* @param session Client session to respond to * @param session Client session to respond to
*/ */
private void sendAcknowledgementResult(IQ packet, LocalClientSession session, QueryRequest queryRequest) { private void sendAcknowledgementResult(IQ packet, Session session, QueryRequest queryRequest) {
IQ result = IQ.createResultIQ(packet); IQ result = IQ.createResultIQ(packet);
Element fin = result.setChildElement("fin", NAMESPACE); Element fin = result.setChildElement("fin", NAMESPACE);
completeFinElement(queryRequest, fin); completeFinElement(queryRequest, fin);
......
package com.reucon.openfire.plugin.archive.xep0313;
import org.jivesoftware.openfire.forward.Forwarded;
import org.xmpp.packet.PacketExtension;
import java.util.Date;
/**
* Created by dwd on 26/07/16.
*/
public final class Result extends PacketExtension {
public Result(Forwarded forwarded, String xmlns, String queryId, String id) {
super("result", xmlns);
element.add(forwarded.getElement());
}
}
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