/*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.openfire.plugin.rest;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.ws.rs.core.Response;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.plugin.rest.entity.SystemProperties;
import org.jivesoftware.openfire.plugin.rest.entity.SystemProperty;
import org.jivesoftware.openfire.plugin.rest.exceptions.ExceptionType;
import org.jivesoftware.openfire.plugin.rest.exceptions.ServiceException;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.PropertyEventDispatcher;
import org.jivesoftware.util.PropertyEventListener;
import org.jivesoftware.util.StringUtils;
import org.jivesoftware.openfire.plugin.rest.service.JerseyWrapper;
/**
* The Class RESTServicePlugin.
*/
public class RESTServicePlugin implements Plugin, PropertyEventListener {
/** The Constant INSTANCE. */
public static final RESTServicePlugin INSTANCE = new RESTServicePlugin();
private static final String CUSTOM_AUTH_FILTER_PROPERTY_NAME = "plugin.restapi.customAuthFilter";
/** The secret. */
private String secret;
/** The allowed i ps. */
private Collection<String> allowedIPs;
/** The enabled. */
private boolean enabled;
/** The http auth. */
private String httpAuth;
/** The custom authentication filter */
private String customAuthFilterClassName;
/**
* Gets the single instance of RESTServicePlugin.
*
* @return single instance of RESTServicePlugin
*/
public static RESTServicePlugin getInstance() {
return INSTANCE;
}
/* (non-Javadoc)
* @see org.jivesoftware.openfire.container.Plugin#initializePlugin(org.jivesoftware.openfire.container.PluginManager, java.io.File)
*/
public void initializePlugin(PluginManager manager, File pluginDirectory) {
secret = JiveGlobals.getProperty("plugin.restapi.secret", "");
// If no secret key has been assigned, assign a random one.
if ("".equals(secret)) {
secret = StringUtils.randomString(16);
setSecret(secret);
}
// See if Custom authentication filter has been defined
customAuthFilterClassName = JiveGlobals.getProperty("plugin.restapi.customAuthFilter", "");
// See if the service is enabled or not.
enabled = JiveGlobals.getBooleanProperty("plugin.restapi.enabled", false);
// See if the HTTP Basic Auth is enabled or not.
httpAuth = JiveGlobals.getProperty("plugin.restapi.httpAuth", "basic");
// Get the list of IP addresses that can use this service. An empty list
// means that this filter is disabled.
allowedIPs = StringUtils.stringToCollection(JiveGlobals.getProperty("plugin.restapi.allowedIPs", ""));
// Listen to system property events
PropertyEventDispatcher.addListener(this);
}
/* (non-Javadoc)
* @see org.jivesoftware.openfire.container.Plugin#destroyPlugin()
*/
public void destroyPlugin() {
// Stop listening to system property events
PropertyEventDispatcher.removeListener(this);
}
/**
* Gets the system properties.
*
* @return the system properties
*/
public SystemProperties getSystemProperties() {
SystemProperties systemProperties = new SystemProperties();
List<SystemProperty> propertiesList = new ArrayList<SystemProperty>();
for(String propertyKey : JiveGlobals.getPropertyNames()) {
String propertyValue = JiveGlobals.getProperty(propertyKey);
propertiesList.add(new SystemProperty(propertyKey, propertyValue));
}
systemProperties.setProperties(propertiesList);
return systemProperties;
}
/**
* Gets the system property.
*
* @param propertyKey the property key
* @return the system property
* @throws ServiceException the service exception
*/
public SystemProperty getSystemProperty(String propertyKey) throws ServiceException {
String propertyValue = JiveGlobals.getProperty(propertyKey);
if(propertyValue != null) {
return new SystemProperty(propertyKey, propertyValue);
} else {
throw new ServiceException("Could not find property", propertyKey, ExceptionType.PROPERTY_NOT_FOUND,
Response.Status.NOT_FOUND);
}
}
/**
* Creates the system property.
*
* @param systemProperty the system property
*/
public void createSystemProperty(SystemProperty systemProperty) {
JiveGlobals.setProperty(systemProperty.getKey(), systemProperty.getValue());
}
/**
* Delete system property.
*
* @param propertyKey the property key
* @throws ServiceException the service exception
*/
public void deleteSystemProperty(String propertyKey) throws ServiceException {
if(JiveGlobals.getProperty(propertyKey) != null) {
JiveGlobals.deleteProperty(propertyKey);
} else {
throw new ServiceException("Could not find property", propertyKey, ExceptionType.PROPERTY_NOT_FOUND,
Response.Status.NOT_FOUND);
}
}
/**
* Update system property.
*
* @param propertyKey the property key
* @param systemProperty the system property
* @throws ServiceException the service exception
*/
public void updateSystemProperty(String propertyKey, SystemProperty systemProperty) throws ServiceException {
if(JiveGlobals.getProperty(propertyKey) != null) {
if(systemProperty.getKey().equals(propertyKey)) {
JiveGlobals.setProperty(propertyKey, systemProperty.getValue());
} else {
throw new ServiceException("Path property name and entity property name doesn't match", propertyKey, ExceptionType.ILLEGAL_ARGUMENT_EXCEPTION,
Response.Status.BAD_REQUEST);
}
} else {
throw new ServiceException("Could not find property for update", systemProperty.getKey(), ExceptionType.PROPERTY_NOT_FOUND,
Response.Status.NOT_FOUND);
}
}
/**
* Returns the loading status message.
*
* @return the loading status message.
*/
public String getLoadingStatusMessage() {
return JerseyWrapper.getLoadingStatusMessage();
}
/**
* Reloads the Jersey wrapper.
*/
public String loadAuthenticationFilter(String customAuthFilterClassName) {
return JerseyWrapper.tryLoadingAuthenticationFilter(customAuthFilterClassName);
}
/**
* Returns the secret key that only valid requests should know.
*
* @return the secret key.
*/
public String getSecret() {
return secret;
}
/**
* Sets the secret key that grants permission to use the userservice.
*
* @param secret
* the secret key.
*/
public void setSecret(String secret) {
JiveGlobals.setProperty("plugin.restapi.secret", secret);
this.secret = secret;
}
/**
* Returns the custom authentication filter class name used in place of the basic ones to grant permission to use the Rest services.
*
* @return custom authentication filter class name .
*/
public String getCustomAuthFilterClassName() {
return customAuthFilterClassName;
}
/**
* Sets the customAuthFIlterClassName used to grant permission to use the Rest services.
*
* @param customAuthFilterClassName
* custom authentication filter class name.
*/
public void setCustomAuthFiIterClassName(String customAuthFilterClassName) {
JiveGlobals.setProperty(CUSTOM_AUTH_FILTER_PROPERTY_NAME, customAuthFilterClassName);
this.customAuthFilterClassName = customAuthFilterClassName;
}
/**
* Gets the allowed i ps.
*
* @return the allowed i ps
*/
public Collection<String> getAllowedIPs() {
return allowedIPs;
}
/**
* Sets the allowed i ps.
*
* @param allowedIPs the new allowed i ps
*/
public void setAllowedIPs(Collection<String> allowedIPs) {
JiveGlobals.setProperty("plugin.restapi.allowedIPs", StringUtils.collectionToString(allowedIPs));
this.allowedIPs = allowedIPs;
}
/**
* Returns true if the user service is enabled. If not enabled, it will not
* accept requests to create new accounts.
*
* @return true if the user service is enabled.
*/
public boolean isEnabled() {
return enabled;
}
/**
* Enables or disables the user service. If not enabled, it will not accept
* requests to create new accounts.
*
* @param enabled
* true if the user service should be enabled.
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
JiveGlobals.setProperty("plugin.restapi.enabled", enabled ? "true" : "false");
}
/**
* Gets the http authentication mechanism.
*
* @return the http authentication mechanism
*/
public String getHttpAuth() {
return httpAuth;
}
/**
* Sets the http auth.
*
* @param httpAuth the new http auth
*/
public void setHttpAuth(String httpAuth) {
this.httpAuth = httpAuth;
JiveGlobals.setProperty("plugin.restapi.httpAuth", httpAuth);
}
/* (non-Javadoc)
* @see org.jivesoftware.util.PropertyEventListener#propertySet(java.lang.String, java.util.Map)
*/
public void propertySet(String property, Map<String, Object> params) {
if (property.equals("plugin.restapi.secret")) {
this.secret = (String) params.get("value");
} else if (property.equals("plugin.restapi.enabled")) {
this.enabled = Boolean.parseBoolean((String) params.get("value"));
} else if (property.equals("plugin.restapi.allowedIPs")) {
this.allowedIPs = StringUtils.stringToCollection((String) params.get("value"));
} else if (property.equals("plugin.restapi.httpAuth")) {
this.httpAuth = (String) params.get("value");
} else if(property.equals(CUSTOM_AUTH_FILTER_PROPERTY_NAME)) {
this.customAuthFilterClassName = (String) params.get("value");
}
}
/* (non-Javadoc)
* @see org.jivesoftware.util.PropertyEventListener#propertyDeleted(java.lang.String, java.util.Map)
*/
public void propertyDeleted(String property, Map<String, Object> params) {
if (property.equals("plugin.restapi.secret")) {
this.secret = "";
} else if (property.equals("plugin.restapi.enabled")) {
this.enabled = false;
} else if (property.equals("plugin.restapi.allowedIPs")) {
this.allowedIPs = Collections.emptyList();
} else if (property.equals("plugin.restapi.httpAuth")) {
this.httpAuth = "basic";
} else if(property.equals(CUSTOM_AUTH_FILTER_PROPERTY_NAME)) {
this.customAuthFilterClassName = null;
}
}
/* (non-Javadoc)
* @see org.jivesoftware.util.PropertyEventListener#xmlPropertySet(java.lang.String, java.util.Map)
*/
public void xmlPropertySet(String property, Map<String, Object> params) {
// Do nothing
}
/* (non-Javadoc)
* @see org.jivesoftware.util.PropertyEventListener#xmlPropertyDeleted(java.lang.String, java.util.Map)
*/
public void xmlPropertyDeleted(String property, Map<String, Object> params) {
// Do nothing
}
}