SimpleLoginController.java :  » J2EE » Expresso » com » jcorporate » expresso » services » controller » Java Open Source

Java Open Source » J2EE » Expresso 
Expresso » com » jcorporate » expresso » services » controller » SimpleLoginController.java
/* ====================================================================
 * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
 *
 * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by Jcorporate Ltd.
 *        (http://www.jcorporate.com/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. "Jcorporate" and product names such as "Expresso" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written permission,
 *    please contact info@jcorporate.com.
 *
 * 5. Products derived from this software may not be called "Expresso",
 *    or other Jcorporate product names; nor may "Expresso" or other
 *    Jcorporate product names appear in their name, without prior
 *    written permission of Jcorporate Ltd.
 *
 * 6. No product derived from this software may compete in the same
 *    market space, i.e. framework, without prior written permission
 *    of Jcorporate Ltd. For written permission, please contact
 *    partners@jcorporate.com.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Jcorporate Ltd. Contributions back
 * to the project(s) are encouraged when you make modifications.
 * Please send them to support@jcorporate.com. For more information
 * on Jcorporate Ltd. and its products, please see
 * <http://www.jcorporate.com/>.
 *
 * Portions of this software are based upon other open source
 * products and are subject to their respective licenses.
 */

package com.jcorporate.expresso.services.controller;

import com.jcorporate.expresso.core.ExpressoConstants;
import com.jcorporate.expresso.core.controller.Controller;
import com.jcorporate.expresso.core.controller.ControllerException;
import com.jcorporate.expresso.core.controller.ControllerRequest;
import com.jcorporate.expresso.core.controller.ControllerResponse;
import com.jcorporate.expresso.core.controller.ErrorCollection;
import com.jcorporate.expresso.core.controller.Input;
import com.jcorporate.expresso.core.controller.NonHandleableException;
import com.jcorporate.expresso.core.controller.Output;
import com.jcorporate.expresso.core.controller.ServletControllerRequest;
import com.jcorporate.expresso.core.controller.State;
import com.jcorporate.expresso.core.controller.Transition;
import com.jcorporate.expresso.core.controller.session.PersistentSession;
import com.jcorporate.expresso.core.dataobjects.Securable;
import com.jcorporate.expresso.core.db.DBException;
import com.jcorporate.expresso.core.dbobj.DBObject;
import com.jcorporate.expresso.core.dbobj.ValidValue;
import com.jcorporate.expresso.core.i18n.Messages;
import com.jcorporate.expresso.core.misc.ConfigManager;
import com.jcorporate.expresso.core.misc.ConfigurationException;
import com.jcorporate.expresso.core.misc.SerializableString;
import com.jcorporate.expresso.core.misc.StringUtil;
import com.jcorporate.expresso.core.security.User;
import com.jcorporate.expresso.kernel.util.FastStringBuffer;
import com.jcorporate.expresso.services.dbobj.RegistrationDomain;
import com.jcorporate.expresso.services.dbobj.Setup;
import com.jcorporate.expresso.services.validation.AuthValidationException;
import com.jcorporate.expresso.services.validation.ValidationEntry;
import org.apache.log4j.Logger;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionForward;
import org.apache.struts.config.ForwardConfig;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.Vector;

/**
 * Main Login Controller - used for login/logout and basic interaction with
 * the registration system.  This class recognizes the 'registration' classHandler
 * name in the expresso-config.xml  It uses the classname in that field to
 * construct and forward to the appropriate registration class.
 */
public class SimpleLoginController
        extends LoginController {

    private static Logger log = Logger.getLogger(SimpleLoginController.class);

    /**
     * LoginController constructor.  Sets all the states and parameters
     * for the system.
     */
    public SimpleLoginController() {
        super();
        State promptLogin = new State("promptLogin", "Prompt Login");
        promptLogin.addOptionalParameter("next"); //Where do we link after login?
        promptLogin.addOptionalParameter("immediate"); //Do we even display the
        //confirmation page or do we
        //just jump straight to the
        //page on success? Y or N
        promptLogin.setSecure(true);
        promptLogin.addOptionalParameter("next"); //Where do we link after login?
        promptLogin.addOptionalParameter("immediate"); //Do we even display the
        //confirmation page or do we
        //just jump straight to the
        //page on success?
        promptLogin.addOptionalParameter("LoginName");
        addState(promptLogin);

        State processLogin = new State("processLogin", "Login");
        processLogin.setSecure(true);
        addState(processLogin);

        State processLogout = new State("processLogout", "Logout");
        addState(processLogout);

        State promptChangePassword = new State("promptChangePassword",
                "Prompt Change Password");
        promptChangePassword.setSecure(true);
        addState(promptChangePassword);


        State processChangePassword = new State("processChangePassword",
                "Change Password");
        processChangePassword.setSecure(true);
        addState(processChangePassword);

        State emailValidate = new State("emailValidate", "Validate User's Email Address");
        emailValidate.addRequiredParameter("db");
        emailValidate.addRequiredParameter("UserName");
        emailValidate.addOptionalParameter("loginController");
        addState(emailValidate);

        State promptSendPassword = new State("promptSendPassword",
                "Prompt Send Password");
        addState(promptSendPassword);

        State processSendPassword = new State("processSendPassword",
                "Reset & Send Password");
        processSendPassword.addParameter("Email",
                false,
                DBObject.EMAIL_MASK,
                "You must enter a valid email address");
        addState(processSendPassword);

        State s = new State("promptRevalidate", "Prompt Revalidate");
        this.addState(s);

        s = new State("processRevalidate", "Process Revalidate");
        s.addParameter("Email", false,
                DBObject.EMAIL_MASK, "You must enter a valid email address");
        this.addState(s);

        setInitialState("promptLogin");
        this.setSchema(com.jcorporate.expresso.core.ExpressoSchema.class);
    }


    /**
     * If the user has validated the email sent to validate change password request,
     * then this method actually resets thepassword and sends notification.
     *
     * @param request  The framework controller request
     * @param response The framework ControllerResponse object
     * @throws ControllerException    upon logic error
     * @throws NonHandleableException upon fatal error
     */
    protected void runEmailValidateState(ControllerRequest request,
                                         ControllerResponse response)
            throws ControllerException,
            NonHandleableException {
// The db context for the user (Note: this is different from the Validation entry context, which
// could very well be in a different DB context)
        String dbname = StringUtil.notNull(request.getParameter("db"));

// The login name of the user
        String loginName = StringUtil.notNull(request.getParameter("UserName"));
        String registrationController = StringUtil.notNull(request.getParameter("RegistrationController"));
        if (registrationController.length() == 0) {
            registrationController = this.getDefaultRegistrationController().getClass().getName();
        }

        String loginController = StringUtil.notNull(request.getParameter("LoginController"));
        try {
            ErrorCollection errors = new ErrorCollection();

// Make sure that the user with this loginName actually exists
            User user = new User();
            user.setDataContext(dbname);
            user.setLoginName(loginName);

            if (!user.find()) {
//errors.addError("Account \"" + loginName + "\" not found");
                errors.addError("login.accountnotfound", (Object) loginName);
            }
// Make sure the User record has not been disabled for some reason
            if (errors.isEmpty()) {
                if (user.getAccountStatus().equals("D")) {
                    errors.addError("error.login.accountdisabled", (Object) loginName);
                }
            }

            if (!errors.isEmpty()) {
                response.saveErrors(errors);
                return;
            }

// Reset the user's password and send email
            String password = null;
            if (errors.isEmpty()) {
                password = user.randomPassword();
                user.setPassword(password);
                user.setAccountStatus("A");
                user.update();

                FastStringBuffer msg = FastStringBuffer.getInstance();
                msg.append(response.getString("passwdReset", loginName,
                        password,
                        Setup.getValue(request.getDataContext(),
                                "CompanyName"),
                        Setup.getValue(request.getDataContext(),
                                "HomePageURL")));
                user.notify(response.getString("passwdResetSubject"),
                        msg.toString());
                msg.release();
            }
// If no errors happened so far, just create an Output to state
// the success and what happened
            if (errors.isEmpty()) {
                Output o = new Output("successMessage",
                        "Password succesfully reset and email sent to user \"" +
                        loginName + "\" ");
                response.add(o);
                FastStringBuffer msg = FastStringBuffer.getInstance();
                try {
                    msg.append("You may log into the system using the password: \n");
                    msg.append(password);
                    msg.append("\n This password has been emailed to you ");
                    msg.append("and should be kept in a safe place");

                    response.add(new Output("passwordMessage", msg.toString()));
                } finally {
                    msg.release();
                }

                Transition login = new Transition();
                login.setLabel("Log In");
                login.setName("promptLogin");
                login.addParam(Controller.CONTROLLER_PARAM_KEY,
                        loginController);
                login.addParam("dbContext", dbname);
                response.add(login);

                Transition register = new Transition();
                register.setLabel("Register");
                register.setName("promptSelfRegister");
                register.addParam(Controller.CONTROLLER_PARAM_KEY,
                        registrationController);
                register.addParam("dbContext", dbname);
                response.add(register);
            } else {

// Errors happened, add the error collection to the response
                response.saveErrors(errors);
            }
        } catch (DBException dbe) {
            throw new ControllerException("DB error", dbe);
        }

    }


    /**
     * @return the title of this controller
     */
    public String getTitle() {
        return ("Expresso Login");
    }


    /**
     * Processes the "change my password" request.
     *
     * @param request  The framework controller request
     * @param response The framework ControllerResponse object
     * @throws ControllerException    upon logic error
     * @throws NonHandleableException upon fatal error
     */
    protected void runProcessChangePasswordState(ControllerRequest request,
                                                 ControllerResponse response)
            throws ControllerException,
            NonHandleableException {
        ErrorCollection errors = new ErrorCollection();
        String loginName = request.getUser();

        try {
            User myUser = new User();
            myUser.setDataContext(request.getDataContext());
            myUser.setLoginName(loginName);

            if (loginName.equals("") || loginName.equals(User.UNKNOWN_USER) ||
                    !myUser.find()) {
                delayLogin(); //Slow 'em down
                errors.addError(response.getString("error.login.mustloginchngpaswd"));
            } else if (!myUser.passwordEquals(StringUtil.notNull(request.getParameter("oldPassword")))) {
                errors.addError(response.getString("error.login.passwordinvalid", loginName));
            }
            if (errors.getErrorCount() < 1) {
                if (!myUser.getAccountStatus().equals("A")) {
                    log.warn("User \"" + loginName +
                            "\" attempted changin password, denied because account status is \"" +
                            myUser.getAccountStatus() + "\"");
                    delayLogin(); //Slow 'em down
                    errors.addError(response.getString("error.login.disablednochngpaswd", loginName));
                }
            }
            if (errors.getErrorCount() < 1) {
                if (!request.getParameter("Password").equals(request.getParameter("password_verify"))) {

                    //password and verify do not match. Add an error.
                    errors.addError("error.login.passwdnomatch");
                }
            }
            if (errors.getErrorCount() < 1) {
                User user = new User();
                user.setDataContext(request.getDataContext());
                user.setUid(request.getUid());
                user.retrieve();
                user.setPassword(request.getParameter("Password"));
                user.update();
            }
        } catch (DBException dbe) {
            throw new ControllerException(dbe);
        } finally {
            if (errors.getErrorCount() < 1) {
                response.clearFormCache();

                Output successMessage = new Output("successMessage",
                        response.getString("PasswordChangeSuccess", loginName));
                response.addOutput(successMessage);
                response.addTransition(new Transition("promptChangePassword",
                        this));
                response.addTransition(new Transition("promptLogin", this));
                response.addTransition(new Transition("processLogout", this));

                Transition editPref = new Transition();
                editPref.setName("editPreferences");
                editPref.addParam(Controller.CONTROLLER_PARAM_KEY,
                        "com.jcorporate.expresso.services.controller.EditUserPreference");
                editPref.addParam(STATE_PARAM_KEY, "edit");
                response.add(editPref);

                Transition showDBMenu = new Transition();
                showDBMenu.setName("showDBMenu");
                showDBMenu.addParam(Controller.CONTROLLER_PARAM_KEY,
                        this.getDefaultRegistrationController().getClass().getName());
                showDBMenu.addParam(STATE_PARAM_KEY, "showDBMenu");
                response.add(showDBMenu);
            } else {
                response.saveErrors(errors);
                response.setFormCache();
                transition("promptChangePassword", request, response);
            }
        }
    }

    /**
     * Processes the login request.... loops back to the promptLoginState
     * if there's an error processing this system.
     *
     * @param request  The framework controller request
     * @param response The framework ControllerResponse object
     * @throws ControllerException    upon logic error
     * @throws NonHandleableException upon fatal error
     */
    protected void runProcessLoginState(ControllerRequest request,
                                        ControllerResponse response)
            throws ControllerException,
            NonHandleableException {
        ErrorCollection errors = new ErrorCollection();
        PersistentSession session = request.getSession();
        String destination = null;

        /* Normally, accessing the HttpServletRequest/Response objects is a very bad
        * idea. The fact that this controller does it means that it is non-portable
        * outside the servlet environment
        */
        ServletControllerRequest sr = (ServletControllerRequest) request;
        HttpServletResponse hres = (HttpServletResponse) sr.getServletResponse();
        HttpServletRequest hreq = (HttpServletRequest) sr.getServletRequest();
        String dbContext = StringUtil.notNull(request.getParameter("dbContext"));
        request.setDataContext(dbContext);

        //
        //Remove wildcards so that it isn't used in finding users.
        //
        String loginName = StringUtil.replaceAll(StringUtil.notNull(request.getParameter("LoginName"))
                , "%", "");
        int uid = 0;

        try {
            uid = attemptLogin(request, response, errors, hreq,
                    hres, session);
        } catch (DBException dbe) {
            throw new ControllerException(dbe);
        } finally {
            if (errors.getErrorCount() > 0) {
                log.debug("Transitioning back to login state...");
                response.saveErrors(errors);
                response.setFormCache();
                transition("promptLogin", request, response);

                return;
            }

            ///////////////////////////////////////
            // good login
            ///////////////////////////////////////
            request.setUser(loginName);
            if (log.isDebugEnabled()) {
                log.debug("good login for uid: " + uid);
            }

            // set locale
            try {
                request.getSession().removePersistentAttribute(Messages.LOCALE_KEY);
                request.getSession().removePersistentAttribute(Globals.ERROR_KEY);
                Messages.establishLocale(hreq);
            } catch (ServletException se) {
                log.error("Cannot manipulate local in session", se);

                // do not abort entire action since this error is recoverable
            }

            /* Template method, override in your derived class to do any
work you may want to accomplish after a successful login */
            postLoginProcessing(request, response);
            String origURL = null;
            if (session != null) {
                SerializableString originalURL = (SerializableString) session.getPersistentAttribute(
                        ExpressoConstants.CONTROLLER_ORIGINAL_URL_KEY);

                if (originalURL != null) {
                    origURL = originalURL.toString();
                    session.removePersistentAttribute(ExpressoConstants.CONTROLLER_ORIGINAL_URL_KEY);
                }
            }
            String nextURL = StringUtil.notNull(request.getParameter("next"));
            if (origURL != null && origURL.length() > 0) {

                /** redirect to original destination
                 *  BUT be careful to use an HTTP tag redirection
                 *  so that the login cookie can be planted.  we cannot
                 *  simply call sendRedirect because then the cookie
                 *  from the current response (set during attemptLogin)
                 *  would not reach the browser.  instead, we send a result
                 *  page, which plants the cookie, and that page has a
                 *  redirect tag.
                 */

                // provide redirect page with a link to destination in case the browser does
                // not redirect properly
                hreq.setAttribute("destination", origURL);
            } else if (nextURL.length() > 0) {
                hreq.setAttribute("destination", nextURL);
            } else {

                /**
                 *
                 if we got here, someone went directly to login page, so there
                 was no original "destination" besides the login page.
                 in that case, send them to a some "home" page,
                 specified as the forward "home" forward
                 */

                // use the previous status.jsp page if we do not find
                // a "home" global forward specification
                destination = null;

                ActionForward fwd = null;
                try {
                    ServletControllerRequest req = (ServletControllerRequest) request;
                    ForwardConfig fc = req.getMapping().getModuleConfig().findForwardConfig("home");
                    fwd = new ActionForward(fc.getName(), fc.getPath(),
                            fc.getRedirect(), fc.getContextRelative());
                } catch (Exception e) {
                    log.error("cannot cast to get servlet request: ", e);
                }

                if (fwd == null) {
                    log.warn("global forward 'home' is missing using status.jsp");
                    response.addTransition(new Transition("promptChangePassword",
                            this));
                    response.addTransition(new Transition("promptLogin", this));
                    response.addTransition(new Transition("processLogout", this));

                    Transition editPref = new Transition();
                    editPref.setName("editPreferences");
                    editPref.addParam(Controller.CONTROLLER_PARAM_KEY,
                            com.jcorporate.expresso.services
                            .controller.EditUserPreference.class.getName());
                    editPref.addParam(STATE_PARAM_KEY, "edit");
                    response.add(editPref);

                    Transition showDBMenu = new Transition();
                    showDBMenu.setName("showDBMenu");
                    showDBMenu.addParam(Controller.CONTROLLER_PARAM_KEY,
                            this.getDefaultRegistrationController()
                            .getClass().getName());
                    showDBMenu.addParam(STATE_PARAM_KEY, "showDBMenu");
                    response.add(showDBMenu);

                } else {
                    destination = ConfigManager.getContextPath() +
                            fwd.getPath();

                    hreq.setAttribute("destination", destination);
                    if (log.isInfoEnabled()) {
                        log.info("via redirect.jsp, redirecting to: "
                                + destination);
                    }
                }
            }
        }


        // redirect.jsp actually handles redirect
    }

    /**
     * Logs a user out of the system and invalidates their session.
     *
     * @param request  The framework controller request
     * @param response The framework ControllerResponse object
     * @throws ControllerException upon logic error
     */
    protected void runProcessLogoutState(ControllerRequest request,
                                         ControllerResponse response)
            throws ControllerException {
        PersistentSession session = request.getSession();
        String loginName = request.getUser();
        String successMessage = loginName + " has been logged out";

        if (loginName.equals("")) {
            successMessage = "You were not logged in anyway!";
        }

        if (request instanceof ServletControllerRequest) {
            ServletControllerRequest sreq = (ServletControllerRequest) request;
            LoginController.setCookie(null, null,
                    (HttpServletResponse) sreq.getServletResponse(),
                    true, request.getDataContext());

        }
        Output successOutput = new Output();
        successOutput.setName("sucessMessage");
        successOutput.setContent(successMessage);
        response.add(successOutput);
        response.setUser(User.UNKNOWN_USER);

        Transition pr = new Transition("promptSelfRegister", this.getDefaultRegistrationController());
        pr.addParam("dbContext", request.getDataContext());
        response.add(pr);

        Transition pl = new Transition("promptLogin", this);
        pl.addParam("dbContext", request.getDataContext());
        response.add(pl);

        session.setClientAttribute("UserName", "NONE");
        session.setClientAttribute("Password", "NONE");
        session.setClientAttribute("dbContext", "NONE");
        session.removePersistentAttribute("CurrentLogin");
        session.invalidate();

        postLogoutProcessing(request, response);


    }

    /**
     * Template Method pattern. override in subclasses as necessary
     *
     * @param request  The framework controller request
     * @param response The framework ControllerResponse object
     */
    public void postLogoutProcessing(ControllerRequest request, ControllerResponse response)
            throws ControllerException {
        //      * Template Method pattern. override in subclasses as necessary
    }


    /**
     * Process the "Please Send me a new password" state.
     *
     * @param request  The framework controller request
     * @param response The framework ControllerResponse object
     * @throws ControllerException    upon logic error
     * @throws NonHandleableException upon fatal error
     */
    protected void runProcessSendPasswordState(ControllerRequest request,
                                               ControllerResponse response)
            throws ControllerException,
            NonHandleableException {
        //
        //Validate input
        //
        ErrorCollection errors = request.getErrorCollection();
        if (errors == null) {
            errors = new ErrorCollection();
        }


        String dbContext = StringUtil.notNull(request.getParameter("dbContext"));

        if (!dbContext.equals("")) {
            request.setDataContext(dbContext);
        }

        response.add(new Transition("promptSelfRegister", this.getDefaultRegistrationController()));
        response.add(new Transition("promptLogin", this));
        String email = StringUtil.replaceAll(StringUtil.notNull(request.getParameter("Email")), "%", "");

        if (email == null || email.length() == 0) {
            errors.addError("error.login.invalidemail");
        }

        if (errors.getErrorCount() > 0) {
            response.saveErrors(errors);
            transition("promptSendPassword", request, response);
            return;
        }

        try {
            User myUser = new User();
            myUser.setDataContext(request.getDataContext());
            myUser.setEmail(email);

            if (!myUser.find()) {
                errors.addError("error.login.nouseremailfound");
            }

            String loginName = myUser.getLoginName();

            if (errors.getErrorCount() < 1) {
                if (!myUser.getAccountStatus().equals("A")) {
                    log.warn("User \"" + loginName +
                            "\" attempted password reset, denied because account status is \"" +
                            myUser.getAccountStatus() + "\"");
                    errors.addError("error.login.accountdiablednosendpaswd");
                }
            }
            if (errors.getErrorCount() < 1) {
                boolean emailValidate = false;
                RegistrationDomain rd = null;
                rd = new RegistrationDomain();
                rd.setDataContext(request.getDataContext());
                rd.setField("Name", myUser.getRegistrationDomain());

                if (!rd.find()) {
                    throw new ControllerException("Registration domain \"" +
                            myUser.getRegistrationDomain() +
                            "\" has not been defined");
                }
                if (rd.getField("EmailValidate").equals("Y")) {
                    emailValidate = true;
                }

                /* HACK: Even though registration doesn't require */
                /* email validate, passwords *always* do */
                emailValidate = true;

                ServletControllerRequest sparams = (ServletControllerRequest) request;
                HttpServletRequest hreq = (HttpServletRequest) sparams.getServletRequest();

                if (emailValidate) {
                    String emailAuthCode = myUser.getEmailAuthCode();
                    myUser.setEmailValCode(emailAuthCode);
                    myUser.update();

                    try {
                        ValidationEntry ve = new ValidationEntry(request.getDataContext());
                        ve.setValidationHandler("com.jcorporate.expresso.services.validation.ChangePasswordValidator");
                        ve.setTitle("Change Password Validation");
                        ve.setDesc("user=" + loginName + ", db=" +
                                request.getDataContext());
                        ve.setServer(hreq.getServerName());
                        ve.setPort(Integer.toString(hreq.getServerPort()));
                        ve.setContextPath(hreq.getContextPath());
                        ve.addParam("db", request.getDataContext());
                        ve.addParam("UserName", loginName);
                        ve.addParam("LoginController", this.getClass().getName());
                        ve.submit();
                    } catch (AuthValidationException avex) {
                        throw new ControllerException("Validation framework problem",
                                avex);
                    }

                    Output successMessage = new Output("successMessage",
                            "Email was sent to \"" +
                            email +
                            "\" to verify password change request");
                    response.addOutput(successMessage);
                } else {
                    String password = myUser.randomPassword();
                    myUser.setPassword(password);
                    myUser.update();

                    FastStringBuffer msg = FastStringBuffer.getInstance();
                    msg.append(response.getString("passwdReset",
                            myUser.getLoginName(),
                            password,
                            Setup.getValue(request.getDataContext(),
                                    "CompanyName"),
                            Setup.getValue(request.getDataContext(),
                                    "HomePageURL")));
                    myUser.notify(response.getString("passwdResetSubject"),
                            msg.toString());
                    msg.release();
                    Output successMessage = new Output("successMessage",
                            "Password for \"" +
                            email +
                            "\" was reset and an email sent");
                    response.addOutput(successMessage);
                }
            }
        } catch (Exception dbe) {
            throw new ControllerException(dbe);
        } finally {
            if (errors.getErrorCount() < 1) {
                response.clearFormCache();
            } else {
                response.saveErrors(errors);
                response.setFormCache();
                transition("promptSendPassword", request, response);
                return;
            }
        }
    }

    /**
     * Displays the 'change password' page.
     *
     * @param request  The framework controller request
     * @param response The framework ControllerResponse object
     * @throws ControllerException upon logic error
     */
    protected void runPromptChangePasswordState(ControllerRequest request,
                                                ControllerResponse response)
            throws ControllerException {
        response.clearFormCache();

        Input oldPassword = new Input();
        oldPassword.setName("oldPassword");
        oldPassword.setLabel(response.getString("CurrentPassword"));

        String opw = StringUtil.notNull(response.getFormCache("oldPassword"));
        oldPassword.setDefaultValue(opw);
        oldPassword.setDisplayLength(15);
        oldPassword.setMaxLength(30);
        oldPassword.setType("password");
        response.addInput(oldPassword);

        Input password = new Input();
        password.setName("Password");
        password.setLabel(response.getString("NewPassword"));

        String pw = StringUtil.notNull(response.getFormCache("Password"));
        password.setDefaultValue(pw);
        password.setDisplayLength(15);
        password.setMaxLength(30);
        password.setType("password");
        response.addInput(password);

        Input password_verify = new Input();
        password_verify.setName("password_verify");
        password_verify.setLabel(response.getString("RetypePassword"));

        String pwv = StringUtil.notNull(response.getFormCache("password_verify"));
        password_verify.setDefaultValue(pwv);
        password_verify.setDisplayLength(15);
        password_verify.setMaxLength(30);
        password_verify.setType("password");
        response.addInput(password_verify);

        //Transition change = new Transition(response.getString("changePasswordTitle"), this);
        Transition change = new Transition("processChangePassword", this);
        change.setLabel(response.getString("changePasswordTitle"));
        response.add(change);
        response.addTransition(new Transition("promptChangePassword", this));
        response.addTransition(new Transition("promptLogin", this));
        response.addTransition(new Transition("processLogout", this));

        Transition editPref = new Transition();
        editPref.setName("editPreferences");
        editPref.addParam(Controller.CONTROLLER_PARAM_KEY,
                "com.jcorporate.expresso.services.controller.EditUserPreference");
        editPref.addParam(STATE_PARAM_KEY, "edit");
        response.add(editPref);

        Transition showDBMenu = new Transition();
        showDBMenu.setName("showDBMenu");
        showDBMenu.addParam(Controller.CONTROLLER_PARAM_KEY,
                this.getDefaultRegistrationController().getClass().getName());
        showDBMenu.addParam(STATE_PARAM_KEY, "showDBMenu");
        response.add(showDBMenu);
    }

    /**
     * Prompts the user for login.
     *
     * @param request  The ControllerRequest object
     * @param response The ControllerResponse object
     */
    protected void runPromptLoginState(ControllerRequest request,
                                       ControllerResponse response)
            throws ControllerException {
        PersistentSession session = request.getSession();
        Input dbContext = new Input("dbContext");
        String useDB = StringUtil.notNull(request.getParameter("dbContext"));

        if (!useDB.equals("")) {
            request.setDataContext(useDB);
            response.addOutput(new Output("dbContext", useDB));
        } else {
            dbContext.setDefaultValue(request.getDataContext());
            dbContext.setLabel(response.getString("Context/Database_"));

            String oneConfigKey = null;
            String oneDescrip = null;
            Vector v = new Vector();

            for (Enumeration ie = ConfigManager.getAllConfigKeys();
                 ie.hasMoreElements();) {
                oneConfigKey = (String) ie.nextElement();
                oneDescrip = "";

                try {
                    oneDescrip = StringUtil.notNull(ConfigManager.getContext(oneConfigKey).getDescription());

                    if (oneDescrip.equals("")) {
                        oneDescrip = oneConfigKey;
                    }
                    /* If it's not an expresso context, you can't log in to it */
                    if (ConfigManager.getContext(oneConfigKey).hasSetupTables()) {
                        v.addElement(new ValidValue(oneConfigKey, oneDescrip));
                    }
                } catch (ConfigurationException ce) {
                    throw new ControllerException(ce);
                }
            }

            dbContext.setValidValues(v);
            response.addInput(dbContext);
        }

        // Fill in the Login field with values in following priority: form-cache, cookie
        Input loginName = new Input();
        loginName.setName("LoginName");

        String ln = StringUtil.notNull(response.getFormCache("LoginName"));

        if (ln.equals("")) {
            ln = request.getUser();
        }
        if (ln.equals(User.UNKNOWN_USER)) {
            ln = "";
        }

        loginName.setDefaultValue(ln);
        loginName.setDisplayLength(15);
        loginName.setMaxLength(30);
        loginName.setLabel("Login");
        response.addInput(loginName);

        // Fill in the Password field with values in following priority: form-cache, cookie
        Input password = new Input();
        password.setName("Password");
        password.setLabel("Password");

        String pw = StringUtil.notNull(response.getFormCache("Password"));

        if ("".equals(pw)) {
            pw = StringUtil.notNull(session.getClientAttribute("Password"));
        }

        if ("NONE".equals(pw)) {
            pw = "";
        }

        password.setDefaultValue(pw);
        password.setDisplayLength(15);
        password.setMaxLength(30);
        password.setType("password");
        response.addInput(password);

        // Fill in the Remember field
        Input remember = new Input("Remember");
        remember.setLabel("Remember Login");

        String rm = response.getFormCache("Remember");

        if (rm == null || rm.length() == 0) {
            rm = "Y";
        }

        remember.setType("checkbox");
        remember.setDefaultValue(rm);
        response.addInput(remember);

        //
        //Put a hidden element on the form to pass the next parameter
        //to process
        //
        String oneParam = StringUtil.notNull(request.getParameter("next"));

        if (oneParam.length() > 0) {
            Input nextURL = new Input("next");
            nextURL.setType("hidden");
            nextURL.setDefaultValue(oneParam);
            response.addInput(nextURL);
        }

        oneParam = StringUtil.notNull(request.getParameter("immediate"));

        if (oneParam.length() > 0) {
            Input nextURL = new Input("immediate");
            nextURL.setType("hidden");
            nextURL.setDefaultValue(oneParam);
            response.addInput(nextURL);
        }

        Transition login = new Transition("processLogin", this);

        if (!useDB.equals("")) {
            login.addParam("dbContext", useDB);
        }

        response.add(login);

        Transition promptChangePassword = new Transition("promptChangePassword", this);

        if (!useDB.equals("")) {
            promptChangePassword.addParam("dbContext", useDB);
        }

        response.add(promptChangePassword);
        response.add(new Transition("processLogout", this));

        Transition promptSendPassword = new Transition("promptSendPassword",
                this);

        if (!useDB.equals("")) {
            promptSendPassword.addParam("dbContext", useDB);
        }

        response.add(promptSendPassword);
        String registerController = this.getDefaultRegistrationController().getClass().getName();


        if (registerController != null) {
            Transition promptRegister = new Transition();
            promptRegister.setControllerObject(registerController);
            promptRegister.setState("promptSelfRegister");
            promptRegister.setName("promptRegister");

            if (!useDB.equals("")) {
                promptRegister.addParam("dbContext", useDB);
            } else {
                promptRegister.addParam("dbContext", "default");
            }

            response.add(promptRegister);
        }

        Transition promptLogin = new Transition("promptLogin", this);

        if (!useDB.equals("")) {
            promptLogin.addParam("dbContext", useDB);
        }

        response.add(promptLogin);

        Transition showDBMenu = new Transition();
        showDBMenu.setName("showDBMenu");
        showDBMenu.addParam(Controller.CONTROLLER_PARAM_KEY,
                this.getDefaultRegistrationController().getClass().getName());
        showDBMenu.addParam(STATE_PARAM_KEY, "showDBMenu");
        response.add(showDBMenu);

        Transition editPref = new Transition();
        editPref.setName("editPreferences");
        editPref.addParam(Controller.CONTROLLER_PARAM_KEY,
                "com.jcorporate.expresso.services.controller.EditUserPreference");
        editPref.addParam(STATE_PARAM_KEY, "edit");
        response.add(editPref);

        //
        //Add a revalidate email link to the login screen if the default
        //registration domain sends validation emails.
        //
        try {
            String regDomain = Setup.getValue(request.getDataContext(), "defaultRegDomain");
            if (regDomain != null && regDomain.length() > 0) {
                RegistrationDomain rd = new RegistrationDomain(Securable.SYSTEM_ACCOUNT);
                rd.setDataContext(request.getDataContext());
                rd.setField("Name", regDomain);
                if (rd.find()) {
                    String emailValidate = rd.getField("EmailValidate");
                    if (StringUtil.toBoolean(emailValidate)) {
                        Transition revalidate = new Transition("promptRevalidate", this);
                        revalidate.setLabel("Resend Email Validation");
                        response.add(revalidate);
                    }
                }
            }
        } catch (DBException ex) {
            log.error("Error getting default regdomain setup parameter", ex);
        }
    }

    /**
     * This function prompts for email revalidation
     *
     * @param request  The <code>ControllerRequest</code> object handed to us
     *                 by the framework.
     * @param response The <code>ControllerResponse</code> object handed to us
     *                 by the framework
     * @throws ControllerException upon error
     */
    protected void runPromptRevalidateState(ControllerRequest request,
                                            ControllerResponse response) throws ControllerException {
        response.setTitle("Enter Email For Revalidation Request");

        response.addOutput(new Output("If there was a transient error in the email delivery" +
                " system, you can request a resend of your email validation request."));

        Input i = new Input("Email", "Email Address");
        response.add(i);

        Transition t = new Transition("processRevalidate", this);
        t.setLabel("Resend Validation Email");
        response.add(t);
    }

    /**
     * This function processes the revalidation email request, attempts to
     * find the user, and if successfull, forwards the control over to the
     * RegistrationController to do the actual resending of the validation
     * email.
     *
     * @param request  The <code>ControllerRequest</code> object handed to us
     *                 by the framework.
     * @param response The <code>ControllerResponse</code> object handed to us
     *                 by the framework
     * @throws ControllerException    upon error
     * @throws NonHandleableException upon fatal error
     */
    protected void runProcessRevalidateState(ControllerRequest request,
                                             ControllerResponse response)
            throws ControllerException, NonHandleableException {
        response.setTitle("Revalidation Processing");
        ErrorCollection ec = request.getErrorCollection();
        if (ec == null) {
            ec = new ErrorCollection();
        }

        if (ec.getErrorCount() > 0) {
            response.setFormCache();
            response.saveErrors(ec);
            transition("promptRevalidate", request, response);
            return;
        }

        try {
            User u = new User();
            u.setDBName(request.getDataContext());
            u.setEmail(request.getParameter("Email"));
            if (!u.find()) {
                log.error("Received request for email address: "
                        + request.getParameter("Email") +
                        "but user does not exist");

                ec.addError("You entered an invalid email address");
            } else if (!"I".equals(u.getAccountStatus())) {
                ec.addError("This account is not waiting for email address confirmation");
            }

            if (ec.getErrorCount() > 0) {
                response.setFormCache();
                response.saveErrors(ec);
                transition("promptRevalidate", request, response);
            } else {
                Transition reValidate = new Transition("revalidate",
                        "Click Here To Resend Email Validation",
                        this.getDefaultRegistrationController().getClass(), "processRevalidate");

                reValidate.addParam("Email", u.getEmail());
                reValidate.addParam("db", request.getDataContext());
                reValidate.addParam("loginController", this.getClass().getName());
                reValidate.transition(request, response, false);
            }


        } catch (DBException ex) {
            log.error("Error processing email revalidation", ex);
            throw new ControllerException("Error processing email revalidation." +
                    "  The Administrator has been notified");
        }

    }


    protected void runPromptSendPasswordState(ControllerRequest request,
                                              ControllerResponse response)
            throws ControllerException {
        String dbContext = StringUtil.notNull(request.getParameter("dbContext"));

        if (!dbContext.equals("")) {
            request.setDataContext(dbContext);
        }

        Input email = new Input();
        email.setName("Email");
        email.setLabel("EMail");

        String emailValue = StringUtil.notNull(response.getFormCache("Email"));
        email.setDefaultValue(emailValue);
        email.setDisplayLength(45);
        email.setMaxLength(60);
        response.addInput(email);

        Transition submit = new Transition("processSendPassword", this);
        submit.setLabel(response.getString("passwdResetSubject"));
        submit.addParam("dbContext", request.getDataContext());
        response.add(submit);

        Transition pr = new Transition("promptSelfRegister", this.getDefaultRegistrationController());
        pr.addParam("dbContext", request.getDataContext());
        response.add(pr);

        Transition pl = new Transition("promptLogin", this);
        pl.addParam("dbContext", request.getDataContext());
        response.add(pl);
    }

    /**
     * Override the normal stateAllowed method to always allow
     * access to this controller for certain states - otherwise no-one can ever log in :-)
     *
     * @param newState the state to transition to.
     * @param params   The controllerRequest object
     * @return true if the state is allowed for the currently logged in user.
     * @throws ControllerException if there is an error while looking up the sercurity permissions
     */
    public synchronized boolean stateAllowed(String newState,
                                             ControllerRequest params)
            throws ControllerException {
        if (newState.equals("promptChangePW") ||
                newState.equals("processChangePW") ||
                newState.equals("promptLogout")) {
            return super.stateAllowed(newState, params);
        }

        return true;
    } /* stateAllowed(String) */


}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.