package com.n2bb.security;

/**** COMMON IMPORTS BEGIN ****/

import java.security.Principal;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.n2bb.action.AbstractAction;
import com.n2bb.util.N2bbException;
import com.n2bb.util.ActionConstants;
import org.apache.struts.action.*;

/**
 * When a user's password has expired, this action:
 *
 * 1) takes the user to the "Change Expired Password" page, or
 * 2) saves the new password, and logs the user in again
 *
 * @author kmatsuoka
 * @version $Id: ChangeExpiredPasswordAction.java,v 1.1 2006/06/17 00:48:49 rao Exp $
 */
public class ChangeExpiredPasswordAction extends AbstractAction {

    /**
     * When the user logs in with the correct password but the password
     * has expired, N2bbJDBCRealm authenticates the user with a temporary
     * Principal whose name is the username prepended by this prefix.
     */
    public static final String CHPASS_PREFIX = "chpass_";

    protected ActionForward executeAction(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        Principal principal = request.getUserPrincipal();

        // extract the actual username from the temporary principal's name
        String username = principal.getName().substring(CHPASS_PREFIX.length());
        ChangeExpiredPasswordForm editForm = (ChangeExpiredPasswordForm) form;

        if (editForm.getAction().equals(ActionConstants.save)) {
            if (editForm.getUsername() == null ||
                    !username.equals(editForm.getUsername())) {
                // this is necessary to stop users from changing
                // other users' passwords by manually submitting
                // another user's username
                request.getSession().invalidate();
                return mapping.findForward("home");
            }

            try {
                SecurityManager.getInstance().changeExpiredPassword(
                        username,
                        editForm.getPassword()
                );
            }
            catch (IdenticalPasswordException e) {
                editForm.setPassword("");
                editForm.setConfirmPassword("");
                throw new N2bbException("error.userManager.passwordNotChanged");
            }

            HttpSession session = request.getSession();
            String originalURI = (String) session.getAttribute("originalURI");

            // logs user out so they can log in under real username
            request.getSession().invalidate();

             // gets new session
            session = request.getSession();
            session.setAttribute("username", username);
            session.setAttribute("password", editForm.getPassword());

            if (originalURI != null) {
                // redirects user to the URI they originally requeted
                response.sendRedirect(response.encodeRedirectURL(originalURI));
                return null;
            }
            else {
                return mapping.findForward("home");
            }
        }
        else {
            ActionErrors errors = new ActionErrors();
            errors.add(ActionErrors.GLOBAL_ERROR,
                    new ActionError("error.login.passwordExpired"));
            saveErrors(request, errors);
            editForm.setUsername(username);
            return mapping.findForward("enterPassword");
        }
    }
}

