001    /*
002     * Databinder: a simple bridge from Wicket to Hibernate
003     * Copyright (C) 2006  Nathan Hamblen nathan@technically.us
004     *
005     * This library is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU Lesser General Public
007     * License as published by the Free Software Foundation; either
008     * version 2.1 of the License, or (at your option) any later version.
009     * 
010     * This library is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013     * Lesser General Public License for more details.
014     * 
015     * You should have received a copy of the GNU Lesser General Public
016     * License along with this library; if not, write to the Free Software
017     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
018     */
019    package net.databinder.auth.components;
020    
021    import net.databinder.auth.AuthSession;
022    import net.databinder.auth.AuthApplication;
023    import net.databinder.auth.data.DataUser;
024    import net.databinder.components.DataStyleLink;
025    import net.databinder.components.SourceList;
026    
027    import org.apache.wicket.Application;
028    import org.apache.wicket.Component;
029    import org.apache.wicket.IClusterable;
030    import org.apache.wicket.Page;
031    import org.apache.wicket.PageParameters;
032    import org.apache.wicket.Session;
033    import org.apache.wicket.authorization.UnauthorizedInstantiationException;
034    import org.apache.wicket.markup.html.WebMarkupContainer;
035    import org.apache.wicket.markup.html.WebPage;
036    import org.apache.wicket.markup.html.basic.Label;
037    import org.apache.wicket.model.ResourceModel;
038    
039    /**
040     * Sign in and registration page.
041     * Replaceable String resources: <pre>
042     * data.auth.title.sign_in
043     * data.auth.pre_register_link
044     * data.auth.register_link
045     * data.auth.pre_sign_in_link
046     * data.auth.sign_in_link
047     * or a subclass of this panel.
048     */
049    public abstract class DataSignInPageBase extends WebPage {
050            private SourceList sourceList;
051            
052            private Component profileSocket, signinSocket;
053            
054            private SourceList.SourceLink profileLink, signinLink;
055            
056            public interface ReturnPage extends IClusterable {
057                    Page get();
058            }
059            
060            /** Displays sign in page. */
061            public DataSignInPageBase(PageParameters params) {
062                    this(params, null);
063            }
064            
065            public DataSignInPageBase(ReturnPage returnPage) {
066                    this(null, returnPage);
067            }
068            
069            public DataSignInPageBase(PageParameters params, ReturnPage returnPage) {
070                    AuthApplication app = null;
071                    try { app = ((AuthApplication)Application.get()); } catch (ClassCastException e) { }
072                    // make sure the user is not trying to sign in or register with the wrong page
073                    if (app == null || !app.getSignInPageClass().isInstance(this))
074                            throw new UnauthorizedInstantiationException(DataSignInPageBase.class);
075    
076                    if (params != null) {
077                            String username = params.getString("username");
078                            String token = params.getString("token");
079                            // e-mail auth, for example
080                            if (username != null && token != null) {
081                                    DataUser user = (DataUser) app.getUser(username);
082                                    
083                                    if (user != null && app.getToken(user).equals(token))
084                                            getAuthSession().signIn(user, true);
085                                    setResponsePage(((Application)app).getHomePage());
086                                    setRedirect(true);
087                                    return;
088                            }
089                    }
090                    
091                    add(new Label("title", new ResourceModel("data.auth.title.sign_in", "Please sign in")));
092    
093                    add(new DataStyleLink("dataStylesheet"));
094                    
095                    sourceList = new SourceList();
096                    
097                    add(profileSocket = profileSocket("profileSocket", returnPage));
098                    add(new WebMarkupContainer("profileLinkWrapper") {
099                            public boolean isVisible() {
100                                    return profileLink.isEnabled();
101                            }
102                    }.add(profileLink = sourceList.new SourceLink("profileLink", profileSocket)));
103                    
104                    add(signinSocket = signinSocket("signinSocket", returnPage));
105                    add(new WebMarkupContainer("signinLinkWrapper") {
106                            @Override
107                            public boolean isVisible() {
108                                    return signinLink.isEnabled();
109                            }
110                    }.add(signinLink = sourceList.new SourceLink("signinLink", signinSocket)));
111                    signinLink.onClick();   // show sign in first
112            }
113            
114            /**
115             * Default returns DataSignInPanel.
116             * @return component (usually panel) to display for sign in
117             * @see DataSignInPanel
118             */
119            protected Component signinSocket(String id, ReturnPage returnPage) {
120                    return new DataSignInPanel(id, returnPage);
121            }
122    
123            /** @return new component to display for profile / registration */
124            protected abstract Component profileSocket(String id, ReturnPage returnPage);
125            
126            /** @return casted session */
127            protected static  AuthSession getAuthSession() {
128                    return (AuthSession) Session.get();
129            }
130    }