Package org.jahia.services.usermanager.jcr

Source Code of org.jahia.services.usermanager.jcr.JCRUser

/**
* This file is part of Jahia, next-generation open source CMS:
* Jahia's next-generation, open source CMS stems from a widely acknowledged vision
* of enterprise application convergence - web, search, document, social and portal -
* unified by the simplicity of web content management.
*
* For more information, please visit http://www.jahia.com.
*
* Copyright (C) 2002-2011 Jahia Solutions Group SA. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU 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.
*
* As a special exception to the terms and conditions of version 2.0 of
* the GPL (or any later version), you may redistribute this Program in connection
* with Free/Libre and Open Source Software ("FLOSS") applications as described
* in Jahia's FLOSS exception. You should have received a copy of the text
* describing the FLOSS exception, and it is also available here:
* http://www.jahia.com/license
*
* Commercial and Supported Versions of the program (dual licensing):
* alternatively, commercial and supported versions of the program may be used
* in accordance with the terms and conditions contained in a separate
* written agreement between you and Jahia Solutions Group SA.
*
* If you are unsure which license is appropriate for your use,
* please contact the sales department at sales@jahia.com.
*/

package org.jahia.services.usermanager.jcr;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.jahia.registries.ServicesRegistry;
import org.jahia.services.content.JCRNodeWrapper;
import org.jahia.services.content.JCRSessionWrapper;
import org.jahia.services.content.JCRTemplate;
import org.jahia.services.content.JCRCallback;
import org.jahia.services.content.decorator.JCRUserNode;
import org.jahia.services.pwdpolicy.JahiaPasswordPolicyService;
import org.jahia.services.pwdpolicy.PasswordHistoryEntry;
import org.jahia.services.usermanager.*;

import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;

import java.util.List;
import java.util.Properties;

/**
* Implementation of JahiaUser using the JCR API
*
* @author rincevent
* @since JAHIA 6.5
* Created : 7 juil. 2009
*/
public class JCRUser implements JahiaUser, JCRPrincipal {
    private static final long serialVersionUID = 4032549320399420578L;
  private transient static Logger logger = LoggerFactory.getLogger(JCRUser.class);
    protected static final String ROOT_USER_UUID = "b32d306a-6c74-11de-b3ef-001e4fead50b";
    private static final String PROVIDER_NAME = "jcr";
    private final String nodeUuid;
    static final String J_PASSWORD = "j:password";
    public static final String J_EXTERNAL = "j:external";
    public static final String J_EXTERNAL_SOURCE = "j:externalSource";
    private String name;
    private Properties properties;
    private UserProperties userProperties;
    private boolean external;
  private List<PasswordHistoryEntry> passwordHistory;
    private String path = null;

    public JCRUser(String nodeUuid) {
        this(nodeUuid, false);
    }

    public JCRUser(String nodeUuid, boolean isExternal) {
        super();
        this.nodeUuid = nodeUuid;
        this.external = isExternal;
    }


    /**
     * Return the unique user's username ( = his user key )
     *
     * @return Return a String representation of the user. In Jahia this
     *         corresponds to the user key, which is unique within a Jahia system.
     */
    public String getName() {
        if (name == null) {
            try {
                return JCRTemplate.getInstance().doExecuteWithSystemSession(new JCRCallback<String>() {
                    public String doInJCR(JCRSessionWrapper session) throws RepositoryException {
                        name = getNode(session).getName();
                        return name;
                    }
                });
            } catch (RepositoryException e) {
                logger.error("Error while retrieving the user's name", e);
                return "";
            }
        } else {
            return name;
        }
    }

    public JCRNodeWrapper getNode(JCRSessionWrapper session) throws RepositoryException {
        return session.getNodeByIdentifier(getIdentifier());
    }

    /**
     * Return the user username.
     *
     * @return Return the username.
     */
    public String getUsername() {
        return getName();
    }

    /**
     * Return the unique String identifier of this user.
     *
     * @return the unique String identifier of this user.
     */
    public String getUserKey() {
        return "{jcr}" + getName();
    }

    /**
     * Get user's properties list.
     * The properties here should not be modified, as the modifications will
     * not be serialized. Use the setProperty() method to modify a user's
     * properties.
     *
     * @return Return a reference on the user's properties list, or null if no
     *         property is present.
     */
    public Properties getProperties() {
        if (properties == null) {
            properties = new Properties();
            try {
                return JCRTemplate.getInstance().doExecuteWithSystemSession(new JCRCallback<Properties>() {
                    public Properties doInJCR(JCRSessionWrapper session) throws RepositoryException {
                        PropertyIterator iterator = getNode(session).getProperties();
                        for (; iterator.hasNext();) {
                            Property property = iterator.nextProperty();
                            if (!property.getDefinition().isMultiple()) {
                                properties.put(property.getName(), property.getString());
                            } else if (property.getType() == PropertyType.UNDEFINED) {
                                Value[] vals = null;
                                try {
                                    vals = property.getValues();
                                } catch (ValueFormatException e) {
                                    try {
                                        vals = new Value[] { property.getValue() };
                                    } catch (ValueFormatException e1) {
                                        // ignore
                                    }
                                }
                                if (vals != null && vals.length == 1) {
                                    properties.put(property.getName(), vals[0].getString());
                                }
                            }
                        }
                        return properties;
                    }
                });
            } catch (RepositoryException e) {
                logger.error("Error while retrieving properties",e);
            }
        }
        return properties;
    }

    /**
     * Returns the users properties format, in which we can test if a property
     * is read-only or not.
     * The properties here should not be modified, as the modifications will
     * not be serialized. Use the setProperty() method to modify a user's
     * properties.
     *
     * @return UserProperties
     */
    public UserProperties getUserProperties() {
        if (userProperties == null) {
            userProperties = new UserProperties();
            try {
                return JCRTemplate.getInstance().doExecuteWithSystemSession(new JCRCallback<UserProperties>() {
                    public UserProperties doInJCR(JCRSessionWrapper session) throws RepositoryException {
                        PropertyIterator iterator = getNode(session).getProperties();
                        for (; iterator.hasNext();) {
                            Property property = iterator.nextProperty();
                            if(property instanceof JCRUserNode.JCRUserProperty) {
                                userProperties.setUserProperty(property.getName(), new UserProperty(property.getName(),
                                                                                                    property.getString(),
                                                                                                    true));
                            } else if (property.getDefinition() != null && !property.getDefinition().isMultiple()) {
                                userProperties.setUserProperty(property.getName(), new UserProperty(property.getName(),
                                                                                                    property.getString(),
                                                                                                    false));
                            }
                        }
                        return userProperties;
                    }
                });
            } catch (RepositoryException e) {
                logger.error("Error while retrieving user properties", e);
            }
        }
        return userProperties;
    }

    /**
     * Retrieve the requested user property.
     *
     * @param key Property's name.
     * @return Return the property's value of the specified key, or null if the
     *         property does not exist.
     */
    public String getProperty(String key) {
        return getProperties().getProperty(key);
    }

    /**
     * Retrieves the user property object, so that we can test is the property
     * is read-only or not.
     *
     * @param key String
     * @return UserProperty
     */
    public UserProperty getUserProperty(String key) {
        return getUserProperties().getUserProperty(key);
    }

    /**
     * Remove the specified property from the properties list.
     * This method can fail and do no modification is the property we are
     * trying to set is read-only.
     *
     * @param key Property's name.
     * @return true if everything went well
     */
    public boolean removeProperty(final String key) {
        try {
            return JCRTemplate.getInstance().doExecuteWithSystemSession(new JCRCallback<Boolean>() {
                public Boolean doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    Node node = getNode(session);
                    Property property = node.getProperty(key);
                    if (property != null) {
                        session.checkout(node);
                        property.remove();
                        session.save();
                        properties = null;
                        userProperties = null;
                        return Boolean.TRUE;
                    }
                    return Boolean.FALSE;
                }
            });
        } catch (RepositoryException e) {
            logger.warn("Error while removing property", e);
        }
        return false;
    }

    /**
     * Add (or update if not already in the property list) a property key-value
     * pair in the user's properties list.
     * This method can fail and do no modification is the property we are
     * trying to set is read-only.
     *
     * @param key   Property's name.
     * @param value Property's value.
     * @return true if everything went well
     */
    public boolean setProperty(final String key, final String value) {
        try {
            if (J_EXTERNAL.equals(key)) {
                external = Boolean.valueOf(value);
            }
            return JCRTemplate.getInstance().doExecuteWithSystemSession(new JCRCallback<Boolean>() {
                public Boolean doInJCR(JCRSessionWrapper session) throws RepositoryException {
                    Node node = getNode(session);
                    session.checkout(node);
                    node.setProperty(key, value);
                    session.save();
                    properties = null;
                    userProperties = null;
                    return Boolean.TRUE;
                }
            });
        } catch (RepositoryException e) {
            logger.warn("Error while setting user property " + key + " with value " + value + " for user " + name, e);
        }
        return false;
    }

    /**
     * Method to test if the password is read-only
     *
     * @return boolean
     */
    public boolean isPasswordReadOnly() {
        return false;
    }

    /**
     * Change the user's password.
     *
     * @param password New user's password
     * @return Return true if the password was successfully changed, false
     *         otherwise
     */
    public boolean setPassword(String password) {
        return setProperty(J_PASSWORD, JahiaUserManagerService.encryptPassword(password));
    }

    /**
     * Test if the user is member of the specified group.
     *
     * @param name   Groupname.
     * @param siteID the site id
     * @return Return true if the user is member of the specified group, or
     *         false on any error.
     */
    public boolean isMemberOfGroup(int siteID, String name) {
        if (JahiaGroupManagerService.GUEST_GROUPNAME.equals(name)) {
            return true;
        }
        if (JahiaGroupManagerService.USERS_GROUPNAME.equals(name)) {
            return !JahiaUserManagerService.GUEST_USERNAME.equals(getName());
        }
        if (isRoot() && JahiaGroupManagerService.POWERFUL_GROUPS.contains(name)) {
            return true;
        }
       
        // Get the services registry
        ServicesRegistry servicesRegistry = ServicesRegistry.getInstance();
        if (servicesRegistry != null) {

            // get the group management service
            JahiaGroupManagerService groupService = servicesRegistry.getJahiaGroupManagerService();

            // lookup the requested group
            JahiaGroup group = groupService.lookupGroup(siteID, name);
            if (group != null) {
                return group.isMember(this);
            }
        }
        return false;
    }

    /**
     * Test if the user is an admin member
     *
     * @param siteID the site id
     * @return Return true if the user is an admin member
     *         false on any error.
     */
    public boolean isAdminMember(int siteID) {
        return isRoot() || isMemberOfGroup(siteID, siteID == 0 ? JahiaGroupManagerService.ADMINISTRATORS_GROUPNAME : JahiaGroupManagerService.SITE_ADMINISTRATORS_GROUPNAME);
    }

    /**
     * Test if the user is the root user
     *
     * @return Return true if the user is the root user
     *         false on any error.
     */
    public boolean isRoot() {
        return nodeUuid.equals(ROOT_USER_UUID);
    }

    /**
     * Verify if the passed in password is the same as the encapsulated by this
     * user.
     *
     * @param password String representation of an non-encrypted password.
     * @return Return true if the passed in password is the same as the
     *         encapsulated password in this user, and return false on any error.
     */
    public boolean verifyPassword(String password) {
        return getProperty(J_PASSWORD).equals(JahiaUserManagerService.encryptPassword(password));
    }

    /**
     * Get the name of the provider of this user.
     *
     * @return String representation of the name of the provider of this user
     */
    public String getProviderName() {
        return PROVIDER_NAME;
    }

    /**
     * Get the path of this user in the local store. For examle for LDAP user this will return the path of
     * the user in the JCR with all necessary encoding.
     *
     * @return String representation of the name of the provider of this user
     */
    public String getLocalPath() {
        if (path == null) {
            path = ServicesRegistry.getInstance().getJahiaUserManagerService().getUserSplittingRule().getPathForUsername(getUsername());
        }
        return path;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        JCRUser jcrUser = (JCRUser) o;

        return getIdentifier().equals(jcrUser.getIdentifier());

    }

    @Override
    public int hashCode() {
        return nodeUuid.hashCode();
    }

    @Override
    public String toString() {
        return "JCRUser{" + "nodeUuid='" + nodeUuid + '\'' + "name='" + getName() + '\'' + '}';
    }

    public String getIdentifier() {
        return nodeUuid;
    }

    /**
     * @return the external
     */
    public boolean isExternal() {
        return external;
    }

  /**
   * Returns the (encrypted) password history map, sorted by change date
   * descending, i.e. the newer passwords are at the top of the list.
   *
   * @return the (encrypted) password history list, sorted by change date
   *         descending, i.e. the newer passwords are at the top of the list
   */
  public List<PasswordHistoryEntry> getPasswordHistory() {
    if (passwordHistory == null) {
      passwordHistory = JahiaPasswordPolicyService.getInstance().getPasswordHistory(this);
    }

    return passwordHistory;
  }

  /**
   * Gets the timestamp of the last password change if available. Otherwise
   * returns <code>0</code>.
   *
   * @return the timestamp of the last password change if available. Otherwise
   *         returns <code>0</code>
   */
  public long getLastPasswordChangeTimestamp() {
    List<PasswordHistoryEntry> pwdHistory = getPasswordHistory();

    return pwdHistory.size() > 0 ? pwdHistory.get(0).getModificationDate().getTime() : 0;
  }

}
TOP

Related Classes of org.jahia.services.usermanager.jcr.JCRUser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.