/*
* Copyright 2006-2010 Daniel Henninger. 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 net.sf.kraken.web;
import net.sf.kraken.BaseTransport;
import net.sf.kraken.KrakenPlugin;
import net.sf.kraken.permissions.PermissionManager;
import net.sf.kraken.registration.Registration;
import net.sf.kraken.registration.RegistrationHandler;
import net.sf.kraken.type.TransportType;
import net.sf.kraken.session.TransportSession;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.group.Group;
import org.jivesoftware.openfire.group.GroupManager;
import org.jivesoftware.openfire.group.GroupNotFoundException;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.NotFoundException;
import org.jivesoftware.util.LocaleUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Attribute;
import org.xmpp.packet.JID;
import org.apache.log4j.Logger;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
/**
* Transport Configuration Manager (for web interface)
*
* Handles web interface interactions with the transport instances, such as enabling or
* disabling them, configuring options, etc.
*
* @author Daniel Henninger
*/
public class ConfigManager {
static Logger Log = Logger.getLogger(ConfigManager.class);
/**
* Toggles whether a transport is enabled or disabled.
*
* @param transportName Name of the transport to be enabled or disabled (type of transport)
* @return True or false if the transport is enabled after this call.
*/
public boolean toggleTransport(String transportName) {
PluginManager pluginManager = XMPPServer.getInstance().getPluginManager();
KrakenPlugin plugin = (KrakenPlugin)pluginManager.getPlugin("kraken");
if (!plugin.serviceEnabled(transportName)) {
plugin.enableService(transportName);
return true;
}
else {
plugin.disableService(transportName);
return false;
}
}
/**
* Saves settings from options screen.
*
* @param transportName Name of the transport to have it's options saved (type of transport)
* @param options Options passed from options form.
*/
public void saveSettings(String transportName, HashMap<String,String> options) {
PluginManager pluginManager = XMPPServer.getInstance().getPluginManager();
KrakenPlugin plugin = (KrakenPlugin)pluginManager.getPlugin("kraken");
Document optConfig = plugin.getOptionsConfig(TransportType.valueOf(transportName));
Element leftPanel = optConfig.getRootElement().element("leftpanel");
if (leftPanel != null && leftPanel.nodeCount() > 0) {
for (Object nodeObj : leftPanel.elements("item")) {
Element node = (Element)nodeObj;
saveOptionSetting(node, options);
}
}
Element rightPanel = optConfig.getRootElement().element("rightpanel");
if (rightPanel != null && rightPanel.nodeCount() > 0) {
for (Object nodeObj : rightPanel.elements("item")) {
Element node = (Element)nodeObj;
saveOptionSetting(node, options);
}
}
Element bottomPanel = optConfig.getRootElement().element("bottompanel");
if (bottomPanel != null && bottomPanel.nodeCount() > 0) {
for (Object nodeObj : bottomPanel.elements("item")) {
Element node = (Element)nodeObj;
saveOptionSetting(node, options);
}
}
}
/**
* Helper function designed to handle saving option type.
*
* @param node Node describing the configuration item.
* @param options Options passed from form.
*/
private void saveOptionSetting(Element node, HashMap<String,String> options) {
Attribute type = node.attribute("type");
if (type.getText().equals("text")) {
// Required fields
Attribute desckey = node.attribute("desckey");
Attribute var = node.attribute("var");
Attribute sysprop = node.attribute("sysprop");
if (desckey == null || var == null || sysprop == null) {
Log.error("Missing variable from options config.");
return;
}
// Process any variables that we are setting.
JiveGlobals.setProperty(sysprop.getText(), options.get(var.getText()));
}
else if (type.getText().equals("toggle")) {
// Required fields
Attribute desckey = node.attribute("desckey");
Attribute var = node.attribute("var");
Attribute sysprop = node.attribute("sysprop");
if (desckey == null || var == null || sysprop == null) {
Log.error("Missing variable from options config.");
return;
}
// Process any variables that we are setting.
JiveGlobals.setProperty(sysprop.getText(), options.get(var.getText()));
// Process any sub-fields.
for (Object itemObj : node.elements("item")) {
Element item = (Element)itemObj;
Log.debug("Found web item "+item);
saveOptionSetting(item, options);
}
}
}
/**
* Saves permissions settings from web interface.
*
* We validate all of the groups before actually adding them.
*
* @param transportName Name of the transport to have it's options saved (type of transport)
* @param overallSetting The general "all(1), some(2), or none(3)" setting for the permissions.
* @param users List of specific users that have access.
* @param groups List of specific groups that have access.
* @param strict Strict permissions associted with setting.
* @return List of usernames and groups (@ preceded) that were rejected.
*/
public List<String> savePermissions(String transportName, Integer overallSetting, List<String> users, List<String> groups, Boolean strict) {
JiveGlobals.setProperty("plugin.gateway."+transportName+".registration", overallSetting.toString());
JiveGlobals.setProperty("plugin.gateway."+transportName+".registrationstrict", strict ? "true" : "false");
PermissionManager permissionManager = new PermissionManager(TransportType.valueOf(transportName));
List<String> errorList = new ArrayList<String>();
ArrayList<User> userList = new ArrayList<User>();
UserManager userManager = UserManager.getInstance();
for (String username : users) {
if (username.matches("\\s*")) { continue; }
try {
if (username.contains("@")) {
JID jid = new JID(username);
if (!jid.getDomain().equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
throw new UserNotFoundException();
}
username = username.substring(0, username.indexOf("@"));
}
User user = userManager.getUser(username);
if (user == null || user.getUsername() == null) { throw new UserNotFoundException(); }
userList.add(user);
}
catch (UserNotFoundException e) {
Log.warn("User "+username+" not found while adding access rules.");
errorList.add(username);
}
}
permissionManager.storeUserList(userList);
ArrayList<Group> groupList = new ArrayList<Group>();
GroupManager groupManager = GroupManager.getInstance();
for (String grpname : groups) {
if (grpname.matches("\\s*")) { continue; }
try {
Group group = groupManager.getGroup(grpname);
if (group == null || group.getName() == null) { throw new GroupNotFoundException(); }
groupList.add(group);
}
catch (GroupNotFoundException e) {
Log.warn("Group "+grpname+" not found while adding access rules.");
errorList.add("@"+grpname);
}
}
permissionManager.storeGroupList(groupList);
return errorList;
}
/**
* Adds a new registration via the web interface.
*
* @param user Username or full JID of user who is getting an account registered.
* @param transportType Type of transport to add user to.
* @param legacyUsername User's username on the legacy service.
* @param legacyPassword User's password on the legacy service.
* @param legacyNickname User's nickname on the legacy service.
* @return Error message or null on success.
*/
public String addRegistration(String user, String transportType, String legacyUsername, String legacyPassword, String legacyNickname) {
PluginManager pluginManager = XMPPServer.getInstance().getPluginManager();
KrakenPlugin plugin = (KrakenPlugin)pluginManager.getPlugin("kraken");
JID jid;
if (user.contains("@")) {
jid = new JID(user);
}
else {
jid = new JID(user, XMPPServer.getInstance().getServerInfo().getXMPPDomain(), null);
}
if (!plugin.getTransportInstance(transportType).isEnabled()) {
return LocaleUtils.getLocalizedString("gateway.web.registrations.notenabled", "kraken");
}
try {
final BaseTransport transport = plugin.getTransportInstance(transportType).getTransport();
new RegistrationHandler(transport).addNewRegistration(jid, legacyUsername, legacyPassword, legacyNickname, false);
return null;
}
catch (UserNotFoundException e) {
Log.error("Not found while adding account for "+jid.toString());
return LocaleUtils.getLocalizedString("gateway.web.registrations.xmppnotfound", "kraken");
}
catch (IllegalAccessException e) {
Log.error("Domain of JID specified for registration is not on this server: "+jid.toString());
return LocaleUtils.getLocalizedString("gateway.web.registrations.illegaldomain", "kraken");
}
catch (IllegalArgumentException e) {
Log.error("Username specified for registration is not valid.");
return LocaleUtils.getLocalizedString("gateway.web.registrations.invaliduser", "kraken");
}
}
/**
* Deletes a registration via the web interface.
*
* @param registrationID ID number associated with registration to delete.
* @return Error message or null on success.
*/
public String deleteRegistration(Integer registrationID) {
PluginManager pluginManager = XMPPServer.getInstance().getPluginManager();
KrakenPlugin plugin = (KrakenPlugin)pluginManager.getPlugin("kraken");
try {
Registration reg = new Registration(registrationID);
if (!plugin.getTransportInstance(reg.getTransportType().toString()).isEnabled()) {
return LocaleUtils.getLocalizedString("gateway.web.registrations.notenabled", "kraken");
}
final BaseTransport transport = plugin.getTransportInstance(reg.getTransportType().toString()).getTransport();
new RegistrationHandler(transport).deleteRegistration(reg.getJID());
return null;
}
catch (NotFoundException e) {
// Ok, nevermind.
Log.error("Not found while deleting id "+registrationID, e);
return LocaleUtils.getLocalizedString("gateway.web.registrations.xmppnotfound", "kraken");
}
catch (UserNotFoundException e) {
// Ok, nevermind.
Log.error("Not found while deleting id "+registrationID, e);
return LocaleUtils.getLocalizedString("gateway.web.registrations.regnotfound", "kraken");
}
}
/**
* Updates a registration via the web interface.
*
*
* @param registrationID ID number associated with registration to modify.
* @param legacyUsername User's updated username on the legacy service.
* @param legacyPassword User's updated password on the legacy service, null if no change.
* @param legacyNickname User's updated nickname on the legacy service.
* @return Error message or null on success.
*/
public String updateRegistration(Integer registrationID, String legacyUsername, String legacyPassword, String legacyNickname) {
PluginManager pluginManager = XMPPServer.getInstance().getPluginManager();
KrakenPlugin plugin = (KrakenPlugin)pluginManager.getPlugin("kraken");
try {
Registration reg = new Registration(registrationID);
if (!plugin.getTransportInstance(reg.getTransportType().toString()).isEnabled()) {
return LocaleUtils.getLocalizedString("gateway.web.registrations.notenabled", "kraken");
}
reg.setUsername(legacyUsername);
if (legacyPassword != null) {
reg.setPassword(legacyPassword);
}
reg.setNickname(legacyNickname);
return null;
}
catch (NotFoundException e) {
// Ok, nevermind.
Log.error("Not found while editing id "+registrationID, e);
return LocaleUtils.getLocalizedString("gateway.web.registrations.regnotfound", "kraken");
}
}
/**
* Logs out session via the web interface.
*
*
* @param registrationID ID number associated with registration to log off.
* @return registration ID on success, -1 on failure (-1 so that js cb_logoutSession knows which Div to edit)
*/
public Integer logoutSession(Integer registrationID)
{
try
{
PluginManager pluginManager = XMPPServer.getInstance().getPluginManager();
KrakenPlugin plugin = (KrakenPlugin)pluginManager.getPlugin("kraken");
Registration registration = new Registration(registrationID);
if (!plugin.getTransportInstance(registration.getTransportType().toString()).isEnabled()) {
return -1;
}
JID jid = registration.getJID();
TransportSession session = plugin.getTransportInstance(registration.getTransportType().toString()).getTransport().getSessionManager().getSession(jid);
plugin.getTransportInstance(registration.getTransportType().toString()).getTransport().registrationLoggedOut(session);
return registrationID;
}
catch(NotFoundException e)
{
return -1;
}
}
}