001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2001-2005 Janne Jalkanen (Janne.Jalkanen@iki.fi)
005:
006: This program is free software; you can redistribute it and/or modify
007: it under the terms of the GNU Lesser General Public License as published by
008: the Free Software Foundation; either version 2.1 of the License, or
009: (at your option) any later version.
010:
011: This program is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: GNU Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public License
017: along with this program; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: package com.ecyrd.jspwiki.auth.user;
021:
022: import java.security.Principal;
023: import java.util.Properties;
024:
025: import com.ecyrd.jspwiki.NoRequiredPropertyException;
026: import com.ecyrd.jspwiki.WikiEngine;
027: import com.ecyrd.jspwiki.auth.NoSuchPrincipalException;
028: import com.ecyrd.jspwiki.auth.WikiSecurityException;
029:
030: /**
031: * Defines an interface for loading, persisting and storing users.
032: * @author Janne Jalkanen
033: * @author Andrew Jaquith
034: * @since 2.3
035: */
036: public interface UserDatabase {
037:
038: /**
039: * No-op method that in previous versions of JSPWiki was intended to
040: * atomically commit changes to the user database. Now, the {@link #rename(String, String)},
041: * {@link #save(UserProfile)} and {@link #deleteByLoginName(String)} methods
042: * are atomic themselves.
043: * @throws WikiSecurityException
044: * @deprecated there is no need to call this method because the save, rename and
045: * delete methods contain their own commit logic
046: */
047: public void commit() throws WikiSecurityException;
048:
049: /**
050: * Looks up and deletes the first {@link UserProfile} in the user database
051: * that matches a profile having a given login name. If the user database
052: * does not contain a user with a matching attribute, throws a
053: * {@link NoSuchPrincipalException}. This method is intended to be atomic;
054: * results cannot be partially committed. If the commit fails, it should
055: * roll back its state appropriately. Implementing classes that persist
056: * to the file system may wish to make this method <code>synchronized</code>.
057: * @param loginName the login name of the user profile that shall be deleted
058: */
059: public void deleteByLoginName(String loginName)
060: throws NoSuchPrincipalException, WikiSecurityException;
061:
062: /**
063: * <p>
064: * Looks up the Principals representing a user from the user database. These
065: * are defined as a set of Principals manufactured from the login name, full
066: * name, and wiki name. The order of the Principals returned is not
067: * significant. If the user database does not contain a user with the
068: * supplied identifier, throws a {@link NoSuchPrincipalException}.
069: * </p>
070: * <p>
071: * Note that if an implememtation wishes to mark one of the returned
072: * Principals as representing the user's common name, it should instantiate
073: * this Principal using
074: * {@link com.ecyrd.jspwiki.auth.WikiPrincipal#WikiPrincipal(String, String)}
075: * with the <code>type</code> parameter set to
076: * {@link com.ecyrd.jspwiki.auth.WikiPrincipal#WIKI_NAME}. The method
077: * {@link com.ecyrd.jspwiki.WikiSession#getUserPrincipal()} will return this
078: * principal as the "primary" principal. Note that this method can also be
079: * used to mark a WikiPrincipal as a login name or a wiki name.
080: * </p>
081: * @param identifier the name of the user to retrieve; this corresponds to
082: * value returned by the user profile's
083: * {@link UserProfile#getLoginName()} method.
084: * @return the array of Principals representing the user's identities
085: */
086: public Principal[] getPrincipals(String identifier)
087: throws NoSuchPrincipalException;
088:
089: /**
090: * Returns all WikiNames that are stored in the UserDatabase
091: * as an array of Principal objects. If the database does not
092: * contain any profiles, this method will return a zero-length
093: * array.
094: * @return the WikiNames
095: */
096: public Principal[] getWikiNames() throws WikiSecurityException;
097:
098: /**
099: * Looks up and returns the first {@link UserProfile} in the user database
100: * that whose login name, full name, or wiki name matches the supplied
101: * string. This method provides a "forgiving" search algorithm for resolving
102: * Principal names when the exact profile attribute that supplied the name
103: * is unknown.
104: * @param index the login name, full name, or wiki name
105: */
106: public UserProfile find(String index)
107: throws NoSuchPrincipalException;
108:
109: /**
110: * Looks up and returns the first {@link UserProfile} in the user database
111: * that matches a profile having a given e-mail address. If the user
112: * database does not contain a user with a matching attribute, throws a
113: * {@link NoSuchPrincipalException}.
114: * @param index the e-mail address of the desired user profile
115: * @return the user profile
116: */
117: public UserProfile findByEmail(String index)
118: throws NoSuchPrincipalException;
119:
120: /**
121: * Looks up and returns the first {@link UserProfile} in the user database
122: * that matches a profile having a given login name. If the user database
123: * does not contain a user with a matching attribute, throws a
124: * {@link NoSuchPrincipalException}.
125: * @param index the login name of the desired user profile
126: * @return the user profile
127: */
128: public UserProfile findByLoginName(String index)
129: throws NoSuchPrincipalException;
130:
131: /**
132: * Looks up and returns the first {@link UserProfile} in the user database
133: * that matches a profile having a given wiki name. If the user database
134: * does not contain a user with a matching attribute, throws a
135: * {@link NoSuchPrincipalException}.
136: * @param index the wiki name of the desired user profile
137: * @return the user profile
138: */
139: public UserProfile findByWikiName(String index)
140: throws NoSuchPrincipalException;
141:
142: /**
143: * Looks up and returns the first {@link UserProfile} in the user database
144: * that matches a profile having a given full name. If the user database
145: * does not contain a user with a matching attribute, throws a
146: * {@link NoSuchPrincipalException}.
147: * @param index the fill name of the desired user profile
148: * @return the user profile
149: */
150: public UserProfile findByFullName(String index)
151: throws NoSuchPrincipalException;
152:
153: /**
154: * Initializes the user database based on values from a Properties object.
155: */
156: public void initialize(WikiEngine engine, Properties props)
157: throws NoRequiredPropertyException;
158:
159: /**
160: * Returns <code>true</code> if this user database shares user/password data with the
161: * web container; <code>false</false> otherwise.
162: * @return the result
163: */
164: public boolean isSharedWithContainer();
165:
166: /**
167: * Factory method that instantiates a new user profile.
168: * The {@link UserProfile#isNew()} method of profiles created using
169: * this method should return <code>true</code>.
170: */
171: public UserProfile newProfile();
172:
173: /**
174: * <p>Renames a {@link UserProfile} in the user database by changing
175: * the profile's login name. Because the login name is the profile's unique
176: * identifier, implementations should verify that the identifier is
177: * "safe" to change before actually changing it. Specifically: the profile
178: * with the supplied login name must already exist, and the proposed new
179: * name must not be in use by another profile.</p>
180: * <p>This method is intended to be atomic; results cannot be partially committed.
181: * If the commit fails, it should roll back its state appropriately.
182: * Implementing classes that persist to the file system may wish to make
183: * this method <code>synchronized</code>.</p>
184: * @param loginName the existing login name for the profile
185: * @param newName the proposed new login name
186: * @throws NoSuchPrincipalException if the user profile identified by
187: * <code>loginName</code> does not exist
188: * @throws DuplicateUserException if another user profile with the
189: * proposed new login name already exists
190: * @throws WikiSecurityException if the profile cannot be renamed for
191: * any reason, such as an I/O error, database connection failure
192: * or lack of support for renames.
193: */
194: public void rename(String loginName, String newName)
195: throws NoSuchPrincipalException, DuplicateUserException,
196: WikiSecurityException;
197:
198: /**
199: * <p>
200: * Saves a {@link UserProfile}to the user database, overwriting the
201: * existing profile if it exists. The user name under which the profile
202: * should be saved is returned by the supplied profile's
203: * {@link UserProfile#getLoginName()} method.
204: * </p>
205: * <p>
206: * The database implementation is responsible for detecting potential
207: * duplicate user profiles; specifically, the login name, wiki name, and
208: * full name must be unique. The implementation is not required to check for
209: * validity of passwords or e-mail addresses. Special case: if the profile
210: * already exists and the password is null, it should retain its previous
211: * value, rather than being set to null.
212: * </p>
213: * <p>Implementations are <em>required</em> to time-stamp the creation
214: * or modification fields of the UserProfile./p>
215: * <p>This method is intended to be atomic; results cannot be partially committed.
216: * If the commit fails, it should roll back its state appropriately.
217: * Implementing classes that persist to the file system may wish to make
218: * this method <code>synchronized</code>.</p>
219: * @param profile the user profile to save
220: * @throws WikiSecurityException if the profile cannot be saved
221: */
222: public void save(UserProfile profile) throws WikiSecurityException;
223:
224: /**
225: * Determines whether a supplied user password is valid, given a login name
226: * and password. It is up to the implementing class to determine how the
227: * comparison should be made. For example, the password might be hashed
228: * before comparing it to the value persisted in the back-end data store.
229: * @param loginName the login name
230: * @param password the password
231: * @return <code>true</code> if the password is valid, <code>false</code>
232: * otherwise
233: */
234: public boolean validatePassword(String loginName, String password);
235:
236: }
|