/* * 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.util.xml.XPathHelper; import ch.entwine.weblounge.common.security.User; import org.w3c.dom.Node; import java.util.HashSet; import java.util.Set; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; /** * Default implementation for a weblounge user that is not logged in. This class * is primarily used for managing user references when it comes to serializing * and deserializing user data. */ public class UserImpl implements User { /** The identifier for this user in the given domain */ protected String login = null; /** The user domain */ protected String realm = null; /** The user's name */ protected String name = null; /** the public credentials set */ protected Set<Object> publicCredentials = null; /** the private credentials set */ protected Set<Object> privateCredentials = null; /** * Creates a new user with the given login. * * @param login * the login */ public UserImpl(String login) { this(login, null, null); } /** * Creates a new user with the given login and realm. * * @param login * the login * @param realm * the user realm */ public UserImpl(String login, String realm) { this(login, realm, null); } /** * Creates a new user with the given login, realm and name. * * @param login * the login * @param realm * the user realm * @param name * the name */ public UserImpl(String login, String realm, String name) { if (login == null) throw new IllegalStateException("Cannot create user without id"); this.login = login; this.realm = realm; this.name = name; } /** * Creates a user from an existing user. This constructor is intended to * transform special users such as the site administrator to regular ones. * * @param user * the user */ public UserImpl(User user) { this.login = user.getLogin(); this.realm = user.getRealm(); this.name = user.getName(); for (Object o : user.getPublicCredentials()) addPublicCredentials(o); for (Object o : user.getPrivateCredentials()) addPrivateCredentials(o); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.security.User#getLogin() */ public String getLogin() { return login; } /** * Sets the display name for the user. * * @param name * the display name */ public void setName(String name) { this.name = name; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.security.User#getName() */ public String getName() { return name; } /** * Sets the domain where the user is registered. Using the realm, a user can * be defined in an external system that is connected using a user service * instead of defining it in the system itself. * * @param realm * the user realm */ public void setRealm(String realm) { // TODO: Ensure that the realm is suitable as an xml attribute this.realm = realm; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.security.User#getRealm() */ public String getRealm() { return realm; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.security.User#addPrivateCredentials(java.lang.Object[]) */ public void addPrivateCredentials(Object... credentials) { if (privateCredentials == null) { privateCredentials = new HashSet<Object>(); } for (Object o : credentials) { privateCredentials.add(o); } } /** * Removes the private credentials from this user. * * @param credentials * the credentials * @return <code>true</code> if the credentials was removed */ public boolean removePrivateCredentials(Object credentials) { if (privateCredentials == null) return false; return privateCredentials.remove(credentials); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.security.User#getPrivateCredentials() */ public Set<Object> getPrivateCredentials() { if (privateCredentials != null) { return privateCredentials; } else { return new HashSet<Object>(); } } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.security.User#getPrivateCredentials(java.lang.Class) */ public Set<Object> getPrivateCredentials(Class<?> type) { Set<Object> set = new HashSet<Object>(); if (privateCredentials != null) { for (Object c : privateCredentials) { if (type.isAssignableFrom(c.getClass())) set.add(c); } } return set; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.security.User#addPublicCredentials(java.lang.Object[]) */ public void addPublicCredentials(Object... credentials) { if (publicCredentials == null) { publicCredentials = new HashSet<Object>(); } for (Object o : credentials) { publicCredentials.add(o); } } /** * Removes the public credentials from this user. * * @param credentials * the credentials * @return <code>true</code> if the credentials was removed */ public boolean removePublicCredentials(Object credentials) { if (publicCredentials == null) return false; return publicCredentials.remove(credentials); } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.security.User#getPublicCredentials() */ public Set<Object> getPublicCredentials() { if (publicCredentials != null) { return publicCredentials; } else { return new HashSet<Object>(); } } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.security.User#getPublicCredentials(java.lang.Class) */ public Set<Object> getPublicCredentials(Class<?> type) { Set<Object> set = new HashSet<Object>(); if (publicCredentials != null) { for (Object c : publicCredentials) { if (type.isAssignableFrom(c.getClass())) set.add(c); } } return set; } /** * This method will create a user from the given <code>XML</code> node or * <code>null</code> if no user information is contained in the node. * * <p> * The input is expected as: * * <pre> * <user id="login" realm="realm">Jon Doe</user> * </pre> * * @param xml * the XML node * @return the user or <code>null</code> if */ public static UserImpl fromXml(Node xml) { XPath xpathProcessor = XPathFactory.newInstance().newXPath(); return fromXml(xml, xpathProcessor); } /** * This method will create a user from the given <code>XML</code> node or * <code>null</code> if no user information is contained in the node. * * <p> * The input is expected as: * * <pre> * <user id="login" realm="realm">Jon Doe</user> * </pre> * * @param xml * the XML node * @param xpath * the XPATH object * @return the user or <code>null</code> if */ public static UserImpl fromXml(Node xml, XPath xpath) { String login = XPathHelper.valueOf(xml, "@id", xpath); if (login == null) throw new IllegalStateException("Found user node without id"); String realm = XPathHelper.valueOf(xml, "@realm", xpath); String name = XPathHelper.valueOf(xml, "text()", xpath); UserImpl user = new UserImpl(login, realm, name); return user; } /** * {@inheritDoc} * * @see java.lang.Object#clone() */ @Override public Object clone() throws CloneNotSupportedException { UserImpl user = (UserImpl) super.clone(); user.login = login; user.realm = realm; user.name = name; return user; } /** * {@inheritDoc} * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return login.hashCode(); } /** * {@inheritDoc} * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj instanceof User) { User u = (User) obj; if (realm != null && !realm.equals(u.getRealm())) return false; if (u.getRealm() != null && realm == null) return false; return login.equals(u.getLogin()); } return super.equals(obj); } /** * {@inheritDoc} * * @see java.lang.Object#toString() */ @Override public String toString() { return (name != null) ? name : login; } /** * {@inheritDoc} * * @see ch.entwine.weblounge.common.security.User#toXml() */ public String toXml() { StringBuffer buf = new StringBuffer(); buf.append("<user"); // id buf.append(" id=\""); buf.append(login); buf.append("\""); // realm if (realm != null) { buf.append(" realm=\""); buf.append(realm); buf.append("\""); } buf.append(">"); // name if (name != null) { buf.append("<![CDATA[").append(name).append("]]>"); } buf.append("</user>"); return buf.toString(); } }