Commit c8172cbc authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

More work in CS integration. External component config is now updated and...

More work in CS integration. External component config is now updated and added listeners and module.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@9919 b35dd754-fafc-0310-a699-88a17e54d16e
parent 5cc22c77
......@@ -16,6 +16,7 @@ import org.dom4j.io.SAXReader;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.audit.AuditManager;
import org.jivesoftware.openfire.audit.spi.AuditManagerImpl;
import org.jivesoftware.openfire.clearspace.ClearspaceManager;
import org.jivesoftware.openfire.cluster.NodeID;
import org.jivesoftware.openfire.commands.AdHocCommandHandler;
import org.jivesoftware.openfire.component.InternalComponentManager;
......@@ -27,6 +28,7 @@ import org.jivesoftware.openfire.filetransfer.DefaultFileTransferManager;
import org.jivesoftware.openfire.filetransfer.FileTransferManager;
import org.jivesoftware.openfire.filetransfer.proxy.FileTransferProxy;
import org.jivesoftware.openfire.handler.*;
import org.jivesoftware.openfire.lockout.LockOutManager;
import org.jivesoftware.openfire.mediaproxy.MediaProxyService;
import org.jivesoftware.openfire.muc.MultiUserChatServer;
import org.jivesoftware.openfire.muc.spi.MultiUserChatServerImpl;
......@@ -44,7 +46,6 @@ import org.jivesoftware.openfire.transport.TransportHandler;
import org.jivesoftware.openfire.update.UpdateManager;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.vcard.VCardManager;
import org.jivesoftware.openfire.lockout.LockOutManager;
import org.jivesoftware.util.*;
import org.jivesoftware.util.cache.CacheFactory;
import org.xmpp.packet.JID;
......@@ -54,14 +55,14 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* The main XMPP server that will load, initialize and start all the server's
......@@ -541,6 +542,7 @@ public class XMPPServer {
loadModule(UpdateManager.class.getName());
loadModule(FlashCrossDomainHandler.class.getName());
loadModule(InternalComponentManager.class.getName());
loadModule(ClearspaceManager.class.getName());
// Load this module always last since we don't want to start listening for clients
// before the rest of the modules have been started
loadModule(ConnectionManagerImpl.class.getName());
......
......@@ -11,9 +11,14 @@
package org.jivesoftware.openfire.clearspace;
import org.jivesoftware.openfire.auth.AuthFactory;
import org.jivesoftware.openfire.component.ExternalComponentConfiguration;
import org.jivesoftware.openfire.component.ExternalComponentManager;
import org.jivesoftware.openfire.component.ExternalComponentManagerListener;
import org.jivesoftware.openfire.container.BasicModule;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import java.util.*;
import org.jivesoftware.util.ModificationNotAllowedException;
/**
* Centralized administration of Clearspace connections. The {@link #getInstance()} method
......@@ -26,74 +31,13 @@ import java.util.*;
*
* @author Daniel Henninger
*/
public class ClearspaceManager {
public class ClearspaceManager extends BasicModule implements ExternalComponentManagerListener {
private static ClearspaceManager instance;
static {
// Create a special Map implementation to wrap XMLProperties. We only implement
// the get, put, and remove operations, since those are the only ones used. Using a Map
// makes it easier to perform LdapManager testing.
Map<String, String> properties = new Map<String, String>() {
public String get(Object key) {
return JiveGlobals.getXMLProperty((String)key);
}
public String put(String key, String value) {
JiveGlobals.setXMLProperty(key, value);
// Always return null since XMLProperties doesn't support the normal semantics.
return null;
}
public String remove(Object key) {
JiveGlobals.deleteXMLProperty((String)key);
// Always return null since XMLProperties doesn't support the normal semantics.
return null;
}
public int size() {
return 0;
}
public boolean isEmpty() {
return false;
}
public boolean containsKey(Object key) {
return false;
}
public boolean containsValue(Object value) {
return false;
}
public void putAll(Map<? extends String, ? extends String> t) {
}
public void clear() {
}
public Set<String> keySet() {
return null;
}
public Collection<String> values() {
return null;
}
public Set<Entry<String, String>> entrySet() {
return null;
}
};
instance = new ClearspaceManager(properties);
}
private static ClearspaceManager instance = new ClearspaceManager();
private String uri;
private String sharedSecret;
private Map<String, String> properties;
/**
* Provides singleton access to an instance of the ClearspaceManager class.
*
......@@ -108,25 +52,20 @@ public class ClearspaceManager {
* called instead of this method. ClearspaceManager instances should only be created directly
* for testing purposes.
*
* @param properties the Map that contains properties used by the Clearspace manager, such as
* Clearspace host and shared secret.
*/
public ClearspaceManager(Map<String, String> properties) {
this.properties = properties;
String uri = properties.get("clearspace.uri");
if (uri != null) {
this.uri = uri;
}
sharedSecret = properties.get("clearspace.sharedSecret");
StringBuilder buf = new StringBuilder();
buf.append("Created new ClearspaceManager() instance, fields:\n");
buf.append("\t URI: ").append(uri).append("\n");
buf.append("\t sharedSecret: ").append(sharedSecret).append("\n");
public ClearspaceManager() {
super("Clearspace integration module");
this.uri = JiveGlobals.getXMLProperty("clearspace.uri");
sharedSecret = JiveGlobals.getXMLProperty("clearspace.sharedSecret");
if (Log.isDebugEnabled()) {
Log.debug("ClearspaceManager: "+buf.toString());
StringBuilder buf = new StringBuilder();
buf.append("Created new ClearspaceManager() instance, fields:\n");
buf.append("\t URI: ").append(uri).append("\n");
buf.append("\t sharedSecret: ").append(sharedSecret).append("\n");
Log.debug("ClearspaceManager: " + buf.toString());
}
}
......@@ -178,7 +117,10 @@ public class ClearspaceManager {
*/
public void setConnectionURI(String uri) {
this.uri = uri;
properties.put("clearspace.uri", uri);
JiveGlobals.setXMLProperty("clearspace.uri", uri);
if (isEnabled()) {
// TODO Reconfigure webservice connection with new setting
}
}
/**
......@@ -198,7 +140,91 @@ public class ClearspaceManager {
*/
public void setSharedSecret(String sharedSecret) {
this.sharedSecret = sharedSecret;
properties.put("clearspace.sharedSecret", sharedSecret);
JiveGlobals.setXMLProperty("clearspace.sharedSecret", sharedSecret);
// Set new password for external component
ExternalComponentConfiguration configuration = new ExternalComponentConfiguration("clearspace",
ExternalComponentConfiguration.Permission.allowed, sharedSecret);
try {
ExternalComponentManager.allowAccess(configuration);
}
catch (ModificationNotAllowedException e) {
Log.warn("Failed to configure password for Clearspace", e);
}
}
/**
* Returns true if Clearspace is being used as the backend of Openfire. When
* integrated with Clearspace then users and groups will be pulled out from
* Clearspace. User authentication will also rely on Clearspace.
*
* @return true if Clearspace is being used as the backend of Openfire.
*/
public boolean isEnabled() {
return AuthFactory.getAuthProvider() instanceof ClearspaceAuthProvider;
}
public void start() throws IllegalStateException {
super.start();
if (isEnabled()) {
// Make sure that external component service is enabled
if (!ExternalComponentManager.isServiceEnabled()) {
try {
ExternalComponentManager.setServiceEnabled(true);
}
catch (ModificationNotAllowedException e) {
Log.warn("Failed to start external component service", e);
}
}
// Listen for changes to external component settings
ExternalComponentManager.addListener(this);
// TODO Send current xmpp domain, network interfaces, external component port and external component secret to CS
}
}
public void serviceEnabled(boolean enabled) throws ModificationNotAllowedException {
// Do not let admins shutdown the external component service
if (!enabled) {
throw new ModificationNotAllowedException("Service cannot be disabled when integrated with Clearspace.");
}
}
public void portChanged(int newPort) throws ModificationNotAllowedException {
//TODO Send the new port to Clearspace
}
public void defaultSecretChanged(String newSecret) throws ModificationNotAllowedException {
// Do nothing
}
public void permissionPolicyChanged(ExternalComponentManager.PermissionPolicy newPolicy)
throws ModificationNotAllowedException {
// Do nothing
}
public void componentAllowed(String subdomain, ExternalComponentConfiguration configuration)
throws ModificationNotAllowedException {
if (subdomain.startsWith("clearspace")) {
// TODO Send new password to Clearspace
//configuration.getSecret();
}
}
public void componentBlocked(String subdomain) throws ModificationNotAllowedException {
if (subdomain.startsWith("clearspace")) {
throw new ModificationNotAllowedException("Communication with Clearspace cannot be blocked.");
}
}
public void componentSecretUpdated(String subdomain, String newSecret) throws ModificationNotAllowedException {
if (subdomain.startsWith("clearspace")) {
// TODO Send new password to Clearspace
}
}
public void componentConfigurationDeleted(String subdomain) throws ModificationNotAllowedException {
// Do not let admins delete configuration of Clearspace component
if (subdomain.startsWith("clearspace")) {
throw new ModificationNotAllowedException("Use 'Profile Settings' to change password.");
}
}
}
\ No newline at end of file
......@@ -11,14 +11,15 @@
package org.jivesoftware.openfire.component;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.ConnectionManager;
import org.jivesoftware.openfire.SessionManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.ConnectionManager;
import org.jivesoftware.openfire.component.ExternalComponentConfiguration.Permission;
import org.jivesoftware.openfire.session.ComponentSession;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.ModificationNotAllowedException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
......@@ -53,7 +54,7 @@ public class ExternalComponentManager {
private static List<ExternalComponentManagerListener> listeners =
new CopyOnWriteArrayList<ExternalComponentManagerListener>();
public static void setServiceEnabled(boolean enabled) throws Exception {
public static void setServiceEnabled(boolean enabled) throws ModificationNotAllowedException {
// Alert listeners about this event
for (ExternalComponentManagerListener listener : listeners) {
listener.serviceEnabled(enabled);
......@@ -67,7 +68,7 @@ public class ExternalComponentManager {
return connectionManager.isComponentListenerEnabled();
}
public static void setServicePort(int port) throws Exception {
public static void setServicePort(int port) throws ModificationNotAllowedException {
// Alert listeners about this event
for (ExternalComponentManagerListener listener : listeners) {
listener.portChanged(port);
......@@ -85,12 +86,12 @@ public class ExternalComponentManager {
* Allows an external component to connect to the local server with the specified configuration.
*
* @param configuration the configuration for the external component.
* @throws Exception if the operation was denied.
* @throws ModificationNotAllowedException if the operation was denied.
*/
public static void allowAccess(ExternalComponentConfiguration configuration) throws Exception {
public static void allowAccess(ExternalComponentConfiguration configuration) throws ModificationNotAllowedException {
// Alert listeners about this event
for (ExternalComponentManagerListener listener : listeners) {
listener.componentAllowed(configuration.getSubdomain());
listener.componentAllowed(configuration.getSubdomain(), configuration);
}
// Remove any previous configuration for this external component
deleteConfigurationFromDB(configuration.getSubdomain());
......@@ -104,9 +105,9 @@ public class ExternalComponentManager {
* connected when the permission was revoked then the connection of the entity will be closed.
*
* @param subdomain the subdomain of the external component that is not allowed to connect.
* @throws Exception if the operation was denied.
* @throws ModificationNotAllowedException if the operation was denied.
*/
public static void blockAccess(String subdomain) throws Exception {
public static void blockAccess(String subdomain) throws ModificationNotAllowedException {
// Alert listeners about this event
for (ExternalComponentManagerListener listener : listeners) {
listener.componentBlocked(subdomain);
......@@ -173,7 +174,7 @@ public class ExternalComponentManager {
return getConfigurations(Permission.blocked);
}
public static void updateComponentSecret(String subdomain, String secret) throws Exception {
public static void updateComponentSecret(String subdomain, String secret) throws ModificationNotAllowedException {
// Alert listeners about this event
for (ExternalComponentManagerListener listener : listeners) {
listener.componentSecretUpdated(subdomain, secret);
......@@ -196,9 +197,9 @@ public class ExternalComponentManager {
* external component.
*
* @param subdomain the subdomain of the external component.
* @throws Exception if the operation was denied.
* @throws ModificationNotAllowedException if the operation was denied.
*/
public static void deleteConfiguration(String subdomain) throws Exception {
public static void deleteConfiguration(String subdomain) throws ModificationNotAllowedException {
// Alert listeners about this event
for (ExternalComponentManagerListener listener : listeners) {
listener.componentConfigurationDeleted(subdomain);
......@@ -343,9 +344,9 @@ public class ExternalComponentManager {
*
* @param defaultSecret the default secret key to use for those external components that
* don't have an individual configuration.
* @throws Exception if the operation was denied.
* @throws ModificationNotAllowedException if the operation was denied.
*/
public static void setDefaultSecret(String defaultSecret) throws Exception {
public static void setDefaultSecret(String defaultSecret) throws ModificationNotAllowedException {
// Alert listeners about this event
for (ExternalComponentManagerListener listener : listeners) {
listener.defaultSecretChanged(defaultSecret);
......@@ -407,9 +408,9 @@ public class ExternalComponentManager {
* the server.
*
* @param policy the new PermissionPolicy to use.
* @throws Exception if the operation was denied.
* @throws ModificationNotAllowedException if the operation was denied.
*/
public static void setPermissionPolicy(PermissionPolicy policy) throws Exception {
public static void setPermissionPolicy(PermissionPolicy policy) throws ModificationNotAllowedException {
// Alert listeners about this event
for (ExternalComponentManagerListener listener : listeners) {
listener.permissionPolicyChanged(policy);
......@@ -434,9 +435,9 @@ public class ExternalComponentManager {
* the server.
*
* @param policy the new policy to use.
* @throws Exception if the operation was denied.
* @throws ModificationNotAllowedException if the operation was denied.
*/
public static void setPermissionPolicy(String policy) throws Exception {
public static void setPermissionPolicy(String policy) throws ModificationNotAllowedException {
setPermissionPolicy(PermissionPolicy.valueOf(policy));
}
......
......@@ -68,9 +68,11 @@ public interface ExternalComponentManagerListener {
* change from taking place.
*
* @param subdomain subdomain of the added component.
* @param configuration configuration for the external component.
* @throws ModificationNotAllowedException if the operation was denied.
*/
void componentAllowed(String subdomain) throws ModificationNotAllowedException;
void componentAllowed(String subdomain, ExternalComponentConfiguration configuration)
throws ModificationNotAllowedException;
/**
* Notification indicating that a component was blocked to connect to the server.
......
......@@ -246,7 +246,7 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
private void createComponentListener() {
// Start components socket unless it's been disabled.
if (isComponentListenerEnabled()) {
if (isComponentListenerEnabled() && componentAcceptor == null) {
// Create SocketAcceptor with correct number of processors
componentAcceptor = buildSocketAcceptor();
// Customize Executor that will be used by processors to process incoming stanzas
......@@ -265,7 +265,8 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
private void startComponentListener() {
// Start components socket unless it's been disabled.
if (isComponentListenerEnabled()) {
if (isComponentListenerEnabled() && componentAcceptor != null &&
componentAcceptor.getManagedServiceAddresses().isEmpty()) {
int port = getComponentListenerPort();
try {
// Listen on a specific network interface if it has been set.
......
......@@ -12,14 +12,17 @@
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%@ page import="org.jivesoftware.util.*,
java.util.Iterator,
org.jivesoftware.openfire.*,
java.util.*,
<%@ page import="org.jivesoftware.openfire.XMPPServer,
org.jivesoftware.openfire.component.ExternalComponentConfiguration,
org.jivesoftware.openfire.component.ExternalComponentManager,
org.jivesoftware.openfire.component.ExternalComponentConfiguration"
org.jivesoftware.util.ModificationNotAllowedException,
org.jivesoftware.util.ParamUtils,
java.util.Collection"
errorPage="error.jsp"
%>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Iterator" %>
<%@ page import="java.util.Map" %>
<html>
<head>
......@@ -45,6 +48,7 @@
boolean blockSuccess = false;
boolean deleteSuccess = false;
boolean operationFailed = false;
String operationFailedDetail = null;
String serverName = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
......@@ -74,6 +78,7 @@
updateSucess = true;
}
catch (ModificationNotAllowedException e) {
operationFailedDetail = e.getMessage();
operationFailed = true;
}
}
......@@ -85,6 +90,7 @@
updateSucess = true;
}
catch (ModificationNotAllowedException e) {
operationFailedDetail = e.getMessage();
operationFailed = true;
}
}
......@@ -95,6 +101,7 @@
deleteSuccess = true;
}
catch (ModificationNotAllowedException e) {
operationFailedDetail = e.getMessage();
operationFailed = true;
}
}
......@@ -118,6 +125,7 @@
allowSuccess = true;
}
catch (ModificationNotAllowedException e) {
operationFailedDetail = e.getMessage();
operationFailed = true;
}
}
......@@ -137,6 +145,7 @@
blockSuccess = true;
}
catch (ModificationNotAllowedException e) {
operationFailedDetail = e.getMessage();
operationFailed = true;
}
}
......@@ -210,7 +219,7 @@
<tr>
<td class="jive-icon"><img src="images/error-16x16.gif" width="16" height="16" border="0"/></td>
<td class="jive-icon-label">
<fmt:message key="component.settings.modification.denied" />
<fmt:message key="component.settings.modification.denied" /> <%= operationFailedDetail != null ? operationFailedDetail : ""%>
</td>
</tr>
</tbody>
......
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