org.tsm.concharto.web.login.LoginController.java Source code

Java tutorial

Introduction

Here is the source code for org.tsm.concharto.web.login.LoginController.java

Source

/*******************************************************************************
 * Copyright 2009 Time Space Map, LLC
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package org.tsm.concharto.web.login;

import java.util.Map;

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

import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.propertyeditors.CustomBooleanEditor;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.util.WebUtils;
import org.tsm.concharto.auth.AuthHelper;
import org.tsm.concharto.dao.UserDao;
import org.tsm.concharto.model.user.User;
import org.tsm.concharto.model.user.UserNote;
import org.tsm.concharto.util.PasswordUtil;
import org.tsm.concharto.web.signup.LoginSignupHelper;
import org.tsm.concharto.web.signup.SignupForm;
import org.tsm.concharto.web.util.SessionHelper;

/**
 * For authentication.  We aren't using the standard j2ee authentaction mechanisms because there
 * is zero control over the user experience and the user experience sucks.
 * 
 * @author frank
 *
 */
public class LoginController extends SimpleFormController {

    private static final Log log = LogFactory.getLog(LoginController.class);
    private UserDao userDao;
    private SessionHelper sessionHelper;

    public void setSessionHelper(SessionHelper sessionHelper) {
        this.sessionHelper = sessionHelper;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
        binder.registerCustomEditor(Boolean.class, new CustomBooleanEditor("true", "false", true));
        super.initBinder(request, binder);
    }

    @SuppressWarnings("unchecked")
    @Override
    protected Map referenceData(HttpServletRequest request, Object command, Errors errors) throws Exception {

        Cookie userCookie = WebUtils.getCookie(request, AuthHelper.COOKIE_REMEMBER_ME_USERNAME);
        if ((userCookie != null) && !StringUtils.isEmpty(userCookie.getValue())) {
            SignupForm signupForm = (SignupForm) command;
            signupForm.setUsername(userCookie.getValue());
            signupForm.setRememberMe(true);
        }
        return super.referenceData(request, command, errors);
    }

    @Override
    protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command,
            BindException errors) throws Exception {
        SignupForm signupForm = (SignupForm) command;
        User user = userDao.find(signupForm.getUsername());

        if ((user != null) && (PasswordUtil.isPasswordValid(signupForm.getPassword(), user.getPassword()))) {
            //matched username and password, ok to proceed
            log.info("user " + signupForm.getUsername() + " signed in");

            //first save the username and roles in the session            
            sessionHelper.setUserInSession(request, user);

            //if they checked "remember me" we set a cookie
            if (BooleanUtils.isTrue(signupForm.getRememberMe())) {
                setRemeberMeCookie(response, user, AuthHelper.COOKIE_REMEMBER_ME_MAX_AGE);
            } else {
                setRemeberMeCookie(response, user, 0);
            }

            //now go where we were originally heading
            return LoginSignupHelper.continueToRequestedUrl(request);
        } else {
            /* NOTE we are doing validation here instead of the validator so that we don't have to 
             * go to the database twice to get the user object.
             */
            //tell the user there was a problem and let the default form handle the rest
            errors.rejectValue("username", "invalidUserPasswd.authForm.username");
            return new ModelAndView(getFormView(), errors.getModel());
        }
    }

    /**
     * Remember me cookie allows the user to come back to the site without having to log in again.
     * It works for a predetermined amount of time (e.g. 20 days)
     * @param response servlet response
     * @param user user
     * @param maxAge max cookie age
     */
    private void setRemeberMeCookie(HttpServletResponse response, User user, int maxAge) {
        if ((null == user.getUserNote()) || (null == user.getUserNote().getRememberMeKey())) {
            String rememberMeKey = PasswordUtil
                    .encrypt(user.getUsername() + Long.toString(System.currentTimeMillis()));
            UserNote userNote = new UserNote();
            userNote.setRememberMeKey(rememberMeKey);
            user.setUserNote(userNote);
            userDao.save(user);
        }
        AuthHelper.setCookie(response, AuthHelper.COOKIE_REMEMBER_ME, maxAge,
                user.getUserNote().getRememberMeKey());
        AuthHelper.setCookie(response, AuthHelper.COOKIE_REMEMBER_ME_USERNAME, maxAge, user.getUsername());
    }

}