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

OF-500

Implemented ability to restrict access to external gateways

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@12911 b35dd754-fafc-0310-a699-88a17e54d16e
parent a09d8e1c
......@@ -44,7 +44,7 @@
Remote Roster Plugin Changelog
</h1>
<p><b>1.0</b> -- Oct 16, 2011</p>
<p><b>1.0 Alpha</b> -- Dec 12, 2011</p>
<ul>
<li>Initial release. </li>
......
......@@ -6,9 +6,9 @@
<name>Remote Roster</name>
<description>ProtoXEP-xxxx: Remote Roster Management support</description>
<author>Holger Bergunde & Daniel Henninger</author>
<author>Holger Bergunde and Daniel Henninger</author>
<version>1.0.0 Alpha</version>
<date>12/01/2011</date>
<date>12/06/2011</date>
<minServerVersion>3.7.0</minServerVersion>
<!-- Admin console entries -->
......
package org.jivesoftware.openfire.plugin;
import java.util.Collection;
import org.jivesoftware.openfire.group.Group;
import org.jivesoftware.openfire.group.GroupManager;
import org.jivesoftware.util.JiveGlobals;
import org.xmpp.packet.JID;
public class PermissionManager {
GroupManager _groupManager = GroupManager.getInstance();
public boolean isGatewayLimited(String subdomain)
{
return getGroupForGateway(subdomain).length() > 0;
}
public boolean allowedForUser(String gateway, JID jid)
{
String groupAllowedFor = getGroupForGateway(gateway);
if (groupAllowedFor != null) {
Collection<Group> groups = _groupManager.getGroups(jid);
for (Group gr : groups) {
if (gr.getName().equals(groupAllowedFor))
{
return true;
}
}
}
return false;
}
public String getGroupForGateway(String gateway)
{
return JiveGlobals.getProperty("plugin.remoteroster.permissiongroup."+gateway, "");
}
public void setGroupForGateway(String gateway, String group)
{
JiveGlobals.setProperty("plugin.remoteroster.permissiongroup."+gateway, group);
}
public void removeGatewayLimitation(String gateway)
{
setGroupForGateway(gateway, "");
}
}
......@@ -15,7 +15,8 @@ import org.jivesoftware.openfire.component.ComponentEventListener;
import org.jivesoftware.openfire.component.InternalComponentManager;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.interceptor.InterceptorManager;
import org.jivesoftware.openfire.plugin.interceptor.AbstractInterceptorHandler;
import org.jivesoftware.openfire.plugin.interceptor.GatewayInterceptorHandler;
import org.jivesoftware.openfire.session.ComponentSession;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.PropertyEventDispatcher;
......@@ -29,11 +30,10 @@ public class RemoteRosterPlugin implements Plugin {
private static final Logger Log = LoggerFactory.getLogger(RemoteRosterPlugin.class);
final SessionManager _sessionManager = SessionManager.getInstance();
private Map<String, RemotePackageInterceptor> _interceptors = new HashMap<String, RemotePackageInterceptor>();
private Map<String, AbstractInterceptorHandler> _interceptors = new HashMap<String, AbstractInterceptorHandler>();
private static PluginManager pluginManager;
private Set<String> _waitingForIQResponse = new HashSet<String>();
private InterceptorManager _interceptorManager;
private PropertyEventListener _settingsObserver;
public RemoteRosterPlugin() {
......@@ -42,11 +42,10 @@ public class RemoteRosterPlugin implements Plugin {
public void initializePlugin(PluginManager manager, File pluginDirectory)
{
Log.debug("Starting RemoteRoster Plguin");
Log.debug("Starting RemoteRoster Plugin");
pluginManager = manager;
manageExternalComponents();
listenToSettings();
_interceptorManager = InterceptorManager.getInstance();
}
private void manageExternalComponents()
......@@ -83,17 +82,18 @@ public class RemoteRosterPlugin implements Plugin {
public void componentInfoReceived(IQ iq)
{
String from = iq.getFrom().getDomain();
//Waiting for this external component sending an IQ response to us?
// Waiting for this external component sending an IQ response to
// us?
if (_waitingForIQResponse.contains(from)) {
Element packet = iq.getChildElement();
Document doc = packet.getDocument();
List<Node> nodes = Utils.findNodesInDocument(doc, "//disco:identity[@category='gateway']");
//Is this external component a gateway and there is no package interceptor for it?
if (nodes.size() > 0 && !_interceptors.containsKey(from))
{
// Is this external component a gateway and there is no
// package interceptor for it?
if (nodes.size() > 0 && !_interceptors.containsKey(from)) {
updateInterceptors(from);
}
// We got the IQ, we can now remove it from the set, because
// we are not waiting any more
_waitingForIQResponse.remove(from);
......@@ -102,8 +102,6 @@ public class RemoteRosterPlugin implements Plugin {
});
}
private void listenToSettings()
{
_settingsObserver = new RemoteRosterPropertyListener() {
......@@ -115,38 +113,30 @@ public class RemoteRosterPlugin implements Plugin {
};
PropertyEventDispatcher.addListener(_settingsObserver);
}
public void destroyPlugin()
{
for (String interceptor : _interceptors.keySet())
{
removeInterceptor(interceptor);
for (String key : _interceptors.keySet()) {
_interceptors.get(key).stop();
}
PropertyEventDispatcher.removeListener(_settingsObserver);
pluginManager = null;
_interceptorManager = null;
}
private void updateInterceptors(String componentJID)
{
Log.debug("Updating my package interceptors for component "+componentJID);
boolean allowed = JiveGlobals.getBooleanProperty("plugin.remoteroster.jids."+componentJID, false);
if (allowed)
{
if(!_interceptors.containsKey(componentJID))
{
boolean allowed = JiveGlobals.getBooleanProperty("plugin.remoteroster.jids." + componentJID, false);
if (allowed) {
if (!_interceptors.containsKey(componentJID)) {
createNewPackageIntercetor(componentJID);
}
} else
{
if(_interceptors.containsKey(componentJID))
{
} else {
if (_interceptors.containsKey(componentJID)) {
removeInterceptor(componentJID);
}
}
}
public String getName()
{
return "remoteRoster";
......@@ -160,20 +150,17 @@ public class RemoteRosterPlugin implements Plugin {
private void removeInterceptor(String initialSubdomain)
{
RemotePackageInterceptor interceptor = _interceptors.get(initialSubdomain);
AbstractInterceptorHandler interceptor = _interceptors.get(initialSubdomain);
if (interceptor != null) {
Log.debug("Removing package interceptor for "+initialSubdomain);
_interceptorManager.removeInterceptor(interceptor);
_interceptors.remove(initialSubdomain);
interceptor.stop();
}
}
private void createNewPackageIntercetor(String initialSubdomain)
{
Log.debug("Creating package interceptor.");
RemotePackageInterceptor interceptor = new RemotePackageInterceptor(initialSubdomain);
AbstractInterceptorHandler interceptor = new GatewayInterceptorHandler(initialSubdomain);
_interceptors.put(initialSubdomain, interceptor);
_interceptorManager.addInterceptor(interceptor);
interceptor.start();
}
}
......@@ -2,6 +2,7 @@ package org.jivesoftware.openfire.plugin;
import java.util.Map;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.PropertyEventListener;
public abstract class RemoteRosterPropertyListener implements PropertyEventListener {
......@@ -10,17 +11,16 @@ public abstract class RemoteRosterPropertyListener implements PropertyEventListe
public void xmlPropertySet(String property, Map<String, Object> params)
{
}
@Override
public void xmlPropertyDeleted(String property, Map<String, Object> params)
{
}
@Override
public void propertySet(String property, Map<String, Object> params)
{
if (property.contains("plugin.remoteroster.jids."))
{
if (property.contains("plugin.remoteroster.jids.")) {
changedProperty(property.replace("plugin.remoteroster.jids.", ""));
}
}
......@@ -28,9 +28,11 @@ public abstract class RemoteRosterPropertyListener implements PropertyEventListe
@Override
public void propertyDeleted(String property, Map<String, Object> params)
{
changedProperty(property);
String hostname = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
property += "." + hostname;
changedProperty(property.replace("plugin.remoteroster.jids.", ""));
}
protected abstract void changedProperty(String prop);
}
......@@ -32,6 +32,7 @@ public class Utils {
{
Map<String, String> namespaceUris = new HashMap<String, String>();
namespaceUris.put("roster", "jabber:iq:roster");
namespaceUris.put("discoitems", "http://jabber.org/protocol/disco#items");
namespaceUris.put("register", "jabber:iq:register");
namespaceUris.put("disco", "http://jabber.org/protocol/disco#info");
XPath xPath = DocumentHelper.createXPath(xpath);
......
package org.jivesoftware.openfire.plugin.interceptor;
import java.util.HashSet;
import java.util.Set;
import org.jivesoftware.openfire.interceptor.InterceptorManager;
import org.jivesoftware.openfire.interceptor.PacketInterceptor;
public abstract class AbstractInterceptorHandler {
private String _subdomain;
private boolean _isRunning = false;
private Set<PacketInterceptor> _interceptors = new HashSet<PacketInterceptor>();
private InterceptorManager _iManager;
public AbstractInterceptorHandler(String subdomain) {
_subdomain = subdomain;
_iManager = InterceptorManager.getInstance();
}
protected boolean addInterceptor(PacketInterceptor interceptor)
{
if (_isRunning) {
return false;
}
return _interceptors.add(interceptor);
}
protected boolean removeInterceptor(PacketInterceptor interceptor)
{
if (_isRunning) {
return false;
}
return _interceptors.remove(interceptor);
}
public void start()
{
System.out.println("Start handling message interceptors for gateway " + _subdomain);
_isRunning = true;
for (PacketInterceptor interceptor : _interceptors) {
_iManager.addInterceptor(interceptor);
}
}
public void stop()
{
System.out.println("Stop handling message interceptors for gateway " + _subdomain);
if (!_isRunning)
return;
_isRunning = false;
for (PacketInterceptor interceptor : _interceptors) {
_iManager.removeInterceptor(interceptor);
}
}
}
package org.jivesoftware.openfire.plugin.interceptor;
import java.util.List;
import org.dom4j.Element;
import org.dom4j.Node;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.interceptor.PacketInterceptor;
import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.plugin.PermissionManager;
import org.jivesoftware.openfire.plugin.Utils;
import org.jivesoftware.openfire.session.Session;
import org.xmpp.packet.IQ;
import org.xmpp.packet.Packet;
public class DiscoPackageInterceptor implements PacketInterceptor {
private PermissionManager _permissions;
private String _subDomain;
private String _host;
public DiscoPackageInterceptor(String subdomain) {
_permissions = new PermissionManager();
_subDomain = subdomain;
XMPPServer server = XMPPServer.getInstance();
_host = server.getServerInfo().getHostname();
}
@Override
public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed)
throws PacketRejectedException
{
if (_permissions.isGatewayLimited(_subDomain)) {
if (packet instanceof IQ) {
IQ iqpacket = (IQ) packet;
Element root = iqpacket.getChildElement();
String ns = root.getNamespaceURI();
if (ns.equals("http://jabber.org/protocol/disco#items") && iqpacket.getType().equals(IQ.Type.result)) {
if (!_permissions.allowedForUser(_subDomain, iqpacket.getTo())) {
if (iqpacket.getFrom().toString().equals(_host)) {
List<Node> nodes = Utils.findNodesInDocument(root.getDocument(), "//discoitems:item");
for (Node node : nodes) {
if (node.valueOf("@jid").equals(_subDomain)) {
root.remove(node);
}
}
}
}
}
}
}
}
}
package org.jivesoftware.openfire.plugin.interceptor;
public class GatewayInterceptorHandler extends AbstractInterceptorHandler {
public GatewayInterceptorHandler(String subdomain) {
super(subdomain);
DiscoPackageInterceptor discoInterceptor = new DiscoPackageInterceptor(subdomain);
RemotePackageInterceptor remoteRosterInterceptor = new RemotePackageInterceptor(subdomain);
addInterceptor(remoteRosterInterceptor);
addInterceptor(discoInterceptor);
}
}
package org.jivesoftware.openfire.plugin;
package org.jivesoftware.openfire.plugin.interceptor;
import java.util.HashMap;
import java.util.Map;
......@@ -6,6 +6,7 @@ import java.util.Map;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.interceptor.PacketInterceptor;
import org.jivesoftware.openfire.interceptor.PacketRejectedException;
import org.jivesoftware.openfire.plugin.Utils;
import org.jivesoftware.openfire.plugin.packageProcessor.AbstractRemoteRosterProcessor;
import org.jivesoftware.openfire.plugin.packageProcessor.CleanUpRosterProcessor;
import org.jivesoftware.openfire.plugin.packageProcessor.ClientToComponentUpdateProcessor;
......
var http = function() {
this.callback = function(a) {};
this.obj = window.XMLHttpRequest ? new XMLHttpRequest()
: new ActiveXObject("Microsoft.XMLHTTP");
this.load = function(url) {
this.obj.open('get', url);
this.obj.callback = this.callback;
this.obj.onreadystatechange = this.handle;
this.obj.send(null);
};
this.handle = function() {
if (this.readyState == 4)
this.callback(this);
};
};
This diff is collapsed.
@CHARSET "ISO-8859-1";
.suggest_link {
background-color: #FFFFFF;
padding: 2px 6px 2px 6px;
}
.suggest_link_over {
background-color: #3366CC;
padding: 2px 6px 2px 6px;
}
#search_suggest {
position: absolute;
background-color: #FFFFFF;
text-align: left;
border: 1px solid #000000;
display:none;
}
.slider {
margin-left:1%;
padding-top:0px;
background-color:rgb(230,230,230);
border-color:#CCCCCC rgb(204, 204, 204);
color:white;
width:58%;
border-style: solid;
border-width: 1px;
border-top:none;
display: none;
}
.gatewayHeader {
width:60%;
background-color:#EEEEEE;
border-color:#CCCCCC rgb(204, 204, 204);
border-style:solid solid solid;
border-width:1px 1px 1px;
}
.gatewayName {
padding-left: 10px;
}
.gatewayIcon {
border-left: 1px;
}
.gatewayCheckbox {
width: 20px;
}
.configTable {
width: 80%;
}
.configTable1Column {
width: 50%;
}
.gatewayIcons img {
float: right;
padding: 4px;
}
#permissions {
margin-left:1%;
padding-top:0px;
background-color:rgb(230,230,230);
border-color:#CCCCCC rgb(204, 204, 204);
color:white;
width:58%;
border-style: solid;
border-width: 1px;
border-top:none;
display: none;
}
.permissionTableColumn
{
width: 50%;
}
.ajaxloading {
padding-left: 4px;
padding-top: 3px;
}
.permissionTitle {
color:black;
size:+2;
}
function searchSuggest(object) {
document.getElementById('search_suggest'+object).innerHTML = '';
var str = escape(document.getElementById('groupSearch'+object).value);
$("#ajaxloading"+object).html("<img src=\"images/ajax-loader.gif\">");
var request = new http();
var f = function(obj) {
console.log(obj);
var ss = document.getElementById('search_suggest'+object);
var resp = obj.responseXML.documentElement
.getElementsByTagName('item');
if (resp.length > 0) {
for ( var i = 0; i < resp.length; i++) {
console.log(resp[i].textContent);
var suggest = '<div onmouseover="javascript:suggestOver(this);" ';
suggest += 'onmouseout="javascript:suggestOut(this);" ';
suggest += 'onclick="javascript:setSearch(this.innerHTML,'+object+');" ';
suggest += 'class="suggest_link">' + resp[i].textContent
+ '</div>';
ss.innerHTML += suggest;
}
$("#search_suggest"+object).show("slow");
} else {
$("#search_suggest"+object).hide("slow");
}
};
request.callback = f;
request.load('searchGroup.jsp?search=' + str);
}
// Mouse over function
function suggestOver(div_value) {
div_value.className = 'suggest_link_over';
}
// Mouse out function
function suggestOut(div_value) {
div_value.className = 'suggest_link';
}
// Click function
function setSearch(value, object) {
document.getElementById("groupSearch"+object).value = value;
// document.getElementById('search_suggest').innerHTML = '';
$("#search_suggest"+object).hide("slow");
checkIfExists(value,object);
}
function checkIfExists(value, object) {
var str = value;
var request = new http();
var f = function(obj) {
console.log(obj);
var ss = document.getElementById('search_suggest'+object);
var resp = obj.responseXML.documentElement.getElementsByTagName('item');
for ( var i = 0; i < resp.length; i++) {
var stri = String(str);
var respStr = String(resp[i].textContent);
if (stri == respStr) {
$("#ajaxloading"+object)
.html("<img src=\"images/correct-16x16.png\">");
break;
}
}
};
request.callback = f;
request.load('searchGroup.jsp?search=' + str);
}
$(document).ready(function () {
console.log("bind da");
var myvalues = [10,8,5,7,4,4,1];
$('#inlinesparkline0').sparkline();
})
function slideToggle(value)
{
$(value).slideToggle();
}
<?xml version="1.0" encoding="UTF-8" ?>
<%@page import="org.dom4j.tree.DefaultElement"%>
<%@page import="org.dom4j.*"%>
<%@ page language="java" contentType="text/xml" pageEncoding="ISO-8859-1"%>
<%@ page import="org.jivesoftware.openfire.group.GroupManager"%>
<%@ page import="org.jivesoftware.openfire.group.Group"%>
<%@ page import="java.util.Collection"%>
<%
String param = request.getParameter("search");
Element root = new DefaultElement("result");
if (param != null && param.length() > 0)
{
GroupManager manager = GroupManager.getInstance();
Collection<Group> groups = manager.getGroups();
for (Group gr : groups)
{
if (gr.getName().startsWith(param))
{
root.addElement("item").addText(gr.getName());
}
}
}
out.write(root.asXML());
%>
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