]> source.dussan.org Git - vaadin-framework.git/commitdiff
Prototype of LoginBox component.
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Thu, 28 Feb 2008 10:14:50 +0000 (10:14 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Thu, 28 Feb 2008 10:14:50 +0000 (10:14 +0000)
svn changeset:3938/svn branch:trunk

src/com/itmill/toolkit/tests/tickets/Ticket1362Login.java [new file with mode: 0644]

diff --git a/src/com/itmill/toolkit/tests/tickets/Ticket1362Login.java b/src/com/itmill/toolkit/tests/tickets/Ticket1362Login.java
new file mode 100644 (file)
index 0000000..9b99019
--- /dev/null
@@ -0,0 +1,272 @@
+package com.itmill.toolkit.tests.tickets;
+
+import java.io.ByteArrayInputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+
+import com.itmill.toolkit.Application;
+import com.itmill.toolkit.terminal.ApplicationResource;
+import com.itmill.toolkit.terminal.DownloadStream;
+import com.itmill.toolkit.terminal.ParameterHandler;
+import com.itmill.toolkit.terminal.URIHandler;
+import com.itmill.toolkit.ui.Button;
+import com.itmill.toolkit.ui.CustomComponent;
+import com.itmill.toolkit.ui.Embedded;
+import com.itmill.toolkit.ui.ExpandLayout;
+import com.itmill.toolkit.ui.Label;
+import com.itmill.toolkit.ui.Panel;
+import com.itmill.toolkit.ui.Window;
+import com.itmill.toolkit.ui.Button.ClickEvent;
+import com.itmill.toolkit.ui.Window.Notification;
+
+/**
+ * Proof of concept how to create a decent login screen that works with browsers
+ * PW managers. (Browsers don't autofill generated login forms)
+ * 
+ * TODO generalize js to work inside iframes (if toolkit is inside iframe)
+ * 
+ * TODO extract login form to a external template.
+ * 
+ * TODO theme
+ * 
+ * TODO refine docs, make LoginBox a standard toolkit component
+ * 
+ * TODO article
+ * 
+ */
+public class Ticket1362Login extends Application {
+
+    public class LoginBox extends CustomComponent {
+
+        Embedded iframe = new Embedded();
+
+        ApplicationResource loginPage = new ApplicationResource() {
+
+            private byte[] loginHTML = (""
+                    + "<html>"
+                    + "<head><script type='text/javascript'>"
+                    + "var setTarget = function() {document.getElementById('loginf').action = top.location;};"
+                    + "</script></head>"
+                    + "<body onload='setTarget();'>"
+                    + "Iframe generated by LoginBox. PW managers can autofill form. Form handled by LoginBox "
+                    + "that will fire LoginEvents. Will post into another iframe, from where the script "
+                    + "will find toolkit client that will be force synced. <form id='loginf' target='logintarget'>"
+                    + "Username : <input type='text' name='username'>"
+                    + "Password : <input type='password' name='password'>"
+                    + "<input type='submit' value='login'>" + "</form>"
+                    + "<iframe name='logintarget'></iframe>" + "</body>"
+                    + "</html>").getBytes();
+
+            public Application getApplication() {
+                return LoginBox.this.getApplication();
+            }
+
+            public int getBufferSize() {
+                return loginHTML.length;
+            }
+
+            public long getCacheTime() {
+                return 0;
+            }
+
+            public String getFilename() {
+                return "login.html";
+            }
+
+            public DownloadStream getStream() {
+                return new DownloadStream(new ByteArrayInputStream(loginHTML),
+                        getMIMEType(), getFilename());
+            }
+
+            public String getMIMEType() {
+                return "text/html";
+            }
+        };
+
+        private ParameterHandler paramHandler = new ParameterHandler() {
+
+            public void handleParameters(Map parameters) {
+                if (parameters.containsKey("username")) {
+                    getWindow().addURIHandler(uriHandler);
+
+                    HashMap params = new HashMap();
+                    // expecting single params
+                    for (Iterator it = parameters.keySet().iterator(); it
+                            .hasNext();) {
+                        String key = (String) it.next();
+                        String value = ((String[]) parameters.get(key))[0];
+                        params.put(key, value);
+                    }
+                    LoginEvent event = new LoginEvent(params);
+                    for (Iterator iterator = listeners.iterator(); iterator
+                            .hasNext();) {
+                        LoginListener listener = (LoginListener) iterator
+                                .next();
+                        listener.onLogin(event);
+                    }
+                }
+            }
+        };
+
+        private URIHandler uriHandler = new URIHandler() {
+            public DownloadStream handleURI(URL context, String relativeUri) {
+                if (window != null) {
+                    window.removeURIHandler(this);
+                }
+                return new DownloadStream(
+                        new ByteArrayInputStream(
+                                "<html><body>Login form handeled.<script type='text/javascript'>top.itmill.forceSync();</script></body></html>"
+                                        .getBytes()), "text/html",
+                        "loginSuccesfull.html");
+            }
+        };
+
+        private LinkedList listeners = new LinkedList();
+
+        private Window window;
+
+        LoginBox() {
+            iframe.setType(Embedded.TYPE_BROWSER);
+            iframe.setSizeFull();
+            setCompositionRoot(iframe);
+        }
+
+        public void attach() {
+            super.attach();
+            getApplication().addResource(loginPage);
+            getWindow().addParameterHandler(paramHandler);
+            iframe.setSource(loginPage);
+        }
+
+        public void detach() {
+            getApplication().removeResource(loginPage);
+            getWindow().removeParameterHandler(paramHandler);
+            // store window temporary to properly remove uri handler once
+            // response is handled. (May happen if login handler removes login
+            // box
+            window = getWindow();
+            super.detach();
+        }
+
+        /**
+         * This event is sent when login form is submitted.
+         */
+        public class LoginEvent {
+
+            private Map params;
+
+            private LoginEvent(Map params) {
+                this.params = params;
+            }
+
+            /**
+             * Returns form value by field name.
+             * 
+             * @param name
+             * @return value in given field
+             */
+            public String getLoginParameter(String name) {
+                if (params.containsKey(name)) {
+                    return (String) params.get(name);
+                } else {
+                    return null;
+                }
+            }
+        }
+
+        /**
+         * Adds LoginListener to handle login logic
+         * 
+         * @param listener
+         */
+        public void addLoginListener(LoginListener listener) {
+            listeners.add(listener);
+        }
+
+        /**
+         * Removes LoginListener
+         * 
+         * @param listener
+         */
+        public void removeLoginListener(LoginListener listener) {
+            listeners.remove(listener);
+        }
+
+    }
+
+    /**
+     * Login listener is a class capable to listen LoginEvents sent from
+     * LoginBox
+     */
+    public interface LoginListener {
+        /**
+         * This method is fired on each login form post.
+         * 
+         * @param event
+         */
+        public void onLogin(LoginBox.LoginEvent event);
+    }
+
+    final static String GUEST = "guest";
+
+    LoginBox loginBox = new LoginBox();
+
+    Label currentUser = new Label(GUEST);
+
+    private Panel mainPanel;
+
+    private ExpandLayout el;
+
+    public void init() {
+
+        final Window mainWin = new Window(
+                "Test app with password manager savvy login functionality");
+
+        el = new ExpandLayout();
+
+        currentUser.setCaption("Currennt user");
+        el.addComponent(currentUser);
+
+        el.addComponent(loginBox);
+        el.expand(loginBox);
+
+        mainWin.setLayout(el);
+
+        setMainWindow(mainWin);
+
+        mainPanel = new Panel("Test app");
+        mainPanel.setSizeFull();
+        mainPanel.addComponent(new Label("User is logged in"));
+        mainPanel.addComponent(new Button("Logout", new Button.ClickListener() {
+
+            public void buttonClick(ClickEvent event) {
+                Ticket1362Login.this.close();
+            }
+        }));
+
+        loginBox.addLoginListener(new LoginListener() {
+            public void onLogin(LoginBox.LoginEvent event) {
+                String pw = event.getLoginParameter("password");
+                String username = event.getLoginParameter("username");
+                if (pw.equals("1234")) {
+                    setUser(username);
+                    currentUser.setValue(username);
+                    currentUser.getWindow().showNotification(
+                            "Logged in user: " + username);
+                    getMainWindow().getLayout().replaceComponent(loginBox,
+                            mainPanel);
+                    el.expand(mainPanel);
+                } else {
+                    getMainWindow().showNotification(
+                            "Wrong password. Hint, try '1234' ",
+                            Notification.TYPE_WARNING_MESSAGE);
+                }
+            }
+        });
+
+    }
+
+}
\ No newline at end of file