----
Here is the source code to the WebApplication plugin.  Someone may find this useful in developing their own plugins.  Same rules on how to make the package structure. ([Third Party])

This plugin expects a user.XML file response, a VFS.XML file response, and a custom VFS items response...example provided below:

{{{
<?xml version="1.0" encoding="UTF-8"?>
<VFS type="vector">
        <VFS_subitem type="properties">
                <type>FILE</type>
                <dir>/</dir>
                <name>HOME</name>
                <data type="vector">                            
                        <data_subitem type="properties">
                                <url>FILE://home/crushftp/testuser1/HOME/</url>
                                <type>DIR</type>                        
                        </data_subitem>
                </data>
        </VFS_subitem>
</VFS>}}}

----
Start.java
----
%%prettify 
{{{
package WebApplication;

import java.util.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import crushftp.handlers.Common;
import crushftp.handlers.SessionCrush;
import crushftp.handlers.UserTools;
import crushftp.server.ServerStatus;

public class Start implements Serializable
{
	Properties settings = new Properties();
	String version = "5.0.4";
	Common c = new Common();

	public Properties getDefaults()
	{
		Properties p = new Properties();
		p.put("enabled", "false");
		p.put("debug", "false");
		p.put("user_url", "http://127.0.0.1/auth/user_properties.xml");
		p.put("user_post_data", "");
		p.put("permissions_url", "http://127.0.0.1/auth/vfs_properties.xml");
		p.put("permissions_post_data", "");
		p.put("vfs_url", "http://127.0.0.1/auth/vfs_vectors.xml");
		p.put("vfs_post_data", "");
		p.put("method", "GET");
		p.put("username", "%username%");
		p.put("password", c.encode_pass("%password%", "DES"));
		p.put("usernameTemplate", "");
		p.put("overwrite_vfs", "true");
		p.put("server_item", "All");
		p.put("version", version);
		return p;
	}

	public void setSettings(Properties p) throws Exception
	{
		settings = p;
	}

	public Properties getSettings()
	{
		settings.put("version", version);
		return settings;
	}

	public Object run(Properties info)
	{
		if (!settings.getProperty("enabled").equalsIgnoreCase("true")) return null;
		if (info.getProperty("action", "").equals("login"))
		{
			Properties user_info = (Properties) info.get("user_info");
			if (user_info == null) user_info = new Properties();
			if (info.getProperty("action", "").equals("login") && (get("server_item").trim().equalsIgnoreCase("All") || get("server_item").trim().length() == 0 || user_info.getProperty("listen_ip_port", "").equals(get("server_item").trim())))
			{
				loadUser(info);
			}
		}
		return null;
	}

	public String replace_vars(String the_line, String username, String password)
	{
		try
		{
			the_line = Common.replace_str(the_line, "%user_name%", username);
		}
		catch (Exception e)
		{
		}
		try
		{
			the_line = Common.replace_str(the_line, "%username%", username);
		}
		catch (Exception e)
		{
		}
		try
		{
			the_line = Common.replace_str(the_line, "%user_password%", password);
		}
		catch (Exception e)
		{
		}
		try
		{
			the_line = Common.replace_str(the_line, "%user_pass%", password);
		}
		catch (Exception e)
		{
		}
		try
		{
			the_line = Common.replace_str(the_line, "%password%", password);
		}
		catch (Exception e)
		{
		}
		return the_line;

	}

	public void loadUser(Properties info)
	{
		boolean found_user = false;
		//we set a bunch of values to the defaults since we don't have options for them in LDAP
		Properties user = (Properties) info.get("user");
		Properties user_info = (Properties) info.get("user_info");
		SessionCrush thisSession = (SessionCrush) info.get("ServerSession");
		String username = info.getProperty("username");
		String password = info.getProperty("password");
		username = username.replaceAll("/", "");
		username = username.replaceAll("\\\\", "");
		try
		{
			msg("Checking login information for user.");
			if (!password.trim().equals("") || info.getProperty("publickey_lookup", "false").equals("true") || info.getProperty("anyPass", "false").equals("true"))
			{
				//user.XML
				String url = replace_vars(get("user_url"), username, password);
				String post_data = replace_vars(get("user_post_data"), username, password);
				try
				{
					url = ServerStatus.thisObj.change_vars_to_values(url, thisSession);
				}
				catch (Exception e)
				{
				}
				try
				{
					post_data = ServerStatus.thisObj.change_vars_to_values(post_data, thisSession);
				}
				catch (Exception e)
				{
				}
				String userXML = getResult(url, post_data, replace_vars(get("username"), username, password), replace_vars(c.decode_pass(get("password")), username, password));
				Properties theUser = (Properties) Common.readXMLObject(new ByteArrayInputStream(userXML.getBytes("UTF8")));
				theUser.put("username", username);
				theUser.put("password", c.encode_pass(password, "DES"));

				//VFS.XML
				url = replace_vars(get("permissions_url"), username, password);
				post_data = replace_vars(get("permissions_post_data"), username, password);
				try
				{
					url = ServerStatus.thisObj.change_vars_to_values(url, thisSession);
				}
				catch (Exception e)
				{
				}
				try
				{
					post_data = ServerStatus.thisObj.change_vars_to_values(post_data, thisSession);
				}
				catch (Exception e)
				{
				}
				String permissionsXML = getResult(url, post_data, replace_vars(get("username"), username, password), replace_vars(c.decode_pass(get("password")), username, password));
				Properties permissions = (Properties) Common.readXMLObject(new ByteArrayInputStream(permissionsXML.getBytes("UTF8")));

				//VFS items XML
				url = replace_vars(get("vfs_url"), username, password);
				post_data = replace_vars(get("vfs_post_data"), username, password);
				try
				{
					url = ServerStatus.thisObj.change_vars_to_values(url, thisSession);
				}
				catch (Exception e)
				{
				}
				try
				{
					post_data = ServerStatus.thisObj.change_vars_to_values(post_data, thisSession);
				}
				catch (Exception e)
				{
				}
				String vfsXML = getResult(url, post_data, replace_vars(get("username"), username, password), replace_vars(c.decode_pass(get("password")), username, password));
				Vector VFSItems = (Vector) Common.readXMLObject(new ByteArrayInputStream(vfsXML.getBytes("UTF8")));

				msg("Credentials OK.");
				msg("got users information:" + theUser);
				if (theUser != null)
				{
					boolean loadedUser = loadTemplateUser(user, info);
					found_user = true;
					user.putAll(theUser);

					String users_path = System.getProperty("crushftp.plugins") + "plugins/WebApplication_VFS/" + username;
					msg("Creating file system for user...");

					info.put("VFSItems", VFSItems);
					info.put("permissions", permissions);
					info.put("uVFS", users_path);
					info.put("templateUser", get("usernameTemplate"));
					info.put("overwrite_vfs", get("overwrite_vfs"));
					user.put("root_dir", "/");

					msg("User loaded.");
				}
			}
		}
		catch (Exception e)
		{
			msg(e);
		}

		msg("found_user:" + found_user);
		if (found_user)
		{
			info.put("action", "success");
		}
	}

	public String getResult(String url, String post_data, String username, String password) throws Exception
	{
		String stars = "******************************************************************************************************************************************";
		msg("getResult..url:" + url);
		msg("getResult...post_data:" + post_data);
		msg("getResult...username:" + username);
		msg("getResult...password:" + stars.substring(0, password.length()));
		HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
		connection.setDoOutput(get("method").equalsIgnoreCase("POST"));
		connection.setDoInput(true);
		if (username.trim().length() > 0)
		{
			String authString = username + ":" + password;
			String auth = "Basic " + new sun.misc.BASE64Encoder().encode(authString.getBytes());
			connection.setRequestProperty("Authorization", auth);
		}
		byte dataBytes[] = post_data.getBytes();
		connection.setRequestMethod(get("method"));
		if (get("method").equalsIgnoreCase("POST"))
		{
			connection.setRequestProperty("Content-Length", dataBytes.length + "");
			//connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			OutputStream os = connection.getOutputStream();
			os.write(dataBytes);
			os.flush();
		}

		BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF8"));

		String decodedString;
		String allData = "";
		while ((decodedString = in.readLine()) != null)
		{
			allData += decodedString + "\r\n";
		}
		in.close();
		msg(allData);
		return allData.trim();
	}

	public boolean checkLogin(String username, String password) throws Exception
	{
		msg("CheckLogin...username:" + username);
		return true;//no error, login was ok.
	}

	public boolean loadTemplateUser(Properties user, Properties info)
	{
		boolean loadedUser = false;
		if (!settings.getProperty("usernameTemplate").equals("") && Common.V() < 6)
		{
			try
			{
				Properties server_item = (Properties) info.get("server_item");
				String listen_ip_port = server_item.getProperty("ip") + "_" + server_item.getProperty("port");
				String listen_ip_port2 = server_item.getProperty("linkedServer");
				msg("Searching for template user in server item:" + listen_ip_port);
				msg("Raw server_item:" + server_item);
				Properties p = UserTools.ut.getUser(listen_ip_port, settings.getProperty("usernameTemplate"), false, false);
				if (p == null) p = UserTools.ut.getUser(listen_ip_port2, settings.getProperty("usernameTemplate"), false, false);
				if (p != null)
				{
					Enumeration keys = p.keys();
					msg("Setting usernameTemplate's settings:" + p.size());
					while (keys.hasMoreElements())
					{
						String key = keys.nextElement().toString();
						if (!key.equalsIgnoreCase("username") && !key.equalsIgnoreCase("user_name") && !key.equalsIgnoreCase("password")) try
						{
							user.put(key, p.get(key));
						}
						catch (Exception e)
						{
						}
					}
					if (user.getProperty("max_logins", "0").equals("-1")) user.put("max_logins", "0");
					loadedUser = true;
				}
				else msg("Template user not found.");
				msg("Load template user complete.");
			}
			catch (Exception e)//no default user found, use template instead.
			{
				msg(e);
			}
		}
		user.put("virtualUser", "true");
		return loadedUser;
	}

	public String get(String key)
	{
		return settings.getProperty(key);
	}

	public void msg(String s)
	{
		if (settings.getProperty("debug").equals("true")) crushftp.handlers.Common.debug(0, "WebApplication:" + s);
	}

	public void msg(Exception e)
	{
		if (settings.getProperty("debug").equals("true")) crushftp.handlers.Common.debug(0, e);
	}
}
}}}
/%