    001package org.apache.turbine.services.security;
    002
    003
    004/*
    005 * Licensed to the Apache Software Foundation (ASF) under one
    006 * or more contributor license agreements.  See the NOTICE file
    007 * distributed with this work for additional information
    008 * regarding copyright ownership.  The ASF licenses this file
    009 * to you under the Apache License, Version 2.0 (the
    010 * "License"); you may not use this file except in compliance
    011 * with the License.  You may obtain a copy of the License at
    012 *
    013 *   http://www.apache.org/licenses/LICENSE-2.0
    014 *
    015 * Unless required by applicable law or agreed to in writing,
    016 * software distributed under the License is distributed on an
    017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    018 * KIND, either express or implied.  See the License for the
    019 * specific language governing permissions and limitations
    020 * under the License.
    021 */
    022
    023
    024import java.util.ArrayList;
    025import java.util.List;
    026
    027import org.apache.commons.configuration.Configuration;
    028import org.apache.fulcrum.security.acl.AccessControlList;
    029import org.apache.fulcrum.security.model.turbine.TurbineUserManager;
    030import org.apache.fulcrum.security.model.turbine.entity.TurbineUser;
    031import org.apache.fulcrum.security.util.DataBackendException;
    032import org.apache.fulcrum.security.util.EntityExistsException;
    033import org.apache.fulcrum.security.util.PasswordMismatchException;
    034import org.apache.fulcrum.security.util.UnknownEntityException;
    035import org.apache.fulcrum.security.util.UserSet;
    036import org.apache.turbine.om.security.DefaultUserImpl;
    037import org.apache.turbine.om.security.User;
    038import org.apache.turbine.services.ServiceManager;
    039import org.apache.turbine.services.TurbineServices;
    040import org.apache.turbine.util.ObjectUtils;
    041
    042/**
    043 * Default user manager.
    044 *
    045 * The user manager wraps Fulcrum security user objects into
    046 * Turbine-specific ones.
    047 *
    048 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
    049 * @version $Id: PassiveUserManager.java 1096130 2011-04-23 10:37:19Z ludwig $
    050 */
    051public class DefaultUserManager implements UserManager
    052{
    053    /** Fulcrum user manager instance to delegate to */
    054    private TurbineUserManager umDelegate = null;
    055
    056    /**
    057     * Wrap a Fulcrum user object into a Turbine user object
    058     *
    059     * @param user the user object to delegate to
    060     *
    061     * @return the wrapped object
    062     */
    063    protected <U extends User> U wrap(TurbineUser user)
    064    {
    065        @SuppressWarnings("unchecked")
    066        U u = (U)new DefaultUserImpl(user);
    067        return u;
    068    }
    069
    070    /**
    071     * Initializes the UserManager
    072     *
    073     * @param conf A Configuration object to init this Manager
    074     */
    075    @Override
    076    public void init(Configuration conf)
    077    {
    078        ServiceManager manager = TurbineServices.getInstance();
    079        this.umDelegate = (TurbineUserManager)manager.getService(TurbineUserManager.ROLE);
    080    }
    081
    082    /**
    083     * Check whether a specified user's account exists.
    084     *
    085     * The login name is used for looking up the account.
    086     *
    087     * @param user The user to be checked.
    088     * @return true if the specified account exists
    089     * @throws DataBackendException if there was an error accessing the data backend.
    090     */
    091    @Override
    092    public boolean accountExists(User user)
    093            throws DataBackendException
    094    {
    095        return umDelegate.checkExists(user);
    096    }
    097
    098    /**
    099     * Check whether a specified user's account exists.
    100     *
    101     * The login name is used for looking up the account.
    102     *
    103     * @param userName The name of the user to be checked.
    104     * @return true if the specified account exists
    105     * @throws DataBackendException if there was an error accessing the data backend.
    106     */
    107    @Override
    108    public boolean accountExists(String userName)
    109            throws DataBackendException
    110    {
    111        return umDelegate.checkExists(userName);
    112    }
    113
    114    /**
    115     * Retrieve a user from persistent storage using username as the
    116     * key.
    117     *
    118     * @param username the name of the user.
    119     * @return an User object.
    120     * @exception UnknownEntityException if the user's record does not
    121     *            exist in the database.
    122     * @exception DataBackendException if there is a problem accessing the
    123     *            storage.
    124     */
    125    @Override
    126    public <U extends User> U retrieve(String username)
    127            throws UnknownEntityException, DataBackendException
    128    {
    129        TurbineUser u = umDelegate.getUser(username);
    130        return wrap(u);
    131    }
    132
    133    /**
    134     * Retrieve a set of users that meet the specified criteria.
    135     *
    136     * As the keys for the criteria, you should use the constants that
    137     * are defined in {@link User} interface, plus the names
    138     * of the custom attributes you added to your user representation
    139     * in the data storage. Use verbatim names of the attributes -
    140     * without table name prefix in case of DB implementation.
    141     *
    142     * @param criteria The criteria of selection.
    143     * @return a List of users meeting the criteria.
    144     * @throws DataBackendException if there is a problem accessing the
    145     *         storage.
    146     */
    147    @Override
    148    public List<? extends User> retrieveList(Object criteria)
    149            throws DataBackendException
    150    {
    151        UserSet uset = umDelegate.getAllUsers();
    152        List<User> userList = new ArrayList<User>();
    153
    154        for (org.apache.fulcrum.security.entity.User u : uset)
    155        {
    156            TurbineUser tu = (TurbineUser)u;
    157            userList.add(wrap(tu));
    158        }
    159
    160        return userList;
    161    }
    162
    163    /**
    164     * Retrieve a user from persistent storage using username as the
    165     * key, and authenticate the user. The implementation may chose
    166     * to authenticate to the server as the user whose data is being
    167     * retrieved.
    168     *
    169     * @param username the name of the user.
    170     * @param password the user supplied password.
    171     * @return an User object.
    172     * @exception PasswordMismatchException if the supplied password was
    173     *            incorrect.
    174     * @exception UnknownEntityException if the user's record does not
    175     *            exist in the database.
    176     * @exception DataBackendException if there is a problem accessing the
    177     *            storage.
    178     */
    179    @Override
    180    public <U extends User> U retrieve(String username, String password)
    181            throws PasswordMismatchException, UnknownEntityException,
    182            DataBackendException
    183    {
    184        TurbineUser u = umDelegate.getUser(username, password);
    185        return wrap(u);
    186    }
    187
    188    /**
    189     * Save an User object to persistent storage. User's record is
    190     * required to exist in the storage.
    191     *
    192     * @param user an User object to store.
    193     * @exception UnknownEntityException if the user's record does not
    194     *            exist in the database.
    195     * @exception DataBackendException if there is a problem accessing the
    196     *            storage.
    197     */
    198    @Override
    199    public void store(User user)
    200            throws UnknownEntityException, DataBackendException
    201    {
    202        try
    203        {
    204            user.setObjectdata(ObjectUtils.serializeMap(user.getPermStorage()));
    205        }
    206        catch (Exception e)
    207        {
    208            throw new DataBackendException("Could not serialize permanent storage", e);
    209        }
    210
    211        umDelegate.saveUser(((DefaultUserImpl)user).getUserDelegate());
    212    }
    213
    214    /**
    215     * Saves User data when the session is unbound. The user account is required
    216     * to exist in the storage.
    217     *
    218     * LastLogin, AccessCounter, persistent pull tools, and any data stored
    219     * in the permData hashtable that is not mapped to a column will be saved.
    220     *
    221     * @exception UnknownEntityException if the user's account does not
    222     *            exist in the database.
    223     * @exception DataBackendException if there is a problem accessing the
    224     *            storage.
    225     */
    226    @Override
    227    public void saveOnSessionUnbind(User user)
    228            throws UnknownEntityException, DataBackendException
    229    {
    230        store(user);
    231    }
    232
    233    /**
    234     * Authenticate an User with the specified password. If authentication
    235     * is successful the method returns nothing. If there are any problems,
    236     * exception was thrown.
    237     *
    238     * @param user an User object to authenticate.
    239     * @param password the user supplied password.
    240     * @exception PasswordMismatchException if the supplied password was
    241     *            incorrect.
    242     * @exception UnknownEntityException if the user's record does not
    243     *            exist in the database.
    244     * @exception DataBackendException if there is a problem accessing the
    245     *            storage.
    246     */
    247    @Override
    248    public void authenticate(User user, String password)
    249            throws PasswordMismatchException, UnknownEntityException,
    250            DataBackendException
    251    {
    252        umDelegate.authenticate(user, password);
    253    }
    254
    255    /**
    256     * Creates new user account with specified attributes.
    257     *
    258     * @param user the object describing account to be created.
    259     * @param initialPassword The password to use for the object creation
    260     *
    261     * @throws DataBackendException if there was an error accessing the data backend.
    262     * @throws EntityExistsException if the user account already exists.
    263     */
    264    @Override
    265    public void createAccount(User user, String initialPassword)
    266            throws EntityExistsException, DataBackendException
    267    {
    268        umDelegate.addUser(user, initialPassword);
    269    }
    270
    271    /**
    272     * Removes an user account from the system.
    273     *
    274     * @param user the object describing the account to be removed.
    275     * @throws DataBackendException if there was an error accessing the data backend.
    276     * @throws UnknownEntityException if the user account is not present.
    277     */
    278    @Override
    279    public void removeAccount(User user)
    280            throws UnknownEntityException, DataBackendException
    281    {
    282        umDelegate.removeUser(user);
    283    }
    284
    285    /**
    286     * Change the password for an User.
    287     *
    288     * @param user an User to change password for.
    289     * @param oldPassword the current password supplied by the user.
    290     * @param newPassword the current password requested by the user.
    291     * @exception PasswordMismatchException if the supplied password was
    292     *            incorrect.
    293     * @exception UnknownEntityException if the user's record does not
    294     *            exist in the database.
    295     * @exception DataBackendException if there is a problem accessing the
    296     *            storage.
    297     */
    298    @Override
    299    public void changePassword(User user, String oldPassword,
    300                               String newPassword)
    301            throws PasswordMismatchException, UnknownEntityException,
    302            DataBackendException
    303    {
    304        umDelegate.changePassword(
    305                ((DefaultUserImpl)user).getUserDelegate(),
    306                oldPassword, newPassword);
    307    }
    308
    309    /**
    310     * Forcibly sets new password for an User.
    311     *
    312     * This is supposed by the administrator to change the forgotten or
    313     * compromised passwords. Certain implementations of this feature
    314     * would require administrative level access to the authenticating
    315     * server / program.
    316     *
    317     * @param user an User to change password for.
    318     * @param password the new password.
    319     * @exception UnknownEntityException if the user's record does not
    320     *            exist in the database.
    321     * @exception DataBackendException if there is a problem accessing the
    322     *            storage.
    323     */
    324    @Override
    325    public void forcePassword(User user, String password)
    326            throws UnknownEntityException, DataBackendException
    327    {
    328        umDelegate.forcePassword(user, password);
    329    }
    330
    331    /**
    332     * Constructs an User object to represent an anonymous user of the
    333     * application.
    334     *
    335     * @return An anonymous Turbine User.
    336     * @throws UnknownEntityException
    337     *             if the anonymous User object couldn't be constructed.
    338     */
    339    @Override
    340    public <T extends User> T getAnonymousUser() throws UnknownEntityException
    341    {
    342        TurbineUser u = umDelegate.getAnonymousUser();
    343        return wrap(u);
    344    }
    345
    346    /**
    347     * Checks whether a passed user object matches the anonymous user pattern
    348     * according to the configured user manager
    349     *
    350     * @param u a user object
    351     *
    352     * @return True if this is an anonymous user
    353     *
    354     */
    355    @Override
    356    public boolean isAnonymousUser(User u)
    357    {
    358        return umDelegate.isAnonymousUser(u);
    359    }
    360
    361    /**
    362     * Construct a blank User object.
    363     *
    364     * This method calls getUserClass, and then creates a new object using the
    365     * default constructor.
    366     *
    367     * @return an object implementing User interface.
    368     * @throws DataBackendException
    369     *             if the object could not be instantiated.
    370     */
    371    @Override
    372    public <T extends User> T getUserInstance() throws DataBackendException
    373    {
    374        TurbineUser u = umDelegate.getUserInstance();
    375        return wrap(u);
    376    }
    377
    378    /**
    379     * Construct a blank User object.
    380     *
    381     * This method calls getUserClass, and then creates a new object using the
    382     * default constructor.
    383     *
    384     * @param userName
    385     *            The name of the user.
    386     *
    387     * @return an object implementing User interface.
    388     * @throws DataBackendException
    389     *             if the object could not be instantiated.
    390     */
    391    @Override
    392    public <T extends User> T getUserInstance(String userName) throws DataBackendException
    393    {
    394        TurbineUser u = umDelegate.getUserInstance(userName);
    395        return wrap(u);
    396    }
    397
    398    /**
    399     * Return a Class object representing the system's chosen implementation of
    400     * of ACL interface.
    401     *
    402     * @return systems's chosen implementation of ACL interface.
    403     * @throws UnknownEntityException
    404     *             if the implementation of ACL interface could not be
    405     *             determined, or does not exist.
    406     */
    407    @Override
    408    public <T extends AccessControlList> T getACL(User user) throws UnknownEntityException
    409    {
    410        return umDelegate.getACL(user);
    411    }
    412}