001package org.apache.turbine.services.security;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.List;
023
024import org.apache.commons.configuration2.Configuration;
025import org.apache.fulcrum.security.acl.AccessControlList;
026import org.apache.fulcrum.security.util.DataBackendException;
027import org.apache.fulcrum.security.util.EntityExistsException;
028import org.apache.fulcrum.security.util.PasswordMismatchException;
029import org.apache.fulcrum.security.util.UnknownEntityException;
030import org.apache.turbine.om.security.User;
031import org.apache.turbine.services.InitializationException;
032
033/**
034 * An UserManager performs {@link org.apache.turbine.om.security.User} objects
035 * related tasks on behalf of the
036 * {@link org.apache.turbine.services.security.DefaultSecurityService}.
037 *
038 * The responsibilities of this class include loading data of an user from the
039 * storage and putting them into the
040 * {@link org.apache.turbine.om.security.User} objects, saving those data
041 * to the permanent storage, and authenticating users.
042 *
043 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
044 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
045 * @version $Id$
046 */
047public interface UserManager
048{
049    /**
050     * Initializes the UserManager
051     *
052     * @param conf A Configuration object to init this Manager
053     *
054     * @throws InitializationException When something went wrong.
055     */
056    void init(Configuration conf)
057        throws InitializationException;
058
059    /**
060     * Check whether a specified user's account exists.
061     *
062     * The login name is used for looking up the account.
063     *
064     * @param user The user to be checked.
065     * @return true if the specified account exists
066     * @throws DataBackendException if there was an error accessing the data
067     *         backend.
068     */
069    boolean accountExists(User user)
070            throws DataBackendException;
071
072    /**
073     * Check whether a specified user's account exists.
074     *
075     * The login name is used for looking up the account.
076     *
077     * @param userName The name of the user to be checked.
078     * @return true if the specified account exists
079     * @throws DataBackendException if there was an error accessing the data
080     *         backend.
081     */
082    boolean accountExists(String userName)
083            throws DataBackendException;
084
085    /**
086     * Retrieve a user from persistent storage using username as the
087     * key.
088     *
089     * @param <U> user class
090     * @param username the name of the user.
091     * @return an User object.
092     * @throws UnknownEntityException if the user's record does not
093     *         exist in the database.
094     * @throws DataBackendException if there is a problem accessing the
095     *         storage.
096     */
097    <U extends User> U retrieve(String username)
098            throws UnknownEntityException, DataBackendException;
099
100    /**
101     * Retrieve a list of users that meet the specified criteria.
102     *
103     * As the keys for the criteria, you should use the constants that
104     * are defined in {@link User} interface, plus the names
105     * of the custom attributes you added to your user representation
106     * in the data storage. Use verbatim names of the attributes -
107     * without table name prefix in case of DB implementation.
108     *
109     * @param criteria The criteria of selection.
110     * @return a List of users meeting the criteria.
111     * @throws DataBackendException if there is a problem accessing the
112     *         storage.
113     */
114    List<? extends User> retrieveList(Object criteria)
115        throws DataBackendException;
116
117    /**
118     * Retrieve a user from persistent storage using username as the
119     * key, and authenticate the user. The implementation may chose
120     * to authenticate to the server as the user whose data is being
121     * retrieved.
122     *
123     * @param <U> user class
124     * @param username the name of the user.
125     * @param password the user supplied password.
126     * @return an User object.
127     * @throws PasswordMismatchException if the supplied password was incorrect.
128     * @throws UnknownEntityException if the user's record does not
129     *         exist in the database.
130     * @throws DataBackendException if there is a problem accessing the storage.
131     */
132    <U extends User> U retrieve(String username, String password)
133            throws PasswordMismatchException, UnknownEntityException,
134            DataBackendException;
135
136    /**
137     * Save an User object to persistent storage. User's record is
138     * required to exist in the storage.
139     *
140     * @param user an User object to store.
141     * @throws UnknownEntityException if the user's record does not
142     *         exist in the database.
143     * @throws DataBackendException if there is a problem accessing the storage.
144     */
145    void store(User user)
146            throws UnknownEntityException, DataBackendException;
147
148    /**
149     * Saves User data when the session is unbound. The user account is required
150     * to exist in the storage.
151     *
152     * LastLogin, AccessCounter, persistent pull tools, and any data stored
153     * in the permData hashtable that is not mapped to a column will be saved.
154     *
155     * @param user the user in the session
156     *
157     * @throws UnknownEntityException if the user's account does not
158     *            exist in the database.
159     * @throws DataBackendException if there is a problem accessing the
160     *            storage.
161     */
162    void saveOnSessionUnbind(User user)
163            throws UnknownEntityException, DataBackendException;
164
165    /**
166     * Authenticate an User with the specified password. If authentication
167     * is successful the method returns nothing. If there are any problems,
168     * exception was thrown.
169     *
170     * @param user an User object to authenticate.
171     * @param password the user supplied password.
172     * @throws PasswordMismatchException if the supplied password was incorrect.
173     * @throws UnknownEntityException if the user's record does not
174     *         exist in the database.
175     * @throws DataBackendException if there is a problem accessing the storage.
176     */
177    void authenticate(User user, String password)
178            throws PasswordMismatchException, UnknownEntityException,
179            DataBackendException;
180
181    /**
182     * Creates new user account with specified attributes.
183     *
184     * @param user the object describing account to be created.
185     * @param initialPassword password for the new user
186     * @throws UnknownEntityException if the user account cannot be created.
187     * @throws DataBackendException if there was an error accessing the data
188     *         backend.
189     * @throws EntityExistsException if the user account already exists.
190     */
191    void createAccount(User user, String initialPassword)
192            throws UnknownEntityException, EntityExistsException, DataBackendException;
193
194    /**
195     * Removes an user account from the system.
196     *
197     * @param user the object describing the account to be removed.
198     * @throws DataBackendException if there was an error accessing the data
199     *         backend.
200     * @throws UnknownEntityException if the user account is not present.
201     */
202    void removeAccount(User user)
203            throws UnknownEntityException, DataBackendException;
204
205    /**
206     * Change the password for an User.
207     *
208     * @param user an User to change password for.
209     * @param oldPassword the current password suplied by the user.
210     * @param newPassword the current password requested by the user.
211     * @throws PasswordMismatchException if the supplied password was incorrect.
212     * @throws UnknownEntityException if the user's record does not
213     *         exist in the database.
214     * @throws DataBackendException if there is a problem accessing the storage.
215     */
216    void changePassword(User user, String oldPassword,
217                        String newPassword)
218            throws PasswordMismatchException, UnknownEntityException,
219            DataBackendException;
220
221    /**
222     * Forcibly sets new password for an User.
223     *
224     * This is supposed by the administrator to change the forgotten or
225     * compromised passwords. Certain implementatations of this feature
226     * would require administrative level access to the authenticating
227     * server / program.
228     *
229     * @param user an User to change password for.
230     * @param password the new password.
231     * @throws UnknownEntityException if the user's record does not
232     *            exist in the database.
233     * @throws DataBackendException if there is a problem accessing the storage.
234     */
235    void forcePassword(User user, String password)
236            throws UnknownEntityException, DataBackendException;
237
238    /**
239     * Constructs an User object to represent an anonymous user of the
240     * application.
241     *
242     * @param <U> user class
243     * @return An anonymous Turbine User.
244     * @throws UnknownEntityException
245     *             if the anonymous User object couldn't be constructed.
246     */
247    <U extends User> U getAnonymousUser() throws UnknownEntityException;
248
249    /**
250     * Checks whether a passed user object matches the anonymous user pattern
251     * according to the configured user manager
252     *
253     * @param u a user object
254     *
255     * @return True if this is an anonymous user
256     *
257     */
258    boolean isAnonymousUser(User u);
259
260    /**
261     * Construct a blank User object.
262     *
263     * This method calls getUserClass, and then creates a new object using the
264     * default constructor.
265     *
266     * @param <U> user class
267     * @return an object implementing User interface.
268     * @throws DataBackendException
269     *             if the object could not be instantiated.
270     */
271    <U extends User> U getUserInstance() throws DataBackendException;
272
273    /**
274     * Construct a blank User object.
275     *
276     * This method calls getUserClass, and then creates a new object using the
277     * default constructor.
278     *
279     * @param <U> user class
280     * @param userName
281     *            The name of the user.
282     *
283     * @return an object implementing User interface.
284     * @throws DataBackendException
285     *             if the object could not be instantiated.
286     */
287    <U extends User> U getUserInstance(String userName) throws DataBackendException;
288
289    /**
290     * Return a Class object representing the system's chosen implementation of
291     * of ACL interface for the given user
292     *
293     * @param <A> ACL class
294     * @param user the user
295     * @return systems's chosen implementation of ACL interface.
296     * @throws UnknownEntityException
297     *             if the implementation of ACL interface could not be
298     *             determined, or does not exist.
299     */
300    <A extends AccessControlList> A getACL(User user) throws UnknownEntityException;
301}