001: /**
002: * Copyright (c) 2003-2007, David A. Czarnecki
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions are met:
007: *
008: * Redistributions of source code must retain the above copyright notice, this list of conditions and the
009: * following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
011: * following disclaimer in the documentation and/or other materials provided with the distribution.
012: * Neither the name of "David A. Czarnecki" and "blojsom" nor the names of its contributors may be used to
013: * endorse or promote products derived from this software without specific prior written permission.
014: * Products derived from this software may not be called "blojsom", nor may "blojsom" appear in their name,
015: * without prior written permission of David A. Czarnecki.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
018: * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
019: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
021: * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
022: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
025: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026: * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
027: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
028: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
029: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
030: */package org.blojsom.plugin.admin;
031:
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034: import org.apache.commons.mail.Email;
035: import org.apache.commons.mail.EmailException;
036: import org.apache.commons.mail.HtmlEmail;
037: import org.blojsom.blog.Blog;
038: import org.blojsom.blog.Entry;
039: import org.blojsom.blog.User;
040: import org.blojsom.fetcher.Fetcher;
041: import org.blojsom.fetcher.FetcherException;
042: import org.blojsom.plugin.PluginException;
043: import org.blojsom.plugin.email.EmailConstants;
044: import org.blojsom.util.BlojsomConstants;
045: import org.blojsom.util.BlojsomUtils;
046:
047: import javax.mail.Session;
048: import javax.naming.Context;
049: import javax.naming.InitialContext;
050: import javax.naming.NamingException;
051: import javax.servlet.http.HttpServletRequest;
052: import javax.servlet.http.HttpServletResponse;
053: import java.util.Date;
054: import java.util.Map;
055: import java.util.Random;
056:
057: /**
058: * Forgotten password plugin
059: *
060: * @author David Czarnecki
061: * @since blojsom 3.0
062: * @version $Id: ForgottenPasswordPlugin.java,v 1.4 2007/01/17 02:35:05 czarneckid Exp $
063: */
064: public class ForgottenPasswordPlugin extends BaseAdminPlugin {
065:
066: private Log _logger = LogFactory
067: .getLog(ForgottenPasswordPlugin.class);
068:
069: // Localization constants
070: private static final String FAILED_PASSWORD_CHANGE_KEY = "failed.password.change.text";
071: private static final String CONSTRUCTED_PASSWORD_EMAIL_KEY = "constructed.password.email.text";
072: private static final String USERNAME_BLANK_KEY = "username.blank.text";
073:
074: private static final String FORGOTTEN_USERNAME_PARAM = "forgotten-username";
075: private static final String FORGOTTEN_PASSWORD_PAGE = "forgotten-password";
076:
077: private Fetcher _fetcher;
078: private String _mailServer;
079: private String _mailServerUsername;
080: private String _mailServerPassword;
081: private Session _session;
082:
083: /**
084: * Default constructor.
085: */
086: public ForgottenPasswordPlugin() {
087: }
088:
089: /**
090: * Set the {@link Fetcher}
091: *
092: * @param fetcher {@link Fetcher}
093: */
094: public void setFetcher(Fetcher fetcher) {
095: _fetcher = fetcher;
096: }
097:
098: /**
099: * Initialize this plugin. This method only called when the plugin is instantiated.
100: *
101: * @throws org.blojsom.plugin.PluginException
102: * If there is an error initializing the plugin
103: */
104: public void init() throws PluginException {
105: super .init();
106:
107: _mailServer = _servletConfig
108: .getInitParameter(EmailConstants.SMTPSERVER_IP);
109:
110: if (_mailServer != null) {
111: if (_mailServer.startsWith("java:comp/env")) {
112: try {
113: Context context = new InitialContext();
114: _session = (Session) context.lookup(_mailServer);
115: } catch (NamingException e) {
116: if (_logger.isErrorEnabled()) {
117: _logger.error(e);
118: }
119:
120: throw new PluginException(e);
121: }
122: } else {
123: _mailServerUsername = _servletConfig
124: .getInitParameter(EmailConstants.SMTPSERVER_USERNAME_IP);
125: _mailServerPassword = _servletConfig
126: .getInitParameter(EmailConstants.SMTPSERVER_PASSWORD_IP);
127: }
128: } else {
129: if (_logger.isErrorEnabled()) {
130: _logger
131: .error("Missing SMTP servername servlet initialization parameter: "
132: + EmailConstants.SMTPSERVER_IP);
133: }
134: }
135: }
136:
137: /**
138: * Setup the comment e-mail
139: *
140: * @param blog {@link Blog} information
141: * @param user {@link User}
142: * @param email Email message
143: * @throws EmailException If there is an error preparing the e-mail message
144: */
145: protected void setupEmail(Blog blog, User user, Email email)
146: throws EmailException {
147: email.setCharset(BlojsomConstants.UTF8);
148:
149: // If we have a mail session for the environment, use that
150: if (_session != null) {
151: email.setMailSession(_session);
152: } else {
153: // Otherwise, if there is a username and password for the mail server, use that
154: if (!BlojsomUtils.checkNullOrBlank(_mailServerUsername)
155: && !BlojsomUtils
156: .checkNullOrBlank(_mailServerPassword)) {
157: email.setHostName(_mailServer);
158: email.setAuthentication(_mailServerUsername,
159: _mailServerPassword);
160: } else {
161: email.setHostName(_mailServer);
162: }
163: }
164:
165: email.setFrom(blog.getBlogOwnerEmail(),
166: "Blojsom Forgotten Password");
167:
168: String authorizedUserEmail = user.getUserEmail();
169: if (BlojsomUtils.checkNullOrBlank(authorizedUserEmail)) {
170: authorizedUserEmail = blog.getBlogOwnerEmail();
171: }
172:
173: String authorizedUser = user.getUserName();
174: if (BlojsomUtils.checkNullOrBlank(authorizedUser)) {
175: authorizedUser = user.getUserLogin();
176: }
177:
178: email.addTo(authorizedUserEmail, authorizedUser);
179: email.setSentDate(new Date());
180: }
181:
182: /**
183: * Process the blog entries
184: *
185: * @param httpServletRequest Request
186: * @param httpServletResponse Response
187: * @param blog {@link Blog} instance
188: * @param context Context
189: * @param entries Blog entries retrieved for the particular request
190: * @return Modified set of blog entries
191: * @throws org.blojsom.plugin.PluginException
192: * If there is an error processing the blog entries
193: */
194: public Entry[] process(HttpServletRequest httpServletRequest,
195: HttpServletResponse httpServletResponse, Blog blog,
196: Map context, Entry[] entries) throws PluginException {
197: String username = BlojsomUtils.getRequestValue(
198: FORGOTTEN_USERNAME_PARAM, httpServletRequest);
199: String action = BlojsomUtils.getRequestValue(ACTION_PARAM,
200: httpServletRequest);
201:
202: if (!BlojsomUtils.checkNullOrBlank(username)) {
203: User user;
204:
205: try {
206: user = _fetcher.loadUser(blog, username);
207:
208: HtmlEmail email = new HtmlEmail();
209: setupEmail(blog, user, email);
210:
211: StringBuffer emailText = new StringBuffer(
212: "Here's your password: ");
213: if (blog.getUseEncryptedPasswords().booleanValue()) {
214: // Otherwise we have to create a new password since the password is one-way encrypted with MD5
215: Random random = new Random(new Date().getTime()
216: + System.currentTimeMillis());
217: int password = random.nextInt(Integer.MAX_VALUE);
218: String updatedPassword = Integer.toString(password);
219:
220: user.setUserPassword(BlojsomUtils
221: .digestString(updatedPassword));
222: _fetcher.saveUser(blog, user);
223: emailText.append(updatedPassword);
224: } else {
225: emailText.append(user.getUserPassword());
226: }
227:
228: email.setHtmlMsg(emailText.toString());
229: email.setTextMsg(emailText.toString());
230:
231: String to = user.getUserName();
232: if (BlojsomUtils.checkNullOrBlank(to)) {
233: to = user.getUserLogin();
234: }
235:
236: email.setSubject("Forgotten password e-mail for " + to);
237:
238: if (_logger.isDebugEnabled()) {
239: _logger
240: .debug("Constructed forgotten password e-mail message for username: "
241: + username);
242: }
243:
244: email.send();
245:
246: addOperationResultMessage(context, formatAdminResource(
247: CONSTRUCTED_PASSWORD_EMAIL_KEY,
248: CONSTRUCTED_PASSWORD_EMAIL_KEY, blog
249: .getBlogAdministrationLocale(),
250: new Object[] { to }));
251: httpServletRequest.setAttribute(
252: BlojsomConstants.PAGE_PARAM, ADMIN_LOGIN_PAGE);
253: } catch (FetcherException e) {
254: if (_logger.isErrorEnabled()) {
255: _logger.error(e);
256: }
257:
258: addOperationResultMessage(context, formatAdminResource(
259: FAILED_PASSWORD_CHANGE_KEY,
260: FAILED_PASSWORD_CHANGE_KEY, blog
261: .getBlogAdministrationLocale(),
262: new Object[] { username }));
263: httpServletRequest.setAttribute(
264: BlojsomConstants.PAGE_PARAM, ADMIN_LOGIN_PAGE);
265:
266: return entries;
267: } catch (EmailException e) {
268: if (_logger.isErrorEnabled()) {
269: _logger.error(e);
270: }
271:
272: addOperationResultMessage(context, formatAdminResource(
273: FAILED_PASSWORD_CHANGE_KEY,
274: FAILED_PASSWORD_CHANGE_KEY, blog
275: .getBlogAdministrationLocale(),
276: new Object[] { username }));
277: httpServletRequest.setAttribute(
278: BlojsomConstants.PAGE_PARAM, ADMIN_LOGIN_PAGE);
279:
280: return entries;
281: }
282: } else {
283: if (BlojsomUtils.checkNullOrBlank(action)) {
284: addOperationResultMessage(context, getAdminResource(
285: USERNAME_BLANK_KEY, USERNAME_BLANK_KEY, blog
286: .getBlogAdministrationLocale()));
287: }
288:
289: httpServletRequest.setAttribute(
290: BlojsomConstants.PAGE_PARAM,
291: FORGOTTEN_PASSWORD_PAGE);
292: }
293:
294: return entries;
295: }
296:
297: /**
298: * Perform any cleanup for the plugin. Called after {@link #process}.
299: *
300: * @throws org.blojsom.plugin.PluginException
301: * If there is an error performing cleanup for this plugin
302: */
303: public void cleanup() throws PluginException {
304: }
305:
306: /**
307: * Called when BlojsomServlet is taken out of service
308: *
309: * @throws org.blojsom.plugin.PluginException
310: * If there is an error in finalizing this plugin
311: */
312: public void destroy() throws PluginException {
313: }
314: }
|