/*
 * $Id: ChangeUserPasswordAction.java,v 1.33 2008/07/08 08:44:31 korowa Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: ChangeUserPasswordAction.java,v $
 * Revision 1.33  2008/07/08 08:44:31  korowa
 * Beim Ändern des Passworts eines Benutzers durch einen Administrator oder einen dedizierten Administrator
 * 			wird der Anzahl der Fehlversuche bei der Angabe des Passworts auf 0 gesetzt.
 *
 * Revision 1.32  2008/02/12 09:33:46  korowa
 * Eine Möglichkeit für den Benutzer hinzugefügt die Emailsart auszuwählen(HTML oder Plaintext)
 *
 * Revision 1.31  2006/10/04 03:15:00  marbobo
 * + Vollständige Unterstützung für Templates implementiert
 * + Alles von Virtoweb auf ProCoBa umgestellt
 *
 * Revision 1.30  2006/03/06 15:11:58  jonyp
 * + Bugfix (wg. Oracle)
 *
 * Revision 1.29  2005/12/15 15:28:50  marbobo
 * + Benutzername und Passwort für Mailserver implementiert
 *
 * Revision 1.28  2005/07/28 19:57:25  marbobo
 * + Template-Pfade angepasst
 *
 * Revision 1.27  2005/04/12 12:56:06  korowa
 * Neuer path für Velocity Engine gesetzt, Head.txt enthält jetzt die gemeinsame Eigenschaften
 * (header,css-Teil und importiertes Bild)die früher in jeder Mail- HTML-Datei  standen.
 *
 * Revision 1.26  2005/02/15 19:24:48  marbobo
 * + Unicode-Konforme E-Mails
 *
 * Revision 1.25  2005/02/14 14:01:45  bigmac
 * Applikationsweites CSS konfigurierbar gemacht + Refactorings
 *
 * Revision 1.24  2005/02/10 14:45:06  marbobo
 * + Unicode-Anzeige bei Emails
 *
 * Revision 1.23  2005/01/20 15:25:48  marbobo
 * + Anpassungen an den Methoden getRootURL() und getContextName()
 *
 * Revision 1.22  2004/11/10 15:02:50  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.21  2004/09/20 10:18:47  koppy
 * Mailgenerierung überarbeitet
 *
 * Revision 1.20  2004/09/16 13:10:54  marbobo
 * + Auf VKCRequestProcessor umgestellt
 *
 * Revision 1.19  2004/08/30 20:06:35  marbobo
 * + Verbesserung des Redirectmechanismus
 *
 * Revision 1.18  2004/08/07 18:17:05  marbobo
 * + Bugfix für Zeitangaben und Refactorings
 *
 * Revision 1.17  2004/08/02 20:19:17  marbobo
 * + Refactorings und Behandlung von Fehlermeldungen
 *
 * Revision 1.16  2004/07/13 22:33:22  marbobo
 * + Sicherheitsüberprüfungen
 *
 * Revision 1.15  2004/05/28 10:43:34  teng
 * *** empty log message ***
 *
 * Revision 1.14  2004/03/18 01:20:31  marbobo
 * EditUserAction und EditUserForm auf request-scope umgestellt
 *
 * Revision 1.13  2004/03/11 20:17:14  bigmac
 * Anpassungen an VKCUserSerializer
 *
 * Revision 1.12  2004/03/09 18:40:36  bigmac
 * Anpassungen an VKCSysParameterSerializer
 *
 * Revision 1.11  2004/03/08 16:29:23  teng
 * MailUtils.java und MailImage.java werden in vkc.misc.mail geschoben
 *
 * Revision 1.10  2004/03/05 19:54:41  teng
 * vkc.misc.VKCMailTemplateParser wird durch vkc.misc.TemplateParser ersetzt
 *
 * Revision 1.9  2004/02/26 15:47:16  teng
 * Funktion MailUtils.sendSMTPMail(senderAddr, recepient, subject, asciiText, htmlText, null, null, images, smtpServer) ist geaendert. Parameter images enthaelt nun MailImage-Objekt statt String[]
 *
 * Revision 1.8  2004/01/26 13:55:24  marbobo
 * +Benutzer- und Gruppenverwaltung für dedizierte Administratoren
 *
 * Revision 1.7  2004/01/12 17:16:36  teng
 * Alte VKCTemplateParser wird durch die Klasse VKCMailTemplateParser ersetzt.
 * VKCMailTemplateParser ist die Unterklasse der VKCTemplateParser und nur benutzt von Email-Benachrichtigung. 
 * VKCTemplateParser kann dann fuer allgemeinen Zweck genutzt werden.
 *
 * Revision 1.6  2003/12/24 10:12:09  bigmac
 * Projektweite Import-Optimierung
 *
 * Revision 1.5  2003/12/11 16:15:08  teng
 * Mailing mit Bild zum neuen Templatedateien angepasst
 *
 * Revision 1.4  2003/10/28 00:56:55  marbobo
 * Mailing auf Templates umgestellt
 *
 * Revision 1.3  2003/10/06 09:57:01  marbobo
 * +Zufälligespasswort generieren
 * +EMail verschicken
 *
 * Revision 1.2  2003/09/08 16:59:01  marbobo
 * *** empty log message ***
 *
 * Revision 1.1  2003/08/22 16:35:22  marbobo
 * Initiale Version
 *
 */
package vkc.administration.action;

import java.security.MessageDigest;
import java.sql.Timestamp;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.struts.Globals;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import vkc.administration.form.ChangeUserPasswordForm;
import vkc.db.entities.VKCUser;
import vkc.db.serializer.VKCSysParameterSerializer;
import vkc.db.serializer.VKCUserSerializer;
import vkc.misc.MailUtils;
import vkc.misc.TemplateParser;
import vkc.misc.VKCLogManager;
import vkc.util.ServletUtils;
import vkc.util.VKCCoder;
import vkc.util.VKCStringUtils;
import vkc.view.WebShare;
import vkc.view.bean.ResourceInfo;

/**
 * Action-Klasse zum Ändern des Passworts eines 
 * Benutzer-Objektes
 *
 * @author marbobo
 */
public final class ChangeUserPasswordAction extends Action {
	private ActionForward DEFAULT_FORWARD = new ActionForward("/templates/${template.name}/administration/changeUserPassword.jsp");
	private ActionForward INFO_FORWARD = new ActionForward("/templates/${template.name}/common/InfoPage.jsp");

	//~ Methods ----------------------------------------------------------------

	/**
	 * Hier werden die entsprechenden Aktionen eingeleitet
	 */
	public ActionForward execute(ActionMapping mapping, 
	        					 ActionForm f, 
	        					 HttpServletRequest request, 
	        					 HttpServletResponse response) 
		throws Exception {
		ChangeUserPasswordForm form = (ChangeUserPasswordForm)f;
		VKCUser user = form.getUser();

		if (!user.hasAdminPrivileges() 
				&& !user.isDedicatedUsersAdmin() 
				&& form.getUserInfo() == null 
				&& !user.getUserId().equals( form.getUserInfo().getCreatorId())) {
            request.setAttribute(WebShare.INFO_KEY, "vkc.info.access_denied");
            
            return INFO_FORWARD;
        }

        // Dispatches the Action
		if (request.getParameter("action.change.password") != null) {
			return handleChangePasswordAction(form, request);
		}

		if (request.getParameter("action.random.password") != null) {
			return handleGenerateRandomPasswordAction(form, request);
		}

		if (request.getParameter("action.back") != null) {
			return new ActionForward(form.getRedirectPath(), true);
		}

		// Not Action
		return DEFAULT_FORWARD;
	}

	private ActionForward handleGenerateRandomPasswordAction(ChangeUserPasswordForm form, HttpServletRequest request) throws Exception {
		VKCUser user = form.getUser();
		VKCUser editUser = VKCUserSerializer.retrieveUser(form.getUserId());

		String username = editUser.getUser();
		//zufälliges MD5-Passwort erzeugen

		String password = RandomStringUtils.randomAlphanumeric( 8 );
		byte[] md5Bytes = (username + password).getBytes("ISO-8859-1");

		MessageDigest digest = MessageDigest.getInstance("MD5");
		digest.reset();
		digest.update(md5Bytes);
		byte[] fingerPrint = digest.digest();
		fingerPrint = VKCCoder.base64Encode(fingerPrint);
		String md5Password = new String(fingerPrint, "ISO-8859-1");
		editUser.setPassword(md5Password);
		editUser.setPasswordChanged(false);
		editUser.setPasswordChangedTs(new Timestamp(System.currentTimeMillis()));
		editUser.setLastChanged(new Timestamp(System.currentTimeMillis()));
		editUser.setLastChangerId(user.getUserId());
        editUser.setPwdMismatchCount(new Integer(0));
		
		try {
			// die Zugangsdaten zuschicken
			String senderAddr  = VKCSysParameterSerializer.retrieveValue("MAIL", "AdminEmail", "");
			String smtpServer  = VKCSysParameterSerializer.retrieveValue("MAIL", "MailServer", "");
			String smtpUsername  = VKCSysParameterSerializer.retrieveValue("MAIL", "MailUsername", "");
			String smtpPassword  = VKCSysParameterSerializer.retrieveValue("MAIL", "MailPassword", "");
			String vkc_rootURL = WebShare.getRootURL() + WebShare.getContextPath();
			String subject     = WebShare.resources.getMessage(editUser.getLanguage().getLocale(), "vkc.changepassword");
			String recepient   = VKCStringUtils.decodeXmlEntities(editUser.getEmail());

			TemplateParser asciiTemplate = TemplateParser.getTemplateParser();
			TemplateParser htmlTemplate = TemplateParser.getTemplateParser();

			HashMap context = new HashMap();
			context.put("adminEmail", senderAddr);
			context.put("homepage", vkc_rootURL);
			context.put("username", VKCStringUtils.filterUnicodeChars(editUser.getUser()));
			context.put("fullname", VKCStringUtils.filterUnicodeChars(editUser.getFirstname() + " " + editUser.getLastname()));
			context.put("password", password);
			context.put("resources", new ResourceInfo(WebShare.resources, editUser.getLanguage().getLocale()));
			context.put("vkcstringutils", new VKCStringUtils());
			context.put("template", editUser.getTemplate().getName());
			
			asciiTemplate.setContextData(context);
			htmlTemplate.setContextData(context);
			String asciiPath = "templates/${template.name}/velocitytemplates/mail/changepassword_notification.plain";
			String htmlPath = "templates/${template.name}/velocitytemplates/mail/changepassword_notification.html";
			
			String asciiText = asciiTemplate.createString(ServletUtils.replacePathVars(asciiPath, editUser));
			String htmlText = htmlTemplate.createString(ServletUtils.replacePathVars(htmlPath, editUser));
			
			MailUtils m = new MailUtils(editUser);
            if(editUser.isEnableHtmlNotification())m.sendSMTPMailWithVKCLogo( senderAddr, recepient, subject, asciiText, htmlText, null, null, smtpServer, smtpUsername, smtpPassword );
            else m.sendSMTPMail( senderAddr, recepient, subject, asciiText,null , null, null, smtpServer, smtpUsername, smtpPassword );
		} catch (Exception e) {
			ActionErrors errors = new ActionErrors();
			errors.add("mailmessage.failure", new ActionError("vkc.administration.newuser.mailfailure"));
			request.setAttribute(Globals.ERROR_KEY, errors);
			VKCLogManager.errorLog(this, "1", " - email sending failes: " + e.getMessage(), e);
			
			return DEFAULT_FORWARD;
		}

        VKCUserSerializer.saveUser(editUser);
		form.setPasswordChanged(true);

		if (user.getUserId().equals(editUser.getUserId())) {
			request.getSession().setAttribute(WebShare.USER_KEY, editUser);
		}

		return DEFAULT_FORWARD;
	}

	/**
	 * Diese Methode ändert das Passwort eines Benutzers
	 */
	private ActionForward handleChangePasswordAction(ChangeUserPasswordForm form, HttpServletRequest request) throws Exception {
		VKCUser user = form.getUser();
		VKCUser editUser = VKCUserSerializer.retrieveUser(form.getUserId());

		String username = editUser.getUser();
		String newpassword = form.getNewpassword().trim();
		byte[] md5Bytes = (username + newpassword).getBytes("ISO-8859-1");

		MessageDigest digest = MessageDigest.getInstance("MD5");
		digest.reset();
		digest.update( md5Bytes );
		byte[] fingerPrint = digest.digest();
		fingerPrint = VKCCoder.base64Encode(fingerPrint);
		String md5Password = new String(fingerPrint, "ISO-8859-1");
		editUser.setPassword(md5Password);
		editUser.setPasswordChanged(false);
		editUser.setPasswordChangedTs(new Timestamp(System.currentTimeMillis()));
		editUser.setLastChanged(new Timestamp(System.currentTimeMillis()));
		editUser.setLastChangerId(user.getUserId());
        editUser.setPwdMismatchCount(new Integer(0));

		try {
			// die Zugangsdaten zuschicken
			String senderAddr  = VKCSysParameterSerializer.retrieveValue("MAIL", "AdminEmail", "");
			String smtpServer  = VKCSysParameterSerializer.retrieveValue("MAIL", "MailServer", "");
			String smtpUsername  = VKCSysParameterSerializer.retrieveValue("MAIL", "MailUsername", "");
			String smtpPassword  = VKCSysParameterSerializer.retrieveValue("MAIL", "MailPassword", "");
			String vkc_rootURL = WebShare.getRootURL() + WebShare.getContextPath();
			String subject     = WebShare.resources.getMessage(editUser.getLanguage().getLocale(), "vkc.changepassword");
			String recepient   = VKCStringUtils.decodeXmlEntities(editUser.getEmail());

			TemplateParser asciiTemplate = TemplateParser.getTemplateParser();
			TemplateParser htmlTemplate = TemplateParser.getTemplateParser();

			HashMap context = new HashMap();
			context.put("adminEmail", senderAddr);
			context.put("homepage", vkc_rootURL);
			context.put("username", VKCStringUtils.filterUnicodeChars(editUser.getUser()));
			context.put("fullname", VKCStringUtils.filterUnicodeChars(editUser.getFirstname() + " " + editUser.getLastname()));
			context.put("password", newpassword);
			context.put("resources", new ResourceInfo(WebShare.resources, editUser.getLanguage().getLocale()));
			context.put("vkcstringutils", new VKCStringUtils());
			context.put("template", editUser.getTemplate().getName());
			
			asciiTemplate.setContextData(context);
			htmlTemplate.setContextData(context);
			String asciiPath = "templates/${template.name}/velocitytemplates/mail/changepassword_notification.plain";
			String htmlPath = "templates/${template.name}/velocitytemplates/mail/changepassword_notification.html";
			
			String asciiText = asciiTemplate.createString(ServletUtils.replacePathVars(asciiPath, editUser));
			String htmlText = htmlTemplate.createString(ServletUtils.replacePathVars(htmlPath, editUser));
			
			MailUtils m = new MailUtils(editUser);
            if(editUser.isEnableHtmlNotification())m.sendSMTPMailWithVKCLogo( senderAddr, recepient, subject, asciiText, htmlText, null, null, smtpServer, smtpUsername, smtpPassword );
            else m.sendSMTPMail( senderAddr, recepient, subject, asciiText,null , null, null, smtpServer, smtpUsername, smtpPassword );
		} catch (Exception e) {
			ActionErrors errors = new ActionErrors();
			errors.add("mailmessage.failure", new ActionError("vkc.administration.newuser.mailfailure"));
			request.setAttribute(Globals.ERROR_KEY, errors);
			VKCLogManager.errorLog(this, "1", " - email sending failes: " + e.getMessage(), e);
			
			return DEFAULT_FORWARD;
		}

        VKCUserSerializer.saveUser(editUser);
		form.setPasswordChanged(true);

		if (user.getUserId().equals(editUser.getUserId())) {
			request.getSession().setAttribute(WebShare.USER_KEY, editUser);
		}

		return DEFAULT_FORWARD;
	}
}