Commit dcad8ede authored by Holger Bergunde's avatar Holger Bergunde Committed by holger.bergunde

OF-490 added support for jabber:iq:registered in disco#info for spark clients

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@12896 b35dd754-fafc-0310-a699-88a17e54d16e
parent cd126149
package org.jivesoftware.openfire.plugin; package org.jivesoftware.openfire.plugin;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node; import org.dom4j.Node;
import org.dom4j.XPath; import org.dom4j.XPath;
import org.dom4j.tree.DefaultAttribute;
import org.dom4j.tree.DefaultElement;
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.packageProcessor.AbstractRemoteRosterProcessor; import org.jivesoftware.openfire.plugin.packageProcessor.AbstractRemoteRosterProcessor;
import org.jivesoftware.openfire.plugin.packageProcessor.DiscoIQResigteredProcessor;
import org.jivesoftware.openfire.plugin.packageProcessor.ReceiveComponentUpdatesProcessor; import org.jivesoftware.openfire.plugin.packageProcessor.ReceiveComponentUpdatesProcessor;
import org.jivesoftware.openfire.plugin.packageProcessor.SendRosterProcessor; import org.jivesoftware.openfire.plugin.packageProcessor.SendRosterProcessor;
import org.jivesoftware.openfire.roster.RosterManager; import org.jivesoftware.openfire.roster.RosterManager;
...@@ -31,7 +27,6 @@ public class RemotePackageInterceptor implements PacketInterceptor { ...@@ -31,7 +27,6 @@ public class RemotePackageInterceptor implements PacketInterceptor {
private static final Logger Log = LoggerFactory.getLogger(RemoteRosterPlugin.class); private static final Logger Log = LoggerFactory.getLogger(RemoteRosterPlugin.class);
private String _mySubdomain; private String _mySubdomain;
private Map<String, AbstractRemoteRosterProcessor> _packetProcessor = new HashMap<String, AbstractRemoteRosterProcessor>(); private Map<String, AbstractRemoteRosterProcessor> _packetProcessor = new HashMap<String, AbstractRemoteRosterProcessor>();
private Set<String> _registeredJids = new HashSet<String>();
public RemotePackageInterceptor(String initialSubdomain) { public RemotePackageInterceptor(String initialSubdomain) {
...@@ -40,8 +35,10 @@ public class RemotePackageInterceptor implements PacketInterceptor { ...@@ -40,8 +35,10 @@ public class RemotePackageInterceptor implements PacketInterceptor {
RosterManager rosterMananger = server.getRosterManager(); RosterManager rosterMananger = server.getRosterManager();
AbstractRemoteRosterProcessor sendroster = new SendRosterProcessor(rosterMananger, _mySubdomain); AbstractRemoteRosterProcessor sendroster = new SendRosterProcessor(rosterMananger, _mySubdomain);
AbstractRemoteRosterProcessor receiveChanges = new ReceiveComponentUpdatesProcessor(rosterMananger); AbstractRemoteRosterProcessor receiveChanges = new ReceiveComponentUpdatesProcessor(rosterMananger);
AbstractRemoteRosterProcessor iqRegistered = new DiscoIQResigteredProcessor(_mySubdomain);
_packetProcessor.put("sendRoster", sendroster); _packetProcessor.put("sendRoster", sendroster);
_packetProcessor.put("receiveChanges", receiveChanges); _packetProcessor.put("receiveChanges", receiveChanges);
_packetProcessor.put("sparkIQRegistered", iqRegistered);
} }
@Override @Override
...@@ -67,30 +64,14 @@ public class RemotePackageInterceptor implements PacketInterceptor { ...@@ -67,30 +64,14 @@ public class RemotePackageInterceptor implements PacketInterceptor {
// Component sends roster update // Component sends roster update
_packetProcessor.get("receiveChanges").process(packet); _packetProcessor.get("receiveChanges").process(packet);
} }
} else if (myPacket.getType().equals(IQ.Type.set) && myPacket.getTo().toString().equals(_mySubdomain)) { } else if (myPacket.getType().equals(IQ.Type.get)
// user provided register informations to gateway && myPacket.toString().contains("http://jabber.org/protocol/disco#info")
if (packet.toXML().contains("jabber:iq:gateway:register")) { && myPacket.getTo().toString().equals(_mySubdomain)) {
_registeredJids.add(from); //modify the disco#info for spark clients if enabled in admin panel
} else if (findNodesInDocument(myPacket.getChildElement().getDocument(), "//register:remove") _packetProcessor.get("sparkIQRegistered").process(packet);
.size() == 1) {
// TODO: works until the server restarts...:(
_registeredJids.remove(from);
}
} else if (myPacket.getType().equals(IQ.Type.result)
&& myPacket.getFrom().toString().equals(_mySubdomain)) {
// Adds iq:registered to features to indicate, that user is
// registered with gateway
if (_registeredJids.contains(to)) {
Element feature = new DefaultElement("feature");
feature.add(new DefaultAttribute("var", "jabber:iq:registered"));
myPacket.getChildElement().add(feature);
}
} }
} }
} }
} }
/** /**
......
package org.jivesoftware.openfire.plugin.packageProcessor;
import java.util.Timer;
import java.util.TimerTask;
import org.dom4j.Attribute;
import org.dom4j.Element;
import org.dom4j.tree.DefaultAttribute;
import org.dom4j.tree.DefaultElement;
import org.jivesoftware.openfire.interceptor.InterceptorManager;
import org.jivesoftware.openfire.interceptor.PacketInterceptor;
import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.JiveGlobals;
import org.xmpp.packet.IQ;
import org.xmpp.packet.Packet;
public class DiscoIQResigteredProcessor extends AbstractRemoteRosterProcessor {
private boolean _isRegistered = false;
private String _mySubdoman;
public DiscoIQResigteredProcessor(String subdomain) {
_mySubdoman = subdomain;
}
@Override
public void process(Packet packet) throws PacketRejectedException
{
//Check if the jabber:iq:register is enabled in admin panel
boolean isFeatureEnabled = JiveGlobals.getBooleanProperty("plugin.remoteroster.sparkDiscoInfo", false);
if (!isFeatureEnabled)
{
return;
}
String from = packet.getFrom().toString();
String to = packet.getTo().toString();
final InterceptorManager interceptorManager = InterceptorManager.getInstance();
final PacketInterceptor interceptor = new PacketInterceptor() {
@Override
public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed)
throws PacketRejectedException
{
if (!processed && incoming) {
if (packet instanceof IQ) {
IQ iqPacket = (IQ) packet;
String ns = iqPacket.getChildElement().getNamespace().getURI();
if (iqPacket.getType().equals(IQ.Type.result) && ns.equals("jabber:iq:register")
&& iqPacket.getFrom().toString().equals(_mySubdoman)) {
// Check if we are already registered
setRegistered(iqPacket.toString().contains("<registered/>"));
throw new PacketRejectedException();
} else if (iqPacket.getType().equals(IQ.Type.result)
&& ns.equals("http://jabber.org/protocol/disco#info")
&& iqPacket.getFrom().toString().equals(_mySubdoman)) {
// This is the answer of the disco#info from spark
// to our component.
// add the jabber:iq:register feature if we are
// registered
if (isRegistered()) {
Attribute attribut = new DefaultAttribute("var", "jabber:iq:registered");
iqPacket.getChildElement().addElement("feature").add(attribut);
}
}
}
}
}
};
interceptorManager.addInterceptor(interceptor);
IQ askComponent = new IQ();
askComponent.setTo(to);
askComponent.setFrom(from);
askComponent.setType(IQ.Type.get);
Element query = new DefaultElement("query");
query.addNamespace("", "jabber:iq:register");
askComponent.setChildElement(query);
//Remove the package intercepter in 1sec
TimerTask removeInterceptorTask = new TimerTask() {
@Override
public void run()
{
interceptorManager.removeInterceptor(interceptor);
}
};
Timer timer = new Timer();
timer.schedule(removeInterceptorTask, 1000);
//Send the register query to component
dispatchPacket(askComponent);
}
private boolean isRegistered()
{
return _isRegistered;
}
private void setRegistered(boolean bool)
{
_isRegistered = bool;
}
}
...@@ -13,7 +13,7 @@ import org.xmpp.packet.IQ; ...@@ -13,7 +13,7 @@ import org.xmpp.packet.IQ;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
public class ReceiveComponentUpdatesProcessor extends AbstractRemoteRosterProcessor { public class ReceiveComponentUpdatesProcessor extends AbstractRemoteRosterProcessor{
private RosterManager _rosterManager; private RosterManager _rosterManager;
...@@ -37,6 +37,11 @@ public class ReceiveComponentUpdatesProcessor extends AbstractRemoteRosterProces ...@@ -37,6 +37,11 @@ public class ReceiveComponentUpdatesProcessor extends AbstractRemoteRosterProces
roster = _rosterManager.getRoster(username); roster = _rosterManager.getRoster(username);
String jid = n.valueOf("@jid"); String jid = n.valueOf("@jid");
String name = n.valueOf("@name"); String name = n.valueOf("@name");
if (jid.equals(myPacket.getFrom().toString()))
{
//Do not add the component itself to the contact list
break;
}
List<String> grouplist = new ArrayList<String>(); List<String> grouplist = new ArrayList<String>();
List<Node> groupnodes = findNodesInDocument(n.getDocument(), "//roster:group"); List<Node> groupnodes = findNodesInDocument(n.getDocument(), "//roster:group");
for (Node ne : groupnodes) { for (Node ne : groupnodes) {
...@@ -53,5 +58,4 @@ public class ReceiveComponentUpdatesProcessor extends AbstractRemoteRosterProces ...@@ -53,5 +58,4 @@ public class ReceiveComponentUpdatesProcessor extends AbstractRemoteRosterProces
} }
} }
} }
} }
...@@ -15,8 +15,12 @@ ...@@ -15,8 +15,12 @@
boolean save = request.getParameter("save") != null; boolean save = request.getParameter("save") != null;
boolean success = request.getParameter("success") != null; boolean success = request.getParameter("success") != null;
boolean persistentRoster = ParamUtils.getBooleanAttribute(request, "persistentEnabled"); boolean persistentRoster = ParamUtils.getBooleanAttribute(request, "persistentEnabled");
String sparkdiscoParam = request.getParameter("sparkDiscoInfo");
boolean sparkDiscoInfo = sparkdiscoParam == null? false: sparkdiscoParam.equals("true");
String[] componentsEnabled = request.getParameterValues("enabledComponents[]"); String[] componentsEnabled = request.getParameterValues("enabledComponents[]");
Map<String,String> errors = new HashMap<String,String>(); Map<String,String> errors = new HashMap<String,String>();
if (save) { if (save) {
for (String property : JiveGlobals.getPropertyNames("plugin.remoteroster.jids")) { for (String property : JiveGlobals.getPropertyNames("plugin.remoteroster.jids")) {
...@@ -28,6 +32,7 @@ ...@@ -28,6 +32,7 @@
} }
} }
JiveGlobals.setProperty("plugin.remoteroster.persistent", (persistentRoster ? "true" : "false")); JiveGlobals.setProperty("plugin.remoteroster.persistent", (persistentRoster ? "true" : "false"));
JiveGlobals.setProperty("plugin.remoteroster.sparkDiscoInfo", (sparkDiscoInfo ? "true" : "false"));
response.sendRedirect("rr-main.jsp?success=true"); response.sendRedirect("rr-main.jsp?success=true");
return; return;
} }
...@@ -148,6 +153,39 @@ ...@@ -148,6 +153,39 @@
</table> </table>
</div> </div>
<div class="jive-contentBoxHeader">Client specific options</div>
<div class="jive-contentBox">
<table cellpadding="3" cellspacing="0" border="0" width="100%">
<tbody>
<tr valign="top">
<td width="1%" nowrap class="c1">
Spark:
</td>
<td width="99%">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td>
<input type="checkbox" name="sparkDiscoInfo" id="SDI" value="true" <%= JiveGlobals.getBooleanProperty("plugin.remoteroster.sparkDiscoInfo", false) ? "checked=\"checked\"" : "" %> />
</td>
<td><label for="SDI"> Support jabber:iq:registered feature*</label></td>
</tr>
<tr>
<td />
<td align="left" style="font-size:-3;color:grey">*If you use Spark clients within your network, it might be necessary to modify the service discovery packets between Spark and the external component. If you check this RemoteRoster will add the feature "jabber:iq:registered" to the disco#info to indicate that the Client is registered with the external component.</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<input type="submit" name="save" value="Save Settings" /> <input type="submit" name="save" value="Save Settings" />
</form> </form>
......
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