/* * Weblounge: Web Content Management System * Copyright (c) 2003 - 2011 The Weblounge Team * http://entwinemedia.com/weblounge * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package ch.entwine.weblounge.common.impl.security; import ch.entwine.weblounge.common.impl.language.LanguageUtils; import ch.entwine.weblounge.common.impl.site.SiteImpl; import ch.entwine.weblounge.common.impl.util.config.ConfigurationUtils; import ch.entwine.weblounge.common.impl.util.xml.XPathHelper; import ch.entwine.weblounge.common.language.Language; import ch.entwine.weblounge.common.security.DigestType; import ch.entwine.weblounge.common.security.Password; import ch.entwine.weblounge.common.security.Security; import ch.entwine.weblounge.common.site.Site; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.xml.namespace.NamespaceContext; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; /** * This class represents the administrator user for a single site. */ public final class SiteAdminImpl extends WebloungeUserImpl { /** * Creates a new SiteAdminImpl user with the {@link SystemRole.SITEADMIN} role * assigned. * * @param login * the login name */ public SiteAdminImpl(String login) { super(login, Security.SYSTEM_CONTEXT); addPublicCredentials(SystemRole.SITEADMIN); setName("Site Administrator (" + login + ")"); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.impl.security.UserImpl#setRealm(java.lang.String) */ @Override public void setRealm(String realm) { throw new UnsupportedOperationException("The admin user realm cannot be changed"); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.impl.security.AuthenticatedUserImpl#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { // Overwritten to document that we are using the super implementation return super.equals(obj); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.impl.security.AuthenticatedUserImpl#hashCode() */ @Override public int hashCode() { // Overwritten to document that we are using the super implementation return super.hashCode(); } /** * Initializes this admin object by reading all information from the * <code>XML</code> configuration node. * * @param userNode * the <code>XML</code> node containing the admin configuration * @param site * the associated site */ public static SiteAdminImpl fromXml(Node userNode, Site site) throws IllegalStateException { XPath xpath = XPathFactory.newInstance().newXPath(); // Define the xml namespace xpath.setNamespaceContext(new NamespaceContext() { public String getNamespaceURI(String prefix) { return "ns".equals(prefix) ? SiteImpl.SITE_XMLNS : null; } public String getPrefix(String namespaceURI) { return null; } public Iterator<?> getPrefixes(String namespaceURI) { return null; } }); return fromXml(userNode, site, xpath); } /** * Initializes this admin object by reading all information from the * <code>XML</code> configuration node. * * @param userNode * the <code>XML</code> node containing the admin configuration * @param site * the associated site * @param xpath * the {@link XPath} processor */ public static SiteAdminImpl fromXml(Node userNode, Site site, XPath xpath) throws IllegalStateException { if (userNode == null) return null; String login = XPathHelper.valueOf(userNode, "ns:login", xpath); SiteAdminImpl user = new SiteAdminImpl(login); Node enabledAttribute = userNode.getAttributes().getNamedItem("enabled"); user.enabled = enabledAttribute == null || ConfigurationUtils.isTrue(XPathHelper.valueOf(userNode, "@enabled", xpath)); String name = XPathHelper.valueOf(userNode, "ns:name", xpath); if (name != null) { user.name = name; } else { user.firstName = XPathHelper.valueOf(userNode, "ns:firstname", xpath); user.lastName = XPathHelper.valueOf(userNode, "ns:lastname", xpath); } // E-mail user.email = XPathHelper.valueOf(userNode, "ns:email", xpath); // Language String language = XPathHelper.valueOf(userNode, "ns:language", xpath); if (language != null) { Language l = LanguageUtils.getLanguage(language); user.language = (l != null) ? l : site.getDefaultLanguage(); } // Password String password = XPathHelper.valueOf(userNode, "ns:password", xpath); if (password != null) { String digestType = null; try { digestType = XPathHelper.valueOf(userNode, "ns:password/@type", xpath); Password pw = new PasswordImpl(password, DigestType.valueOf(digestType)); user.addPrivateCredentials(pw); } catch (Throwable t) { throw new IllegalStateException("Unknown password digest found: " + digestType); } } // Properties NodeList properties = XPathHelper.selectList(userNode, "ns:properties/ns:property", xpath); if (properties != null) { for (int i = 0; i < properties.getLength(); i++) { String key = XPathHelper.valueOf(properties.item(i), "ns:name", xpath); String value = XPathHelper.valueOf(properties.item(i), "ns:value", xpath); // TODO: Check for serialized objects or xml nodes if (key != null && value != null) user.properties.put(key, value); } } return user; } /** * Returns an <code>XML</code> representation of this user. * * @return the user as an <code>XML</code> document fragment */ public String toXml() { StringBuffer b = new StringBuffer(); // Add root node b.append("<administrator"); if (!enabled) { b.append(" enabled=\"" + enabled + "\""); } b.append(">"); // Login b.append("<login>").append(login).append("</login>"); // Password Set<Object> passwords = getPrivateCredentials(Password.class); for (Object o : passwords) { Password password = (Password)o; b.append("<password type=\""); b.append(password.getDigestType().toString()); b.append("\"><![CDATA["); b.append(password.getPassword()); b.append("]]></password>"); } // First name if (firstName != null) { b.append("<firstname>"); b.append(firstName); b.append("</firstname>"); } // Last name if (lastName != null) { b.append("<lastname>"); b.append(lastName); b.append("</lastname>"); } // Name, if first name and last name were not given if (name != null && firstName == null && lastName == null) { b.append("<name><![CDATA["); b.append(name); b.append("]]></name>"); } // Email if (email != null) { b.append("<email>"); b.append(email); b.append("</email>"); } // properties if (properties != null && properties.size() > 0) { b.append("<properties>"); for (Map.Entry<String, Object> entry : properties.entrySet()) { b.append("<property>"); b.append("<name><![CDATA["); b.append(entry.getKey()); b.append("]]></name>"); b.append("<value>"); // TODO: Examine object. If XML node or serializable, serialize with // care b.append(entry.getValue().toString()); b.append("</value>"); b.append("</property>"); } b.append("</properties>"); } b.append("</administrator>"); return b.toString(); } }