Commit f95a3d6d authored by Matt Tucker's avatar Matt Tucker Committed by matt

Initial checkin -- from Justin Hunt.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@3581 b35dd754-fafc-0310-a699-88a17e54d16e
parent 4fca9fe9
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>User Service Plugin Changelog</title>
<style type="text/css">
BODY {
font-size : 100%;
}
BODY, TD, TH {
font-family : tahoma, verdana, arial, helvetica, sans-serif;
font-size : 0.8em;
}
H2 {
font-size : 10pt;
font-weight : bold;
padding-left : 1em;
}
A:hover {
text-decoration : none;
}
H1 {
font-family : tahoma, arial, helvetica, sans-serif;
font-size : 1.4em;
font-weight: bold;
border-bottom : 1px #ccc solid;
padding-bottom : 2px;
}
TT {
font-family : courier new;
font-weight : bold;
color : #060;
}
PRE {
font-family : courier new;
font-size : 100%;
}
</style>
</head>
<body>
<h1>
User Service Plugin Changelog
</h1>
<p><b>1.1</b> -- March 16, 2006</p>
<ul>
<li>Updates to documentation and source to support Wildfire 2.4 and above.</li>
</ul>
<p><b>1.0</b> -- Nov 10, 2005</p>
<ul>
<li>Initial release. </li>
</ul>
</body>
</html>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<class>org.jivesoftware.wildfire.plugin.UserServicePlugin</class>
<name>User Service</name>
<description>Allows administration of users via HTTP requests.</description>
<author>Justin Hunt</author>
<version>1.1</version>
<date>03/16/2006</date>
<minServerVersion>2.4.4</minServerVersion>
<adminconsole>
<tab id="tab-server">
<sidebar id="sidebar-server-settings">
<item id="user-service" name="User Service" url="user-service.jsp"
description="Click to manage the service that allows remote admin of users" />
</sidebar>
</tab>
</adminconsole>
</plugin>
\ No newline at end of file
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>User Service Plugin Readme</title>
<style type="text/css">
BODY {
font-size : 100%;
}
BODY, TD, TH {
font-family : tahoma, verdana, arial, helvetica, sans-serif;
font-size : 0.8em;
}
H2 {
font-size : 10pt;
font-weight : bold;
}
A:hover {
text-decoration : none;
}
H1 {
font-family : tahoma, arial, helvetica, sans-serif;
font-size : 1.4em;
font-weight: bold;
border-bottom : 1px #ccc solid;
padding-bottom : 2px;
}
TT {
font-family : courier new;
font-weight : bold;
color : #060;
}
PRE {
font-family : courier new;
font-size : 100%;
}
#datatable TH {
color : #fff;
background-color : #2A448C;
text-align : left;
}
#datatable TD {
background-color : #FAF6EF;
}
#datatable .name {
background-color : #DCE2F5;
}
</style>
</head>
<body>
<h1>
User Service Plugin Readme
</h1>
<h2>Overview</h2>
<p>
The User Service Plugin provides the ability to add,edit,delete users by sending an http request to the server.
It is intended to be used by applications automating the user administration process.
This plugin's functionality is useful for applications that need to administer users outside of the Wildfire admin console.
An example of such an application might be a live sports reporting application that uses XMPP as its transport, and
creates/deletes users according to the receipt, or non receipt, of a subscription fee.
</p>
<h2>Installation</h2>
<p>Copy userservice.jar into the plugins directory of your Wildfire server. The
plugin will then be automatically deployed. To upgrade to a new version, copy the new
userservice.jar file over the existing file.</p>
<h2>Configuration</h2>
Access to the service is restricted with a "secret" that can be viewed and set from the User Service page in the Wildfire admin console
This should really only be considered weak security. The plugin was initially written with the assumption that http access to the Wildfire service was
only available to trusted machines. In the case of the plugin's author, a web application running on the same server as
Wildfire makes the request.
<h2>Using the Plugin</h2>
To administer users, submit HTTP requests to the userservice service.
The service address is [hostname]plugins/userService/userservice. For example,
if your server name is "example.com", the URL is http://example.com/plugins/userService/userservice<p>
The following parameters can be passed into the request:<p>
<div id="datatable">
<table cellpadding="3" cellspacing="1" border="0" width="700">
<tr>
<th colspan=2>Name</th><th>Description</th>
</tr>
<tr>
<td class="name">type</td><td>Required</td><td>The admin service required.
Possible values are add, delete, update</td>
</tr>
<tr>
<td class="name">secret</td><td>required</td>
<td>The secret key that allows access to the User Service.</td>
</tr>
<tr>
<td class="name">jid</td><td>required for delete and update operations</td>
<td>The bare JID (address) of the user to be administered(ie includes @yourdomain.com).
</td>
</tr>
<tr>
<td class="name">username</td><td>required for add operation</td>
<td>The username of the new user. ie the part before the @ symbol.</td>
</tr>
<tr>
<td class="name">password</td><td>required for add operation</td>
<td>The password of the new user or the user being updated.</td>
</tr>
<tr>
<td class="name">name</td><td>optional</td>
<td>The display name of the new user or the user being updated.</td>
</tr>
<tr>
<td class="name">email</td><td>optional</td>
<td>The email address of the new user or the user being updated.</td>
</tr>
</table><p>
<p><b>Sample HTML</b><p>
The following example adds a user
<ul>
<form>
<textarea cols=65 rows=3 wrap=virtual>
http://example.com:9090/plugins/userService/userservice?type=add&secret=bigsecret&username=kafka&password=drowssap&name=franz&email=franz@kafka.com
</textarea>
</form>
</ul>
The following example deletes a user
<ul>
<form>
<textarea cols=65 rows=4 wrap=virtual>
http://example.com:9090/plugins/userService/userservice?type=delete&secret=bigsecret&jid=kafka@example.com
</textarea>
</form>
</ul>
This example updates a user
<ul>
<form>
<textarea cols=65 rows=3 wrap=virtual>
http://example.com:9090/plugins/userService/userservice?type=update&secret=bigsecret&jid=kafka@example.com&password=drowssap&name=franz&email=beetle@kafka.com
</textarea>
</form>
</ul>
<br><br>
* When sending double characters (Chinese/Japanese/Korean etc) you should URLEncode the string as utf8.<br>
In Java this is done like this<br>
URLEncoder.encode(username, "UTF-8"));
<br>If the strings are encoded incorrectly, double byte characters will look garbeled in the Admin Console.
<h2>Server Reply</h2>
The server will reply to all User Service requests with an XML result page.
If the request was processed successfully the return will be a "result" element with a text body of "OK".
If the request was unsuccessful, the return will be an "error" element with a text body of one of the following error strings.
<p>
<div id="datatable">
<table cellpadding="3" cellspacing="1" border="0" width="700">
<tr>
<th >Error String</th><th>Description</th>
</tr>
<tr>
<td class="name">IllegalArgumentException</td>
<td>one of the parameters passed in to the User Service was bad.</td>
</tr>
<tr>
<td class="name">UserNotFoundException</td>
<td>No user of the name specified, for a delete or update operation, exists on this server.</td>
</tr>
<tr>
<td class="name">UserAlreadyExistsException</td>
<td>A user with the same name as the user about to be added, already exists.
</td>
</tr>
<tr>
<td class="name">RequestNotAuthorised</td>
<td>The supplied secret does not match the secret specified in the Admin Console.</td>
</tr>
<tr>
<td class="name">UserServiceDisabled</td>
<td>The User Service is currently set to disabled in the Admin Console.</td>
</tr>
</table><p>
</body>
</html>
/**
* $Revision: 1722 $
* $Date: 2005-07-28 15:19:16 -0700 (Thu, 28 Jul 2005) $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.plugin;
import org.jivesoftware.wildfire.container.Plugin;
import org.jivesoftware.wildfire.container.PluginManager;
import org.jivesoftware.wildfire.user.UserManager;
import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.jivesoftware.wildfire.user.UserAlreadyExistsException;
import org.jivesoftware.wildfire.user.User;
import org.jivesoftware.wildfire.XMPPServer;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.StringUtils;
import org.xmpp.packet.JID;
import java.io.File;
/**
* Plugin that allows the administration of users via HTTP requests.
*
* @author Justin Hunt
*/
public class UserServicePlugin implements Plugin {
private UserManager userManager;
private String hostname;
private String secret;
private boolean enabled;
public void initializePlugin(PluginManager manager, File pluginDirectory) {
XMPPServer server = XMPPServer.getInstance();
userManager = server.getUserManager();
hostname = server.getServerInfo().getName();
secret = JiveGlobals.getProperty("plugin.userservice.secret", "");
// If no secret key has been assigned to the user service yet, assign a random one.
if (secret.equals("")){
secret = StringUtils.randomString(8);
setSecret(secret);
}
// See if the service is enabled or not.
enabled = JiveGlobals.getBooleanProperty("plugin.userservice.enabled", false);
}
public void destroyPlugin() {
userManager = null;
}
public void createUser(String username, String password, String name, String email)
throws UserAlreadyExistsException
{
userManager.createUser(username, password, name, email);
}
public void deleteUser(String jid) throws UserNotFoundException{
User user = getUser(jid);
userManager.deleteUser(user);
}
public void updateUser(String jid, String password, String name, String email)
throws UserNotFoundException
{
User user = getUser(jid);
user.setPassword(password);
user.setName(name);
user.setEmail(email);
}
/**
* Returns the the requested user or <tt>null</tt> if there are any
* problems that don't throw an error.
*
* @param jid the bare JID of the entity whose presence is being probed.
* @return the requested user.
* @throws UserNotFoundException if the requested user
* does not exist in the local server.
*/
private User getUser(String jid) throws UserNotFoundException {
JID targetJID = new JID(jid);
// Check that the sender is not requesting information of a remote server entity
if (targetJID.getDomain() == null || XMPPServer.getInstance().isRemote(targetJID)) {
throw new UserNotFoundException("Domain does not matches local server domain");
}
if (!hostname.equals(targetJID.getDomain())) {
// Sender is requesting information about component presence
// TODO Implement this
throw new UserNotFoundException("Presence of components not supported yet!");
}
if (targetJID.getNode() == null) {
// Sender is requesting presence information of an anonymous user
throw new UserNotFoundException("Username is null");
}
return userManager.getUser(targetJID.getNode());
}
/**
* 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.userservice.secret", secret);
this.secret = secret;
}
/**
* 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.userservice.enabled", enabled ? "true" : "false");
}
}
\ No newline at end of file
/**
* $RCSfile$
* $Revision: 1710 $
* $Date: 2005-07-26 11:56:14 -0700 (Tue, 26 Jul 2005) $
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.plugin.userService;
import org.jivesoftware.wildfire.XMPPServer;
import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.jivesoftware.wildfire.user.UserAlreadyExistsException;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.plugin.UserServicePlugin;
import org.jivesoftware.admin.AuthCheckFilter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Servlet that addition/deletion/modification of the users info in the system.
* Use the <b>type</b>
* parameter to specify the type of action. Possible values are <b>add</b>,<b>delete</b> and
* <b>update</b>. <p>
* <p/>
* The request <b>MUST</b> include the <b>secret</b> parameter. This parameter will be used
* to authenticate the request. If this parameter is missing from the request then
* an error will be logged and no action will occur.
*
* @author Justin Hunt
*/
public class UserServiceServlet extends HttpServlet {
private UserServicePlugin plugin;
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
plugin = (UserServicePlugin) XMPPServer.getInstance().getPluginManager().getPlugin("userservice");
// Exclude this servlet from requiring the user to login
AuthCheckFilter.addExclude("userService/userservice");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String username = request.getParameter("username");
String password = request.getParameter("password");
String name = request.getParameter("name");
String email = request.getParameter("email");
String jid = request.getParameter("jid");
String type = request.getParameter("type");
String secret = request.getParameter("secret");
//No defaults, add, delete, update only
//type = type == null ? "image" : type;
// Printwriter for writing out responses to browser
PrintWriter out = response.getWriter();
// Check that our plugin is enabled.
if (!plugin.isEnabled()) {
Log.warn("User service plugin is disabled: " + request.getQueryString());
replyError("UserServiceDisabled",response, out);
return;
}
// Check this request is authorised
if (secret == null || !secret.equals(plugin.getSecret())){
Log.warn("An unauthorised user service request was received: " + request.getQueryString());
replyError("RequestNotAuthorised",response, out);
return;
}
// Check the request type and process accordingly
try {
if ("add".equals(type)) {
plugin.createUser(username, password, name, email);
replyMessage("ok",response, out);
//imageProvider.sendInfo(request, response, presence);
}
else if ("delete".equals(type)) {
plugin.deleteUser(jid);
replyMessage("ok",response,out);
//xmlProvider.sendInfo(request, response, presence);
}
else if ("update".equals(type)) {
plugin.updateUser(jid, password,name,email);
replyMessage("ok",response,out);
//xmlProvider.sendInfo(request, response, presence);
}
else {
Log.warn("The userService servlet received an invalid request of type: " + type);
// TODO Do something
}
}
catch (UserAlreadyExistsException e) {
replyError("UserAlreadyExistsException",response, out);
}
catch (UserNotFoundException e) {
replyError("UserNotFoundException",response, out);
}
catch (IllegalArgumentException e) {
replyError("IllegalArgumentException",response, out);
}
catch (Exception e) {
replyError(e.toString(),response, out);
}
}
private void replyMessage(String message,HttpServletResponse response, PrintWriter out){
response.setContentType("text/xml");
out.println("<result>" + message + "</result>");
out.flush();
}
private void replyError(String error,HttpServletResponse response, PrintWriter out){
response.setContentType("text/xml");
out.println("<error>" + error + "</error>");
out.flush();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
public void destroy() {
super.destroy();
// Release the excluded URL
AuthCheckFilter.removeExclude("userService/userservice");
}
}
\ No newline at end of file
<?xml version='1.0' encoding='ISO-8859-1'?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- Servlets -->
<servlet>
<servlet-name>UserServiceServlet</servlet-name>
<servlet-class>org.jivesoftware.wildfire.plugin.userService.UserServiceServlet</servlet-class>
</servlet>
<!-- Servlet mappings -->
<servlet-mapping>
<servlet-name>UserServiceServlet</servlet-name>
<url-pattern>/userservice</url-pattern>
</servlet-mapping>
</web-app>
<%@ page import="java.util.*,
org.jivesoftware.admin.*,
org.jivesoftware.wildfire.XMPPServer,
org.jivesoftware.util.*,
org.jivesoftware.wildfire.plugin.UserServicePlugin"
errorPage="error.jsp"
%>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%-- Define Administration Bean --%>
<jsp:useBean id="admin" class="org.jivesoftware.util.WebManager" />
<c:set var="admin" value="${admin.manager}" />
<% admin.init(request, response, session, application, out ); %>
<% // Get parameters
boolean save = request.getParameter("save") != null;
boolean success = request.getParameter("success") != null;
String secret = ParamUtils.getParameter(request, "secret");
boolean enabled = ParamUtils.getBooleanParameter(request, "enabled");
UserServicePlugin plugin = (UserServicePlugin) XMPPServer.getInstance().getPluginManager().getPlugin("userservice");
// Handle a save
Map errors = new HashMap();
if (save) {
if (errors.size() == 0) {
plugin.setEnabled(enabled);
plugin.setSecret(secret);
response.sendRedirect("user-service.jsp?success=true");
return;
}
}
secret = plugin.getSecret();
enabled = plugin.isEnabled();
%>
<html>
<head>
<title>User Service Properties</title>
<meta name="pageID" content="user-service"/>
</head>
<body>
<p>
Use the form below to enable or disable the User Service and configure the secret key.
By default the User Service plugin is <strong>disabled</strong>, which means that
HTTP requests to the service will be ignored.
</p>
<% if (success) { %>
<div class="jive-success">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr><td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td>
<td class="jive-icon-label">
User service properties edited successfully.
</td></tr>
</tbody>
</table>
</div><br>
<% } %>
<form action="user-service.jsp?save" method="post">
<fieldset>
<legend>User Service</legend>
<div>
<p>
The addition, deletion and editing of users is not normally available outside of the admin console.
This service lets those administration tasks be performed HTTP requests to provide
simple integration with other applications.</p>
<p>However, the presence of this service exposes a security risk. Therefore,
a secret key is used to validate legitimate requests to this service. For
full security, it's recommended that you deploy other security measures in front
of the user service, such as restricted network access.
</p>
<ul>
<input type="radio" name="enabled" value="true" id="rb01"
<%= ((enabled) ? "checked" : "") %>>
<label for="rb01"><b>Enabled</b> - User service requests will be processed.</label>
<br>
<input type="radio" name="enabled" value="false" id="rb02"
<%= ((!enabled) ? "checked" : "") %>>
<label for="rb02"><b>Disabled</b> - User service requests will be ignored.</label>
<br><br>
<label for="text_secret">Secret key:</label>
<input type="text" name="secret" value="<%= secret %>" id="text_secret">
</ul>
</div>
</fieldset>
<br><br>
<input type="submit" value="Save Settings">
</form>
</body>
</html>
\ No newline at end of file
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