Commit 7297b4bb authored by Axel Brand's avatar Axel Brand Committed by daeva

Gojara 2.1.3

- Changed registration tracking once again, now properly works with Gajim 0.15
- Push presence when receiving gajim Registration info as gajim does not push presences to transport
- Added option to push available presence to all transport on roster of user so gajim does auto connect on startup.
- minor refactoring & documentation changes

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@13732 b35dd754-fafc-0310-a699-88a17e54d16e
parent 98e8f200
...@@ -43,6 +43,14 @@ ...@@ -43,6 +43,14 @@
<h1> <h1>
GoJara Plugin Changelog GoJara Plugin Changelog
</h1> </h1>
<p><b>2.1.3</b> -- Aug 20, 2013</p>
<ul>
<li>Changed registration tracking once again, now properly works with Gajim 0.15</li>
<li>Push presence when receiving gajim Registration info as gajim does not push presences to transport</li>
<li>Added option to push available presence to all transport on roster of user so gajim does auto connect on startup.</li>
</ul>
<p><b>2.1.2</b> -- Aug 09, 2013</p> <p><b>2.1.2</b> -- Aug 09, 2013</p>
......
...@@ -4,13 +4,19 @@ import java.util.HashMap; ...@@ -4,13 +4,19 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.Node;
import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.interceptor.PacketInterceptor; import org.jivesoftware.openfire.interceptor.PacketInterceptor;
import org.jivesoftware.openfire.interceptor.PacketRejectedException; import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.plugin.gojara.messagefilter.processors.*; import org.jivesoftware.openfire.plugin.gojara.messagefilter.processors.*;
import org.jivesoftware.openfire.plugin.gojara.sessions.GojaraAdminManager; import org.jivesoftware.openfire.plugin.gojara.sessions.GojaraAdminManager;
import org.jivesoftware.openfire.plugin.gojara.sessions.TransportSessionManager; import org.jivesoftware.openfire.plugin.gojara.sessions.TransportSessionManager;
import org.jivesoftware.openfire.plugin.gojara.utils.XpathHelper;
import org.jivesoftware.openfire.roster.RosterManager; import org.jivesoftware.openfire.roster.RosterManager;
import org.jivesoftware.openfire.session.Session; import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.ConcurrentHashSet; import org.jivesoftware.util.ConcurrentHashSet;
...@@ -18,6 +24,7 @@ import org.jivesoftware.util.JiveGlobals; ...@@ -18,6 +24,7 @@ import org.jivesoftware.util.JiveGlobals;
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;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message; import org.xmpp.packet.Message;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
import org.xmpp.packet.Presence; import org.xmpp.packet.Presence;
...@@ -35,14 +42,18 @@ public class MainInterceptor implements PacketInterceptor { ...@@ -35,14 +42,18 @@ public class MainInterceptor implements PacketInterceptor {
private static final Logger Log = LoggerFactory.getLogger(MainInterceptor.class); private static final Logger Log = LoggerFactory.getLogger(MainInterceptor.class);
private Set<String> activeTransports = new ConcurrentHashSet<String>(); private Set<String> activeTransports = new ConcurrentHashSet<String>();
/**
* For referencing the abstract remote Processors
*/
private Map<String, AbstractRemoteRosterProcessor> packetProcessors = new HashMap<String, AbstractRemoteRosterProcessor>(); private Map<String, AbstractRemoteRosterProcessor> packetProcessors = new HashMap<String, AbstractRemoteRosterProcessor>();
private TransportSessionManager tSessionManager = TransportSessionManager.getInstance(); private TransportSessionManager tSessionManager = TransportSessionManager.getInstance();
private GojaraAdminManager gojaraAdminmanager = GojaraAdminManager.getInstance(); private GojaraAdminManager gojaraAdminmanager = GojaraAdminManager.getInstance();
private XMPPServer server;
private Boolean frozen; private Boolean frozen;
public MainInterceptor() { public MainInterceptor() {
Log.info("Created MainInterceptor for GoJara Plugin."); Log.info("Created MainInterceptor for GoJara Plugin.");
XMPPServer server = XMPPServer.getInstance(); server = XMPPServer.getInstance();
RosterManager rosterMananger = server.getRosterManager(); RosterManager rosterMananger = server.getRosterManager();
AbstractRemoteRosterProcessor iqRegisteredProcessor = new DiscoIQRegisteredProcessor(); AbstractRemoteRosterProcessor iqRegisteredProcessor = new DiscoIQRegisteredProcessor();
...@@ -194,36 +205,26 @@ public class MainInterceptor implements PacketInterceptor { ...@@ -194,36 +205,26 @@ public class MainInterceptor implements PacketInterceptor {
Element query = iqPacket.getChildElement(); Element query = iqPacket.getChildElement();
if (query == null) if (query == null)
return; return;
// Okay, so now we have a IQ Packet with a query xmlns: jabber:iq:register /*
// Spark sends registrations and unregistrations in such a query, register has a x xmls * Okay, so now we have a IQ Packet with a query xmlns: jabber:iq:register Spark sends registrations and
// jabber:iq:gateway:register, unregister is just a <remove/> element * unregistrations in such a query, register has a x xmls jabber:iq:gateway:register, unregister is just
// Gajim sends the whole form with x xmlns jabber:x:data type="submit", where a field var=unregister * a <remove/> element Gajim sends the whole form with x xmlns jabber:x:data type="submit", where a
// value of 0 is a registration, and unregister = 1 is unregistration * field var=unregister value of 0 is a registration, and unregister = 1 is unregistration
*/
if (query.getNamespaceURI().equals("jabber:iq:register") && iqPacket.getType().equals(IQ.Type.set)) { if (query.getNamespaceURI().equals("jabber:iq:register") && iqPacket.getType().equals(IQ.Type.set)) {
// spark unregister // spark + gajim unregister
if (query.element("remove") != null) if (query.element("remove") != null)
tSessionManager.removeRegistrationOfUser(to, iqPacket.getFrom().getNode().toString()); tSessionManager.removeRegistrationOfUser(to, iqPacket.getFrom().getNode().toString());
else if (query.element("x") != null) { else if (query.element("x") != null) {
String namespace = query.element("x").getNamespaceURI(); Element xElem = query.element("x");
String xNamespace = xElem.getNamespaceURI();
// spark register // spark register
if (namespace.equals("jabber:iq:gateway:register")) if (xNamespace.equals("jabber:iq:gateway:register"))
tSessionManager.registerUserTo(to, iqPacket.getFrom().getNode().toString()); tSessionManager.registerUserTo(to, iqPacket.getFrom().getNode().toString());
// Gajim packet // Gajim register + presence push
else if (namespace.equals("jabber:x:data")) { else if (xNamespace.equals("jabber:x:data") && xElem.attribute("type").getText().equals("submit")) {
// .... not really nice, but i dont know xpath so idk how to do this else
@SuppressWarnings("rawtypes")
List list = query.element("x").elements("field");
for (Object ele : list) {
Element e = (Element) ele;
if (e.attributeValue("var").equals("unregister")) {
// register form
if (e.elementText("value").equals("0"))
tSessionManager.registerUserTo(to, iqPacket.getFrom().getNode().toString()); tSessionManager.registerUserTo(to, iqPacket.getFrom().getNode().toString());
// unregister form presencePush(packet.getTo(), packet.getFrom(), 150);
else if (e.elementText("value").equals("1"))
tSessionManager.removeRegistrationOfUser(to, iqPacket.getFrom().getNode().toString());
}
}
} }
} }
} }
...@@ -245,13 +246,63 @@ public class MainInterceptor implements PacketInterceptor { ...@@ -245,13 +246,63 @@ public class MainInterceptor implements PacketInterceptor {
&& query.getNamespaceURI().equals("http://jabber.org/protocol/disco#info") && from.length() > 0 && query.getNamespaceURI().equals("http://jabber.org/protocol/disco#info") && from.length() > 0
&& activeTransports.contains(from)) && activeTransports.contains(from))
packetProcessors.get("mucfilterProcessor").process(packet, from, to, from); packetProcessors.get("mucfilterProcessor").process(packet, from, to, from);
// GAJIM presence push when connecting... probably doesnt really belong here but by now we would have
// 50processors for every edge case we handle...
// If roster is persistent and we dont block presences no need to do this since presences are being
// pushed by OF anyways
else if (JiveGlobals.getBooleanProperty("plugin.remoteroster.gajimBroadcast", false)) {
if (to.contains("Gajim") && query.getNamespaceURI().equals("jabber:iq:roster") && iqPacket.getType().equals(IQ.Type.result)) {
List<Node> nodes = XpathHelper.findNodesInDocument(iqPacket.getElement().getDocument(), "//roster:item");
for (Node n : nodes) {
String jid = n.valueOf("@jid");
if (activeTransports.contains(jid)) {
JID pushTo = new JID(jid);
presencePush(pushTo, iqPacket.getTo(), 3000);
}
}
}
}
} else if (packet instanceof Presence) { } else if (packet instanceof Presence) {
// We block Presences to users of a subdomain so OF/S2 wont log you in automatically if you have a /*
// subdomain user in your roster * We block Presences to users of a subdomain (except transport itself) so OF/S2 wont log you in
* automatically if you have a subdomain user in your roster. This prevents some clients from logging
* automatically, as the clients dont send a specific presence to the transport. We could do a presence
* push if we see them come online, but that would do the same as just not intercepting these presences,
* as the problem is really the client
*/
String to_s = searchJIDforSubdomain(to); String to_s = searchJIDforSubdomain(to);
if (to_s.length() > 0 && !activeTransports.contains(to)) if (to_s.length() > 0 && !activeTransports.contains(to))
throw new PacketRejectedException(); throw new PacketRejectedException();
} }
} }
} }
/**
* Just pushes a available presence, we need this for GAJIM Client as it does not push available presence after
* registering We also wait a little so after register transport is on users roster. Really didnt wanted this here
* but doesnt really belong anywhere else
*
* @param to
* @param from
* @param delay MS until the job should be done
*/
private void presencePush(final JID to, final JID from, int delay) {
TimerTask pushPresenceTask = new TimerTask() {
@Override
public void run() {
PacketRouter router = server.getPacketRouter();
Packet presence = new Presence();
presence.setTo(to);
presence.setFrom(from);
router.route(presence);
}
};
Timer timer = new Timer();
timer.schedule(pushPresenceTask, delay);
}
} }
...@@ -30,6 +30,7 @@ abstract public class AbstractRemoteRosterProcessor { ...@@ -30,6 +30,7 @@ abstract public class AbstractRemoteRosterProcessor {
public AbstractRemoteRosterProcessor() { public AbstractRemoteRosterProcessor() {
_server = XMPPServer.getInstance(); _server = XMPPServer.getInstance();
_router = _server.getPacketRouter();
} }
...@@ -51,8 +52,7 @@ abstract public class AbstractRemoteRosterProcessor { ...@@ -51,8 +52,7 @@ abstract public class AbstractRemoteRosterProcessor {
*/ */
protected void dispatchPacket(Packet packet) { protected void dispatchPacket(Packet packet) {
Log.debug("Sending package to PacketRouter: \n" + packet.toString() + "\n"); Log.debug("Sending package to PacketRouter: \n" + packet.toString() + "\n");
PacketRouter router = _server.getPacketRouter(); _router.route(packet);
router.route(packet);
} }
/** /**
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
String mucFilterParam = request.getParameter("mucFilter"); String mucFilterParam = request.getParameter("mucFilter");
boolean mucFilter = mucFilterParam == null ? false : mucFilterParam.equals("true"); boolean mucFilter = mucFilterParam == null ? false : mucFilterParam.equals("true");
String gajimBroadcastParam = request.getParameter("gajimBroadcast");
boolean gajimBroadcast = gajimBroadcastParam == null ? false : gajimBroadcastParam.equals("true");
String[] componentsEnabled = request.getParameterValues("enabledComponents[]"); String[] componentsEnabled = request.getParameterValues("enabledComponents[]");
PermissionManager _pmanager = new PermissionManager(); PermissionManager _pmanager = new PermissionManager();
DatabaseManager _db; DatabaseManager _db;
...@@ -53,6 +56,7 @@ ...@@ -53,6 +56,7 @@
JiveGlobals.setProperty("plugin.remoteroster.sparkDiscoInfo", (sparkDiscoInfo ? "true" : "false")); JiveGlobals.setProperty("plugin.remoteroster.sparkDiscoInfo", (sparkDiscoInfo ? "true" : "false"));
JiveGlobals.setProperty("plugin.remoteroster.iqLastFilter", (iqLastFilter ? "true" : "false")); JiveGlobals.setProperty("plugin.remoteroster.iqLastFilter", (iqLastFilter ? "true" : "false"));
JiveGlobals.setProperty("plugin.remoteroster.mucFilter", (mucFilter ? "true" : "false")); JiveGlobals.setProperty("plugin.remoteroster.mucFilter", (mucFilter ? "true" : "false"));
JiveGlobals.setProperty("plugin.remoteroster.gajimBroadcast", (gajimBroadcast ? "true" : "false"));
response.sendRedirect("rr-main.jsp?success=true"); response.sendRedirect("rr-main.jsp?success=true");
return; return;
} }
...@@ -264,8 +268,6 @@ ...@@ -264,8 +268,6 @@
</div> </div>
<% <%
++i; ++i;
} }
...@@ -299,7 +301,7 @@ ...@@ -299,7 +301,7 @@
<td /> <td />
<td align="left" style="font-size: -3; color: grey">When Persistent-Roster is enabled, contacts will be saved to database and <td align="left" style="font-size: -3; color: grey">When Persistent-Roster is enabled, contacts will be saved to database and
no contacts will be deleted by GoJara automatically.<br> no contacts will be deleted by GoJara automatically.<br>
When Persistent-Roster is disabled, contacts will not be saved to databse and When Persistent-Roster is disabled, contacts will not be saved to database and
GoJara will automatically delete all Legacy-RosterItems from the OF-Roster of a User upon logout. </td> GoJara will automatically delete all Legacy-RosterItems from the OF-Roster of a User upon logout. </td>
</tr> </tr>
<tr> <tr>
...@@ -314,6 +316,7 @@ ...@@ -314,6 +316,7 @@
of some Transports. If this should not be allowed, because only internal Jabber Conferences should be used, GoJara of some Transports. If this should not be allowed, because only internal Jabber Conferences should be used, GoJara
can remove these.</td> can remove these.</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</td> </td>
...@@ -365,6 +368,28 @@ ...@@ -365,6 +368,28 @@
</table> </table>
</td> </td>
</tr> </tr>
<tr valign="top">
<td width="1%" nowrap class="c1">Gajim:</td>
<td width="99%">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td><input type="checkbox" name="gajimBroadcast" id="gajimBroadcast" value="true"
<%=JiveGlobals.getBooleanProperty("plugin.remoteroster.gajimBroadcast", false) ? "checked=\"checked\""
: ""%> />
</td>
<td><label for="gajimBroadcast">Push available presence on startup</label></td>
</tr>
<tr>
<td />
<td align="left" style="font-size: -3; color: grey">Enable this if Gojara should push available presences to
transports from your roster on startup. If disabled, you have to manually send an available presence to the specific
transport to connect to it.</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>
......
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