001: /*
002: * Copyright (c) 2001 - 2005 ivata limited.
003: * All rights reserved.
004: * -----------------------------------------------------------------------------
005: * ivata groupware may be redistributed under the GNU General Public
006: * License as published by the Free Software Foundation;
007: * version 2 of the License.
008: *
009: * These programs are free software; you can redistribute them and/or
010: * modify them under the terms of the GNU General Public License
011: * as published by the Free Software Foundation; version 2 of the License.
012: *
013: * These programs are distributed in the hope that they will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: *
017: * See the GNU General Public License in the file LICENSE.txt for more
018: * details.
019: *
020: * If you would like a copy of the GNU General Public License write to
021: *
022: * Free Software Foundation, Inc.
023: * 59 Temple Place - Suite 330
024: * Boston, MA 02111-1307, USA.
025: *
026: *
027: * To arrange commercial support and licensing, contact ivata at
028: * http://www.ivata.com/contact.jsp
029: * -----------------------------------------------------------------------------
030: * $Log: PlainTextSecurityServer.java,v $
031: * Revision 1.8 2005/10/14 14:01:46 colinmacleod
032: * Changed password checking routines to return boolean, rather than throwing
033: * an exception.
034: *
035: * Revision 1.7 2005/10/03 10:21:14 colinmacleod
036: * Fixed some style and javadoc issues.
037: *
038: * Revision 1.6 2005/10/02 14:08:58 colinmacleod
039: * Added/improved log4j logging.
040: *
041: * Revision 1.5 2005/09/29 14:17:04 colinmacleod
042: * Split UserGroupDO off from GroupDO.
043: * Moved UserGroupDO, Right classes to security subproject (from
044: * addressbook).
045: * Centralized user right handling into Rights and RightsImpl.
046: *
047: * Revision 1.4 2005/09/14 16:10:22 colinmacleod
048: * Removed unused local and class variables.
049: * Added serialVersionUID.
050: *
051: * Revision 1.3 2005/04/10 20:09:48 colinmacleod
052: * Added new themes.
053: * Changed id type to String.
054: * Changed i tag to em and b tag to strong.
055: * Improved PicoContainerFactory with NanoContainer scripts.
056: *
057: * Revision 1.2 2005/04/09 17:19:57 colinmacleod
058: * Changed copyright text to GPL v2 explicitly.
059: *
060: * Revision 1.1.1.1 2005/03/10 17:51:41 colinmacleod
061: * Restructured ivata op around Hibernate/PicoContainer.
062: * Renamed ivata groupware.
063: *
064: * Revision 1.4 2004/11/12 18:16:07 colinmacleod
065: * Ordered imports.
066: *
067: * Revision 1.3 2004/11/12 15:57:18 colinmacleod
068: * Removed dependencies on SSLEXT.
069: * Moved Persistence classes to ivata masks.
070: *
071: * Revision 1.2 2004/11/03 16:04:58 colinmacleod
072: * Fixed persistence sessions left open.
073: *
074: * Revision 1.1 2004/09/30 15:15:58 colinmacleod
075: * Split off addressbook elements into security subproject.
076: *
077: * Revision 1.2 2004/07/13 19:41:12 colinmacleod
078: * Moved project to POJOs from EJBs.
079: * Applied PicoContainer to services layer (replacing session EJBs).
080: * Applied Hibernate to persistence layer (replacing entity EJBs).
081: *
082: * Revision 1.1 2004/03/21 20:16:24 colinmacleod
083: * First version. Plain text security server allows for open portal to function
084: * without a mail server.
085: * -----------------------------------------------------------------------------
086: */
087: package com.ivata.groupware.admin.security.server;
088:
089: import org.apache.log4j.Logger;
090:
091: import org.picocontainer.MutablePicoContainer;
092: import org.picocontainer.PicoContainer;
093: import org.picocontainer.defaults.DefaultPicoContainer;
094:
095: import com.ivata.groupware.admin.security.user.UserConstants;
096: import com.ivata.groupware.admin.security.user.UserDO;
097: import com.ivata.groupware.container.PicoContainerFactory;
098: import com.ivata.mask.persistence.PersistenceSession;
099: import com.ivata.mask.persistence.QueryPersistenceManager;
100: import com.ivata.mask.util.SystemException;
101: import com.ivata.mask.validation.ValidationError;
102: import com.ivata.mask.validation.ValidationException;
103:
104: /**
105: * Simple security server which compares passwords against plain text values in
106: * the CMP layer.
107: *
108: * <p>
109: * This security server is not very secure! You are advised not to use this but
110: * to set up an <strong>IMAP</strong> server with the <code>MailServer</code>
111: * class from the <code>webmail</code> subproject.
112: * </p>
113: *
114: * @since 2004-05-11
115: * @version $Revision: 1.8 $
116: * @author Colin MacLeod
117: * <a href='mailto:colin.macleod@ivata.com'>colin.macleod@ivata.com</a>
118: */
119: public class PlainTextSecurityServer implements SecurityServer {
120: /**
121: * Logger for this class.
122: */
123: private static final Logger logger = Logger
124: .getLogger(PlainTextSecurityServer.class);
125:
126: /**
127: * Serialization version (for <code>Serializable</code> interface).
128: */
129: private static final long serialVersionUID = 1L;
130: /**
131: * Persistence manger used to store/retrieve data objects, or retrieve a
132: * new persistence session.
133: */
134: private QueryPersistenceManager persistenceManager;
135:
136: /**
137: * Construct and initialize the Securtiy Server implementation.
138: *
139: * @param persistenceManagerParam persistence manager used to store/retrieve
140: * data objects from the peristence store.
141: */
142: public PlainTextSecurityServer(
143: final QueryPersistenceManager persistenceManagerParam) {
144: this .persistenceManager = persistenceManagerParam;
145: }
146:
147: /**
148: * Add a new user to the system.
149: *
150: * @param securitySession Can be used to authenticate the current user.
151: * Not checked in this implementation.
152: * @param userName user name to add.
153: * @param fullName full name under which the user will be filed.
154: * @throws SystemException if this user cannot be added.
155: */
156: public void addUser(final SecuritySession securitySession,
157: final String userName, final String fullName)
158: throws SystemException {
159: if (logger.isDebugEnabled()) {
160: logger.debug("addUser(SecuritySession securitySession = "
161: + securitySession + ", String userName = "
162: + userName + ", String fullName = " + fullName
163: + ") - start");
164: }
165:
166: // this server does not need to do anything additional to add a user
167:
168: if (logger.isDebugEnabled()) {
169: logger
170: .debug("addUser(SecuritySession, String, String) - end");
171: }
172: }
173:
174: /**
175: * Check the password for a user is correct.
176: *
177: * @param securitySession Used to authenticate the current user against
178: * the persistence rights.
179: * @param userName name of the user for whom to check the password.
180: * @param password the new password value to check against the system.
181: * @return <code>true</code> if the passwords match, otherwise
182: * <code>false</code>.
183: * @throws SystemException If the password cannot be checked for any
184: * reason.
185: */
186: public boolean checkPassword(final SecuritySession securitySession,
187: final String userName, final String password)
188: throws SystemException {
189: if (logger.isDebugEnabled()) {
190: logger
191: .debug("checkPassword(SecuritySession securitySession = "
192: + securitySession
193: + ", String userName = "
194: + userName
195: + ", String password = "
196: + password + ") - start");
197: }
198:
199: PersistenceSession persistenceSession = persistenceManager
200: .openSession(securitySession);
201: try {
202:
203: UserDO user = (UserDO) persistenceManager.findInstance(
204: persistenceSession, "securityUserByName",
205: new Object[] { userName });
206:
207: String userPassword = user.getPassword();
208: if (password == null) {
209: if (userPassword != null) {
210: logger
211: .warn("checkPassword - null password specified - "
212: + "not null in data store for user '"
213: + userName + "'.");
214: return false;
215: }
216: } else if (!password.equals(userPassword)) {
217: if (logger.isDebugEnabled()) {
218: logger
219: .debug("checkPassword - passwords do not match for "
220: + "user '" + userName + "'.");
221: }
222: return false;
223: }
224: } catch (Exception e) {
225: logger
226: .error(
227: "checkPassword(SecuritySession, String, String)",
228: e);
229:
230: persistenceSession.cancel();
231: throw new SystemException(e);
232: } finally {
233: persistenceSession.close();
234: }
235:
236: if (logger.isDebugEnabled()) {
237: logger
238: .debug("checkPassword - end - return value = " + true);
239: }
240: return true;
241: }
242:
243: /**
244: * {@inheritDoc}
245: *
246: * @param securitySession {@inheritDoc}
247: * @param userName {@inheritDoc}
248: * @return {@inheritDoc}
249: */
250: public final String getSystemUserName(
251: final SecuritySession securitySession, final String userName) {
252: if (logger.isDebugEnabled()) {
253: logger
254: .debug("getSystemUserName(SecuritySession securitySession = "
255: + securitySession
256: + ", String userName = "
257: + userName + ") - start");
258: }
259:
260: if (logger.isDebugEnabled()) {
261: logger.debug("getSystemUserName - end - return value = "
262: + userName);
263: }
264: return userName;
265: }
266:
267: /**
268: * {@inheritDoc}
269: *
270: * @param securitySession {@inheritDoc}
271: * @param systemUserName {@inheritDoc}
272: * @return {@inheritDoc}
273: */
274: public final String getUserNameFromSystemUserName(
275: final SecuritySession securitySession,
276: final String systemUserName) {
277: if (logger.isDebugEnabled()) {
278: logger.debug("getUserNameFromSystemUserName("
279: + "SecuritySession securitySession = "
280: + securitySession + ", String systemUserName = "
281: + systemUserName + ") - start");
282: }
283:
284: if (logger.isDebugEnabled()) {
285: logger
286: .debug("getUserNameFromSystemUserName - end - return value = "
287: + systemUserName);
288: }
289: return systemUserName;
290: }
291:
292: /**
293: * {@inheritDoc}
294: *
295: * @param userNameParam {@inheritDoc}
296: * @return {@inheritDoc}
297: */
298: public boolean isUser(final SecuritySession securitySession,
299: final String userNameParam) {
300: if (logger.isDebugEnabled()) {
301: logger.debug("isUser(SecuritySession securitySession = "
302: + securitySession + ", String userNameParam = "
303: + userNameParam + ") - start");
304: }
305:
306: if (logger.isDebugEnabled()) {
307: logger.debug("isUser - end - return value = " + false);
308: }
309: return false;
310: }
311:
312: /**
313: * <p>Login to an authentication server using the user name and password
314: * provided.</p>
315: *
316: * @param user user to login to the server.
317: * @param password used to login to the server
318: * @return valid session for this username password combination.
319: * @throws SystemException if this user cannot be authenticated.
320: */
321: public SecuritySession login(final UserDO user,
322: final String password) throws SystemException {
323: if (logger.isDebugEnabled()) {
324: logger.debug("login(UserDO user = " + user
325: + ", String password = " + password + ") - start");
326: }
327:
328: if (!checkPassword(loginGuest(), user.getName(), password)) {
329: throw new ValidationException(new ValidationError(
330: "errors.field.passwordConfirm", null));
331: }
332: PicoContainer globalContainer = PicoContainerFactory
333: .getInstance().getGlobalContainer();
334: MutablePicoContainer sessionContainer = new DefaultPicoContainer(
335: globalContainer);
336: PlainTextSecuritySession session = new PlainTextSecuritySession(
337: sessionContainer, user);
338: sessionContainer.registerComponentInstance(
339: SecuritySession.class, session);
340: session.setPassword(password);
341:
342: if (logger.isDebugEnabled()) {
343: logger
344: .debug("login(UserDO, String) - end - return value = "
345: + session);
346: }
347: return session;
348: }
349:
350: /**
351: * {@inheritDoc}
352: *
353: * @return {@inheritDoc}
354: * @throws SystemException {@inheritDoc}
355: */
356: public SecuritySession loginGuest() throws SystemException {
357: if (logger.isDebugEnabled()) {
358: logger.debug("loginGuest() - start");
359: }
360:
361: PicoContainer globalContainer = PicoContainerFactory
362: .getInstance().getGlobalContainer();
363: UserDO guestUser = new UserDO();
364: guestUser.setId(UserConstants.GUEST);
365: guestUser.setDeleted(false);
366: guestUser.setEnabled(true);
367: guestUser.setName("guest");
368: MutablePicoContainer sessionContainer = new DefaultPicoContainer(
369: globalContainer);
370: SecuritySession session = new PlainTextSecuritySession(
371: sessionContainer, guestUser);
372: sessionContainer.registerComponentInstance(
373: SecuritySession.class, session);
374:
375: if (logger.isDebugEnabled()) {
376: logger.debug("loginGuest() - end - return value = "
377: + session);
378: }
379: return session;
380: }
381:
382: /**
383: * <p>Remove the user with the given name from the system.</p>
384: *
385: * @param securitySession {@inheritDoc}
386: * @param userName name of the user to be removed.
387: * @throws SystemException if this user cannot be removed.
388: */
389: public void removeUser(final SecuritySession securitySession,
390: final String userName) throws SystemException {
391: if (logger.isDebugEnabled()) {
392: logger
393: .debug("removeUser(SecuritySession securitySession = "
394: + securitySession
395: + ", String userName = "
396: + userName + ") - start");
397: }
398:
399: // don't need to do anything additional to remove a user for this server
400:
401: if (logger.isDebugEnabled()) {
402: logger.debug("removeUser(SecuritySession, String) - end");
403: }
404: }
405:
406: /**
407: * <p>Set the password for a user.</p>
408: *
409: * @param securitySession {@inheritDoc}
410: * @param userName name of the user for whom to set the password.
411: * @param password the new password value to set.
412: * @throws SystemException if the password cannot be set for any
413: * reason.
414: */
415: public final void setPassword(
416: final SecuritySession securitySession,
417: final String userName, final String password)
418: throws SystemException {
419: if (logger.isDebugEnabled()) {
420: logger
421: .debug("setPassword(SecuritySession securitySession = "
422: + securitySession
423: + ", String userName = "
424: + userName
425: + ", String password = "
426: + password + ") - start");
427: }
428:
429: PersistenceSession persistenceSession = persistenceManager
430: .openSession(securitySession);
431: try {
432: UserDO user = (UserDO) persistenceManager.findInstance(
433: persistenceSession, "securityUserByName",
434: new Object[] { userName });
435: user.setPassword(password);
436: persistenceManager.amend(persistenceSession, user);
437: } catch (Exception e) {
438: logger.error(
439: "setPassword(SecuritySession, String, String)", e);
440:
441: persistenceSession.cancel();
442: throw new SystemException(e);
443: } finally {
444: persistenceSession.close();
445: }
446:
447: if (logger.isDebugEnabled()) {
448: logger
449: .debug("setPassword(SecuritySession, String, String) - end");
450: }
451: };
452:
453: }
|