/* * 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; } } }