Add userbox with username (near logout link). Refactor session implementation. Now extensions should use WebConsoleSession to implement own login logic or extend JaasWebSession to provide logic related to specific JAAS relam

Signed-off-by: Lukasz Dywicki <luke@code-house.org>

git-svn-id: https://svn.apache.org/repos/asf/karaf/webconsole/trunk@1167178 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/internal/WebConsoleApplication.java b/core/src/main/java/org/apache/karaf/webconsole/core/internal/WebConsoleApplication.java
index a6baede..874cc8f 100644
--- a/core/src/main/java/org/apache/karaf/webconsole/core/internal/WebConsoleApplication.java
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/internal/WebConsoleApplication.java
@@ -18,7 +18,7 @@
 
 import org.apache.karaf.webconsole.core.dashboard.DashboardPage;
 import org.apache.karaf.webconsole.core.page.LoginPage;
-import org.apache.karaf.webconsole.core.security.JaasWebSession;
+import org.apache.karaf.webconsole.core.security.KarafJaasWebSession;
 import org.apache.wicket.authentication.AuthenticatedWebApplication;
 import org.apache.wicket.authentication.AuthenticatedWebSession;
 import org.apache.wicket.markup.html.WebPage;
@@ -61,7 +61,7 @@
 
     @Override
     protected Class<? extends AuthenticatedWebSession> getWebSessionClass() {
-        return JaasWebSession.class;
+        return KarafJaasWebSession.class;
     }
 
 }
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/page/SecuredPage.java b/core/src/main/java/org/apache/karaf/webconsole/core/page/SecuredPage.java
index dbb498f..497cb2f 100644
--- a/core/src/main/java/org/apache/karaf/webconsole/core/page/SecuredPage.java
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/page/SecuredPage.java
@@ -16,10 +16,12 @@
  */
 package org.apache.karaf.webconsole.core.page;
 
+import java.util.List;
+
 import org.apache.karaf.webconsole.core.BasePage;
 import org.apache.karaf.webconsole.core.navigation.ConsoleTabProvider;
 import org.apache.karaf.webconsole.core.navigation.markup.NavigationPanel;
-import org.apache.wicket.Session;
+import org.apache.karaf.webconsole.core.security.WebConsoleSession;
 import org.apache.wicket.authorization.strategies.role.annotations.AuthorizeInstantiation;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.link.Link;
@@ -27,8 +29,6 @@
 import org.apache.wicket.model.StringResourceModel;
 import org.ops4j.pax.wicket.api.PaxWicketBean;
 
-import java.util.List;
-
 /**
  * Page which requires admin role, in other words authorized user.
  */
@@ -46,10 +46,12 @@
             }
         }));
 
-        Link aLink = new Link<Void>("logoutLink") {
+        add(new Label("username", WebConsoleSession.get().getUsername()));
+
+        Link<Void> aLink = new Link<Void>("logoutLink") {
             @Override
             public void onClick() {
-                Session.get().invalidateNow();
+                WebConsoleSession.get().invalidateNow();
                 getRequestCycle().setRedirect(true);
                 setResponsePage(LoginPage.class);
             }
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/security/JaasWebSession.java b/core/src/main/java/org/apache/karaf/webconsole/core/security/JaasWebSession.java
index 04c9b62..ae09684 100644
--- a/core/src/main/java/org/apache/karaf/webconsole/core/security/JaasWebSession.java
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/security/JaasWebSession.java
@@ -16,47 +16,49 @@
  */
 package org.apache.karaf.webconsole.core.security;
 
-import java.io.IOException;
 import java.security.Principal;
 
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 
-import org.apache.karaf.jaas.modules.RolePrincipal;
 import org.apache.wicket.Request;
-import org.apache.wicket.authentication.AuthenticatedWebSession;
 import org.apache.wicket.authorization.strategies.role.Roles;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Authenticated web session which uses JAAS to authenticate user and obtain roles.
+ * Base class for JAAS based authentication sessions.
  */
-public class JaasWebSession extends AuthenticatedWebSession {
+public abstract class JaasWebSession extends WebConsoleSession {
 
-    private Logger logger = LoggerFactory.getLogger(JaasWebSession.class);
+    /**
+     * Logger.
+     */
+    protected Logger logger = LoggerFactory.getLogger(JaasWebSession.class);
 
-    public static final String APPLICATION_POLICY_NAME = "karaf";
+    /**
+     * Roles.
+     */
+    protected final Roles roles = new Roles();
 
-    private Roles roles = new Roles();
+    /**
+     * Name of current user;
+     */
+    private String username;
 
     public JaasWebSession(Request request) {
         super(request);
     }
 
-    public boolean authenticate(String username, String password) {
+    public final boolean authenticate(String username, String password) {
         boolean authenticated = false;
         LoginCallbackHandler handler = new LoginCallbackHandler(username, password);
 
         try {
-            LoginContext ctx = new LoginContext(APPLICATION_POLICY_NAME, handler);
+            LoginContext ctx = new LoginContext(getRealmName(), handler);
             ctx.login();
             authenticated = true;
+            this.username = username;
 
             for (Principal p : ctx.getSubject().getPrincipals()) {
                 if (isRole(p)) {
@@ -70,39 +72,30 @@
         return authenticated;
     }
 
-    protected boolean isRole(Principal p) {
-        return p instanceof RolePrincipal;
-    }
-
-    public Roles getRoles() {
+    @Override
+    public final Roles getRoles() {
         return roles;
     }
 
-    private class LoginCallbackHandler implements CallbackHandler {
-
-        private String username;
-
-        private String password;
-
-        public LoginCallbackHandler(String username, String password) {
-            this.username = username;
-            this.password = password;
-        }
-
-        public void handle(Callback[] callbacks) throws IOException,
-                UnsupportedCallbackException {
-            for (int i = 0; i < callbacks.length; i++) {
-                Callback callback = callbacks[i];
-                if (callback instanceof NameCallback) {
-                    ((NameCallback) callback).setName(username);
-                } else if (callback instanceof PasswordCallback) {
-                    PasswordCallback pwCallback = (PasswordCallback) callback;
-                    pwCallback.setPassword(password.toCharArray());
-                } else {
-                    throw new UnsupportedCallbackException(callbacks[i], "Callback type not supported");
-                }
-            }
-        }
+    @Override
+    public final String getUsername() {
+        return username;
     }
 
-}
+    /**
+     * Gets name of JAAS realm to use during authentication process.
+     */
+    protected abstract String getRealmName();
+
+    /**
+     * Verify if given JAAS principal assigned after authentication is role or
+     * not. The name of the principal will be added to list of roles assigned
+     * to this session.
+     * 
+     * @param principal Principal
+     * @return True if principal name should be used as role name.
+     */
+    protected abstract boolean isRole(Principal principal);
+
+
+}
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/security/KarafJaasWebSession.java b/core/src/main/java/org/apache/karaf/webconsole/core/security/KarafJaasWebSession.java
new file mode 100644
index 0000000..3063596
--- /dev/null
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/security/KarafJaasWebSession.java
@@ -0,0 +1,45 @@
+/*
+ * 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 org.apache.karaf.webconsole.core.security;
+
+import java.security.Principal;
+
+import org.apache.karaf.jaas.modules.RolePrincipal;
+import org.apache.wicket.Request;
+
+/**
+ * Authenticated web session which uses JAAS to authenticate user and obtain roles.
+ */
+public class KarafJaasWebSession extends JaasWebSession {
+
+    private static final String KARAF_REALM = "karaf";
+
+    public KarafJaasWebSession(Request request) {
+        super(request);
+    }
+
+    @Override
+    protected boolean isRole(Principal p) {
+        return p instanceof RolePrincipal;
+    }
+
+    @Override
+    protected String getRealmName() {
+        return KARAF_REALM;
+    }
+
+}
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/security/LoginCallbackHandler.java b/core/src/main/java/org/apache/karaf/webconsole/core/security/LoginCallbackHandler.java
new file mode 100644
index 0000000..3735b0d
--- /dev/null
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/security/LoginCallbackHandler.java
@@ -0,0 +1,54 @@
+/*
+ * 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 org.apache.karaf.webconsole.core.security;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+/**
+ * Login callback which sets username and password in callbacks.
+ */
+public class LoginCallbackHandler implements CallbackHandler {
+
+    private String username;
+
+    private String password;
+
+    public LoginCallbackHandler(String username, String password) {
+        this.username = username;
+        this.password = password;
+    }
+
+    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+        for (int i = 0; i < callbacks.length; i++) {
+            Callback callback = callbacks[i];
+            if (callback instanceof NameCallback) {
+                ((NameCallback) callback).setName(username);
+            } else if (callback instanceof PasswordCallback) {
+                PasswordCallback pwCallback = (PasswordCallback) callback;
+                pwCallback.setPassword(password.toCharArray());
+            } else {
+                throw new UnsupportedCallbackException(callbacks[i], "Callback type not supported");
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/karaf/webconsole/core/security/WebConsoleSession.java b/core/src/main/java/org/apache/karaf/webconsole/core/security/WebConsoleSession.java
new file mode 100644
index 0000000..548d69c
--- /dev/null
+++ b/core/src/main/java/org/apache/karaf/webconsole/core/security/WebConsoleSession.java
@@ -0,0 +1,36 @@
+/*
+ * 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 org.apache.karaf.webconsole.core.security;
+
+import org.apache.wicket.Request;
+import org.apache.wicket.authentication.AuthenticatedWebSession;
+
+/**
+ * Base class for web console session implementation.
+ */
+public abstract class WebConsoleSession extends AuthenticatedWebSession {
+
+    public WebConsoleSession(Request request) {
+        super(request);
+    }
+
+    public abstract String getUsername();
+
+    public static WebConsoleSession get() {
+        return (WebConsoleSession) AuthenticatedWebSession.get();
+    }
+}
diff --git a/core/src/main/resources/org/apache/karaf/webconsole/core/page/SecuredPage.html b/core/src/main/resources/org/apache/karaf/webconsole/core/page/SecuredPage.html
index f40d71f..f96c1fe 100644
--- a/core/src/main/resources/org/apache/karaf/webconsole/core/page/SecuredPage.html
+++ b/core/src/main/resources/org/apache/karaf/webconsole/core/page/SecuredPage.html
@@ -25,7 +25,12 @@
 <body>
 
     <wicket:extend>
-        <a href="#" wicket:id="logoutLink"><div wicket:id="logoutTranslatedLink"/></a>
+        <div id="userbox" class="grid_1 prefix_11 suffix_0">
+            <p>
+                Welcome <span wicket:id="username">admin</span>
+                <a href="#" wicket:id="logoutLink"><span wicket:id="logoutTranslatedLink"/></a>
+            </p>
+        </div>
 
         <div class="grid_12">
             <div wicket:id="navigationPanel">Navigation goes here</div>
diff --git a/core/src/main/resources/org/apache/karaf/webconsole/core/style.css b/core/src/main/resources/org/apache/karaf/webconsole/core/style.css
index 8742e3b..f1679fa 100644
--- a/core/src/main/resources/org/apache/karaf/webconsole/core/style.css
+++ b/core/src/main/resources/org/apache/karaf/webconsole/core/style.css
@@ -30,6 +30,14 @@
     width: 250px;
 }
 
+#userbox span {
+    font-weight: bold;
+}
+
+#usebox a span {
+    font-weight: normal;
+}
+
 #sidebar ul li, #languages ul li {
     list-style-type: none;
 }
diff --git a/core/src/test/java/org/apache/karaf/webconsole/core/WebConsoleTest.java b/core/src/test/java/org/apache/karaf/webconsole/core/WebConsoleTest.java
index 48e72bd..c31c556 100644
--- a/core/src/test/java/org/apache/karaf/webconsole/core/WebConsoleTest.java
+++ b/core/src/test/java/org/apache/karaf/webconsole/core/WebConsoleTest.java
@@ -5,7 +5,7 @@
 
 import org.apache.karaf.webconsole.core.brand.DefaultBrandProvider;
 import org.apache.karaf.webconsole.core.internal.WebConsoleApplication;
-import org.apache.karaf.webconsole.core.security.JaasWebSession;
+import org.apache.karaf.webconsole.core.security.KarafJaasWebSession;
 import org.apache.wicket.authentication.AuthenticatedWebSession;
 import org.apache.wicket.protocol.http.WebApplication;
 import org.junit.Before;
@@ -43,6 +43,6 @@
     }
 
     protected Class<? extends AuthenticatedWebSession> getWebSessionClass() {
-        return JaasWebSession.class;
+        return KarafJaasWebSession.class;
     }
 }
\ No newline at end of file
diff --git a/core/src/test/java/org/apache/karaf/webconsole/core/test/AlwaysAuthenticatedWebSession.java b/core/src/test/java/org/apache/karaf/webconsole/core/test/AlwaysAuthenticatedWebSession.java
index b645b66..9dc501a 100644
--- a/core/src/test/java/org/apache/karaf/webconsole/core/test/AlwaysAuthenticatedWebSession.java
+++ b/core/src/test/java/org/apache/karaf/webconsole/core/test/AlwaysAuthenticatedWebSession.java
@@ -16,15 +16,15 @@
  */
 package org.apache.karaf.webconsole.core.test;
 
+import org.apache.karaf.webconsole.core.security.WebConsoleSession;
 import org.apache.wicket.Request;
-import org.apache.wicket.authentication.AuthenticatedWebSession;
 import org.apache.wicket.authorization.strategies.role.Roles;
 
 /**
  * Dummy session which does not handle authentication, simply returns true for
  * all input values and only one role.
  */
-public class AlwaysAuthenticatedWebSession extends AuthenticatedWebSession {
+public class AlwaysAuthenticatedWebSession extends WebConsoleSession {
 
     private Roles roles;
 
@@ -39,6 +39,11 @@
     }
 
     @Override
+    public String getUsername() {
+        return "test";
+    }
+
+    @Override
     public Roles getRoles() {
         return roles;
     }