com.madalla.webapp.components.member.LoginPanel.java Source code

Java tutorial

Introduction

Here is the source code for com.madalla.webapp.components.member.LoginPanel.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 com.madalla.webapp.components.member;

import org.apache.commons.lang.StringUtils;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Page;
import org.apache.wicket.RestartResponseAtInterceptPageException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponentLabel;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.madalla.util.security.ICredentialHolder;
import com.madalla.webapp.CmsPanel;
import com.madalla.webapp.css.Css;
import com.madalla.wicket.form.FocusOnLoadBehavior;

/**
 * Reusable user sign in panel with username and password as well as support for cookie persistence
 * of the both. When the SignInPanel's form is submitted, the method signIn(String, String) is
 * called, passing the username and password submitted. The signIn() method should authenticate the
 * user's session. The default implementation calls AuthenticatedWebSession.get().signIn().
 *
 * @author Jonathan Locke
 * @author Juergen Donnerstag
 * @author Eelco Hillenius
 */
public abstract class LoginPanel extends CmsPanel {
    private static final long serialVersionUID = 1L;
    private static final Logger log = LoggerFactory.getLogger(LoginPanel.class);

    /** True if the panel should display a remember-me checkbox */
    private boolean includeRememberMe = true;

    private final Class<? extends Page> destination;

    /** Field for password. */
    private PasswordTextField password;
    private FormComponentLabel passwordLabel;

    /** True if the user should be remembered via form persistence (cookies) */
    private boolean rememberMe = true;

    /** Field for user name. */
    private TextField<String> username;
    private FormComponentLabel usernameLabel;

    private AjaxLink<String> unlockUser;
    private Label lockedLabel;

    /**
     * Sign in form.
     */
    public final class SignInForm extends Form<Object> {
        private static final long serialVersionUID = 1L;

        /**
         * Constructor.
         *
         * @param id
         *            id of the form component
         */
        public SignInForm(final String id, ICredentialHolder credentials) {
            super(id);
            // Attach textfield components that edit properties map
            // in lieu of a formal beans model
            add(username = new TextField<String>("username", new PropertyModel<String>(credentials, "username")));
            username.setRequired(true);
            add(password = new PasswordTextField("password", new PropertyModel<String>(credentials, "password")));

            add(usernameLabel = new FormComponentLabel("usernameLabel", username));
            usernameLabel.setOutputMarkupId(true);

            add(passwordLabel = new FormComponentLabel("passwordLabel", password));
            passwordLabel.setVisibilityAllowed(true);
            passwordLabel.setOutputMarkupId(true);

            password.setRequired(false);
            password.setOutputMarkupId(true);
            password.setVisibilityAllowed(true);

            // MarkupContainer row for remember me checkbox
            final WebMarkupContainer rememberMeRow = new WebMarkupContainer("rememberMeRow");
            rememberMeRow.setOutputMarkupId(true);
            add(rememberMeRow);

            // Add rememberMe checkbox
            rememberMeRow
                    .add(new CheckBox("rememberMe", new PropertyModel<Boolean>(LoginPanel.this, "rememberMe")));

            // Show remember me checkbox?
            rememberMeRow.setVisible(includeRememberMe);

            //add(new SubmitLink("submitLink"));
        }

        /**
         * @see org.apache.wicket.markup.html.form.Form#onSubmit()
         */
        @Override
        public void onSubmit() {
            log.debug("Login with userName=" + getUsername());
            //continue to Ajax submit

        }
    }

    public LoginPanel(final String id, ICredentialHolder credentials) {
        this(id, credentials, true);
    }

    public LoginPanel(final String id, final ICredentialHolder credentials, final boolean includeRememberMe) {
        this(id, credentials, includeRememberMe, null);
    }

    /**
     * @param id
     *            See Component constructor
     * @param includeRememberMe
     *            True if form should include a remember-me checkbox
     * @see org.apache.wicket.Component#Component(String)
     */
    public LoginPanel(final String id, final ICredentialHolder credentials, final boolean includeRememberMe,
            Class<? extends Page> destination) {
        super(id);

        if (destination == null) {
            this.destination = getApplication().getHomePage();
        } else {
            this.destination = destination;
        }

        //if we have a valid populated credential then validate
        if (StringUtils.isNotEmpty(credentials.getUsername()) && StringUtils.isNotEmpty(credentials.getPassword())
                && signIn(credentials.getUsername(), credentials.getPassword())) {

            throw new RestartResponseAtInterceptPageException(destination);

        }

        this.includeRememberMe = includeRememberMe;

        final Form<Object> form = new SignInForm("signInForm", credentials);

        add(form);

        final FeedbackPanel feedback = new FeedbackPanel("loginFeedback");
        feedback.setOutputMarkupId(true);
        form.add(feedback);

        lockedLabel = new Label("lockedLabel",
                new StringResourceModel("label.locked", this, new Model<ICredentialHolder>(credentials)));
        lockedLabel.setVisibilityAllowed(true);
        lockedLabel.setVisible(false);
        form.add(lockedLabel);

        unlockUser = new AjaxLink<String>("unlockUser") {
            private static final long serialVersionUID = 1L;

            @Override
            public void onClick(AjaxRequestTarget target) {
                target.add(form);
                lockUserName(false);
                credentials.setUsername("");
            }

        };
        unlockUser.setVisibilityAllowed(true);
        form.add(unlockUser);

        //set up depending on if we have a username or not
        lockUserName(StringUtils.isNotEmpty(credentials.getUsername()));

        AjaxButton submit = new IndicatingAjaxButton("submitLink", form) {

            private static final long serialVersionUID = 1L;

            @Override
            protected void onError(AjaxRequestTarget target, Form<?> form) {
                log.debug("Ajax onError called");
                target.add(feedback);
                onSignInFailed(getUsername());
            }

            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                log.debug("Ajax submit called");
                target.add(form);
                preSignIn(getUsername());

                if (!isUserLocked()) {
                    lockUserName(true);
                } else {
                    if (signIn(getUsername(), getPassword())) {
                        feedback.info(getLocalizer().getString("signInFailed", this, "Success"));
                        onSignInSucceeded(target);
                    } else {
                        feedback.error(getLocalizer().getString("signInFailed", this, "Sign in failed"));
                        target.add(feedback);
                        onSignInFailed(getUsername());
                    }

                }

            }

        };
        submit.setEnabled(true);

        //submit.setVisibilityAllowed(true);
        form.add(submit);
        form.add(new AttributeModifier("onSubmit", true, new Model<String>(
                "document.getElementById('" + submit.getMarkupId() + "').onclick();return false;")));

    }

    @Override
    public void renderHead(IHeaderResponse response) {
        response.render(CssHeaderItem.forReference(Css.CSS_FORM));
    }

    @Override
    protected void onBeforeRender() {
        super.onBeforeRender();
        username.setLabel(new Model<String>(getString("label.name")));
        password.setLabel(new Model<String>(getString("label.password")));
    }

    private void lockUserName(boolean lock) {
        username.setVisible(!lock);
        usernameLabel.setVisible(!lock);
        unlockUser.setVisible(lock);
        password.setVisible(lock);
        password.setRequired(lock);
        passwordLabel.setVisible(lock);
        lockedLabel.setVisible(lock);
        if (lock) {
            password.add(new FocusOnLoadBehavior());
        } else {
            username.add(new FocusOnLoadBehavior());
        }
    }

    private boolean isUserLocked() {
        return !username.isVisible();
    }

    /**
     * Convenience method to access the password.
     *
     * @return The password
     */
    public String getPassword() {
        return password.getDefaultModelObjectAsString();
    }

    /**
     * Get model object of the rememberMe checkbox
     *
     * @return True if user should be remembered in the future
     */
    public boolean getRememberMe() {
        return rememberMe;
    }

    /**
     * Convenience method to access the username.
     *
     * @return The user name
     */
    public String getUsername() {
        return username.getDefaultModelObjectAsString();
    }

    /**
     * Sign in user if possible.
     *
     * @param username
     *            The username
     * @param password
     *            The password
     * @return True if signin was successful
     */
    public abstract boolean signIn(String username, String password);

    protected void preSignIn(String username) {

    }

    protected void onSignInFailed(String username) {
        if (null == username) {
            log.warn("onSignInFailed - no user name.");
        } else {
            log.warn("onSignInFailed - user = " + username);
        }
    }

    protected void onSignInSucceeded() {
        // If login has been called because the user was not yet
        // logged in, then continue to the original destination,
        // otherwise to the Home page
        continueToOriginalDestination();
        setResponsePage(destination);
    }

    protected void onSignInSucceeded(AjaxRequestTarget target) {
        onSignInSucceeded();

    }

}