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 {
// Set the Full JID as the "from" attribute
delayInfo.addAttribute("from", delayFrom.toString());
}
element.add(delayInfo);
}
element.add(copy);
}
......
......@@ -129,11 +129,13 @@ public class JdbcPersistenceManager implements PersistenceManager {
+ "ofMessageArchive.toJID, " + "ofMessageArchive.sentDate, " + "ofMessageArchive.stanza, "
+ "ofMessageArchive.messageID, " + "ofConParticipant.bareJID "
+ "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) "
+ "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) {
/* read only */
......
......@@ -7,11 +7,12 @@ import java.util.Date;
import java.util.Iterator;
import org.dom4j.*;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
import org.jivesoftware.openfire.forward.Forwarded;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -41,7 +42,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
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 (session == null) {
......@@ -53,17 +54,30 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
}
if(packet.getType().equals(IQ.Type.get)) {
sendSupportedFieldsResult(packet, session);
return null;
return buildSupportedFieldsResult(packet, session);
}
// 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) {
archiveJid = new JID(packet.getElement().attribute("to").getStringValue());
// Only allow queries to users own archives
if(!archiveJid.toBareJID().equals(packet.getFrom().toBareJID())) {
// Auth checking.
if(!archiveJid.equals(requestor)) { // Not user's own
// ... disallow unless admin.
if (!XMPPServer.getInstance().getAdmins().contains(requestor)) {
return buildForbiddenResponse(packet);
}
}
......@@ -82,11 +96,11 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
return null;
}
protected void sendMidQuery(IQ packet, LocalClientSession session) {
protected void sendMidQuery(IQ packet, Session session) {
// 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
......@@ -161,7 +175,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
* @param packet Received query packet
* @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);
session.process(result);
}
......@@ -171,7 +185,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
* @param session Client session to respond to
* @param queryRequest Received query request
*/
private void sendFinalMessage(LocalClientSession session,
private void sendFinalMessage(Session session,
final QueryRequest queryRequest) {
Message finalMessage = new Message();
......@@ -200,12 +214,18 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
* @param archivedMessage Message to send to client
* @return
*/
private void sendMessageResult(LocalClientSession session,
private void sendMessageResult(Session session,
QueryRequest queryRequest, ArchivedMessage archivedMessage) {
if(archivedMessage.getStanza() == null) {
// Don't send legacy archived messages (that have no stanza)
return;
String stanzaText = archivedMessage.getStanza();
if(stanzaText == null || stanzaText.equals("")) {
// 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();
......@@ -214,7 +234,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
Document stanza;
try {
stanza = DocumentHelper.parseText(archivedMessage.getStanza());
stanza = DocumentHelper.parseText(stanzaText);
fwd = new Forwarded(stanza.getRootElement(), archivedMessage.getTime(), null);
} catch (DocumentException e) {
Log.error("Failed to parse message stanza.", e);
......@@ -233,7 +253,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
* @param packet Incoming query (form field request) packet
* @param session Session with client
*/
private void sendSupportedFieldsResult(IQ packet, LocalClientSession session) {
private IQ buildSupportedFieldsResult(IQ packet, Session session) {
IQ result = IQ.createResultIQ(packet);
......@@ -248,7 +268,7 @@ abstract class IQQueryHandler extends AbstractIQHandler implements
query.add(form.getElement());
session.process(result);
return result;
}
@Override
......
......@@ -3,6 +3,7 @@ package com.reucon.openfire.plugin.archive.xep0313;
import org.dom4j.*;
import org.jivesoftware.openfire.handler.IQHandler;
import org.jivesoftware.openfire.session.LocalClientSession;
import org.jivesoftware.openfire.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.IQ;
......@@ -21,12 +22,12 @@ class IQQueryHandler0 extends IQQueryHandler {
}
@Override
protected void sendMidQuery(IQ packet, LocalClientSession session) {
protected void sendMidQuery(IQ packet, Session session) {
sendAcknowledgementResult(packet, session);
}
@Override
protected void sendEndQuery(IQ packet, LocalClientSession session, QueryRequest queryRequest) {
protected void sendEndQuery(IQ packet, Session session, QueryRequest queryRequest) {
sendFinalMessage(session, queryRequest);
}
......@@ -35,7 +36,7 @@ class IQQueryHandler0 extends IQQueryHandler {
* @param packet Received query packet
* @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);
session.process(result);
}
......@@ -45,7 +46,7 @@ class IQQueryHandler0 extends IQQueryHandler {
* @param session Client session to respond to
* @param queryRequest Received query request
*/
private void sendFinalMessage(LocalClientSession session,
private void sendFinalMessage(Session session,
final QueryRequest queryRequest) {
Message finalMessage = new Message();
......
......@@ -2,6 +2,7 @@ package com.reucon.openfire.plugin.archive.xep0313;
import org.dom4j.*;
import org.jivesoftware.openfire.session.LocalClientSession;
import org.jivesoftware.openfire.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.IQ;
......@@ -19,7 +20,7 @@ class IQQueryHandler1 extends IQQueryHandler {
}
@Override
protected void sendEndQuery(IQ packet, LocalClientSession session, QueryRequest queryRequest) {
protected void sendEndQuery(IQ packet, Session session, QueryRequest queryRequest) {
sendAcknowledgementResult(packet, session, queryRequest);
}
......@@ -28,7 +29,7 @@ class IQQueryHandler1 extends IQQueryHandler {
* @param packet Received query packet
* @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);
Element fin = result.setChildElement("fin", NAMESPACE);
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