From a7571bc1d831a83643d4fc5257a510a1bb53316b Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 29 Sep 2011 23:34:04 -0400
Subject: [PATCH] Split RepositoriesPage into 3 pages. Inline page header authentication.

---
 src/com/gitblit/wicket/pages/RepositoriesPage.java           |   66 ----
 src/com/gitblit/wicket/pages/StandardPage.java               |   40 +++
 src/com/gitblit/wicket/pages/StandardPage.html               |   32 ++
 src/com/gitblit/wicket/pages/ReviewProposalPage.java         |   11 
 src/com/gitblit/wicket/pages/SendProposalPage.java           |    4 
 src/com/gitblit/wicket/pages/RootPage.html                   |   36 ++
 src/com/gitblit/wicket/pages/EditUserPage.html               |    9 
 src/com/gitblit/wicket/GitBlitWebApp.properties              |    4 
 src/com/gitblit/wicket/pages/RootPage.java                   |  157 ++++++++++++
 src/com/gitblit/wicket/pages/RepositoriesPage.html           |   25 -
 src/com/gitblit/wicket/pages/ReviewProposalPage.html         |    5 
 resources/bootstrap.gb.css                                   |   38 +-
 src/com/gitblit/wicket/pages/EditRepositoryPage.html         |   18 
 src/com/gitblit/wicket/pages/FederationRegistrationPage.html |    5 
 resources/markdown.css                                       |    2 
 src/com/gitblit/wicket/pages/EditRepositoryPage.java         |    9 
 src/com/gitblit/wicket/AuthorizationStrategy.java            |    8 
 src/com/gitblit/wicket/pages/UsersPage.html                  |   11 
 src/com/gitblit/wicket/pages/EditUserPage.java               |    7 
 src/com/gitblit/wicket/pages/FederationRegistrationPage.java |    6 
 src/com/gitblit/wicket/pages/FederationPage.html             |   17 +
 /dev/null                                                    |  118 ---------
 src/com/gitblit/wicket/pages/FederationPage.java             |   51 +++
 src/com/gitblit/wicket/pages/BasePage.java                   |    6 
 src/com/gitblit/wicket/pages/SendProposalPage.html           |   14 
 src/com/gitblit/wicket/GitBlitWebApp.java                    |   10 
 src/com/gitblit/wicket/pages/UsersPage.java                  |   29 ++
 27 files changed, 439 insertions(+), 299 deletions(-)

diff --git a/resources/bootstrap.gb.css b/resources/bootstrap.gb.css
index 747f812..db91249 100644
--- a/resources/bootstrap.gb.css
+++ b/resources/bootstrap.gb.css
@@ -26,11 +26,11 @@
 }
 
 .page-header {	
-	margin-bottom: 5px;
+	margin-bottom: 5px;	
 }
 
 .page-header h2 small {
-	font-size: 90%;
+	font-size: 80%;
 	font-weight: bold;
 }
 
@@ -492,6 +492,20 @@
 	border-bottom: 1px solid #ccc;
 }
 
+table.palette { border:0; width: 0 !important; }
+table.palette td.header { 
+	font-weight: bold; 
+	background-color: #ffffff !important;
+	padding-top: 0px !important;
+	margin-bottom: 0 !imporant;	
+	border: 0 !important;
+	border-radius: 0 !important;
+	line-height: 1em;
+}
+table.palette td.pane {
+	padding: 0px;
+}
+
 table.gitnotes {		
 	border: 0;	
 }
@@ -644,19 +658,17 @@
 	border-color: #00cc33;
 }
 
-.feedbackPanelERROR {	
-	color: red;
-	list-style-image: url(bullet_error.png);
-	font-weight: bold;	
-	vertical-align: top;
-	padding:0;	
-	margin:0;	
+.feedbackPanelERROR, .feedbackPanelINFO {	
+	list-style: none;
 }
 
-.feedbackPanelINFO {
-/* 	position:relative;padding:7px 15px;margin-bottom:18px;color:#404040;background-color:#eedc94;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94));background-image:-moz-linear-gradient(top, #fceec1, #eedc94);background-image:-ms-linear-gradient(top, #fceec1, #eedc94);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94));background-image:-webkit-linear-gradient(top, #fceec1, #eedc94);background-image:-o-linear-gradient(top, #fceec1, #eedc94);background-image:linear-gradient(top, #fceec1, #eedc94);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#eedc94 #eedc94 #e4c652;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);border-width:1px;border-style:solid;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);} */
-	list-style: none;
-	background-color:#ddf4fb;border-color:#c6edf9;
+.feedbackPanelINFO span, .feedbackPanelERROR span {
+	position:relative;padding:7px 15px;margin-top:5px;margin-bottom:5px;color:#404040;background-color:#eedc94;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94));background-image:-moz-linear-gradient(top, #fceec1, #eedc94);background-image:-ms-linear-gradient(top, #fceec1, #eedc94);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94));background-image:-webkit-linear-gradient(top, #fceec1, #eedc94);background-image:-o-linear-gradient(top, #fceec1, #eedc94);background-image:linear-gradient(top, #fceec1, #eedc94);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#eedc94 #eedc94 #e4c652;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);border-width:1px;border-style:solid;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);
+}
+
+.feedbackPanelERROR span {
+	color: #ffffff;
+	background-color:#c43c35;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-ms-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(top, #ee5f5b, #c43c35);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#c43c35 #c43c35 #882a25;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
 }
 
 /* google-code-prettify line numbers */
diff --git a/resources/markdown.css b/resources/markdown.css
index 1623078..e0bfe38 100644
--- a/resources/markdown.css
+++ b/resources/markdown.css
@@ -23,14 +23,12 @@
 div.markdown h1 {    
     margin-top: 0.5em;
     margin-bottom: 0.5em;
-    padding-bottom: 0.5em;
     border-bottom: 2px solid #000080 !important;
 }
 
 div.markdown h2 {
     margin-top: 1em;
     margin-bottom: 0.5em;    
-    padding-bottom: 0.5em;
 	border-bottom: 2px solid #000080 !important;    
 }
 
diff --git a/src/com/gitblit/wicket/AuthorizationStrategy.java b/src/com/gitblit/wicket/AuthorizationStrategy.java
index b6b745b..19bee6d 100644
--- a/src/com/gitblit/wicket/AuthorizationStrategy.java
+++ b/src/com/gitblit/wicket/AuthorizationStrategy.java
@@ -24,7 +24,6 @@
 import com.gitblit.Keys;
 import com.gitblit.models.UserModel;
 import com.gitblit.wicket.pages.BasePage;
-import com.gitblit.wicket.pages.LoginPage;
 import com.gitblit.wicket.pages.RepositoriesPage;
 
 public class AuthorizationStrategy extends AbstractPageAuthorizationStrategy implements
@@ -73,12 +72,7 @@
 	@Override
 	public void onUnauthorizedInstantiation(Component component) {
 		if (component instanceof BasePage) {
-			GitBlitWebSession session = GitBlitWebSession.get();
-			if (!session.isLoggedIn()) {
-				throw new RestartResponseAtInterceptPageException(LoginPage.class);
-			} else {
-				throw new RestartResponseAtInterceptPageException(RepositoriesPage.class);
-			}
+			throw new RestartResponseAtInterceptPageException(RepositoriesPage.class);
 		}
 	}
 }
diff --git a/src/com/gitblit/wicket/GitBlitWebApp.java b/src/com/gitblit/wicket/GitBlitWebApp.java
index 8c41df0..3edcf6a 100644
--- a/src/com/gitblit/wicket/GitBlitWebApp.java
+++ b/src/com/gitblit/wicket/GitBlitWebApp.java
@@ -32,17 +32,15 @@
 import com.gitblit.wicket.pages.CommitDiffPage;
 import com.gitblit.wicket.pages.CommitPage;
 import com.gitblit.wicket.pages.DocsPage;
-import com.gitblit.wicket.pages.ReviewProposalPage;
 import com.gitblit.wicket.pages.FederationRegistrationPage;
 import com.gitblit.wicket.pages.HistoryPage;
 import com.gitblit.wicket.pages.LogPage;
-import com.gitblit.wicket.pages.LoginPage;
-import com.gitblit.wicket.pages.LogoutPage;
 import com.gitblit.wicket.pages.MarkdownPage;
 import com.gitblit.wicket.pages.MetricsPage;
 import com.gitblit.wicket.pages.PatchPage;
 import com.gitblit.wicket.pages.RawPage;
 import com.gitblit.wicket.pages.RepositoriesPage;
+import com.gitblit.wicket.pages.ReviewProposalPage;
 import com.gitblit.wicket.pages.SearchPage;
 import com.gitblit.wicket.pages.SummaryPage;
 import com.gitblit.wicket.pages.TagPage;
@@ -100,12 +98,6 @@
 		// federation urls
 		mount("/proposal", ReviewProposalPage.class, "t");
 		mount("/registration", FederationRegistrationPage.class, "u", "n");
-
-		// setup login/logout urls, if we are using authentication
-		if (useAuthentication) {
-			mount("/login", LoginPage.class);
-			mount("/logout", LogoutPage.class);
-		}
 	}
 
 	private void mount(String location, Class<? extends WebPage> clazz, String... parameters) {
diff --git a/src/com/gitblit/wicket/GitBlitWebApp.properties b/src/com/gitblit/wicket/GitBlitWebApp.properties
index f279612..9e76a03 100644
--- a/src/com/gitblit/wicket/GitBlitWebApp.properties
+++ b/src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -138,4 +138,6 @@
 gb.message = message
 gb.myUrlDescription = the publicly accessible url for your Gitblit instance
 gb.destinationUrl = send to
-gb.destinationUrlDescription = the url of the Gitblit instance to send your proposal
\ No newline at end of file
+gb.destinationUrlDescription = the url of the Gitblit instance to send your proposal
+gb.users = users
+gb.federation = federation
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/BasePage.java b/src/com/gitblit/wicket/pages/BasePage.java
index ebb4e89..0cb91d5 100644
--- a/src/com/gitblit/wicket/pages/BasePage.java
+++ b/src/com/gitblit/wicket/pages/BasePage.java
@@ -44,7 +44,6 @@
 import com.gitblit.Keys;
 import com.gitblit.models.UserModel;
 import com.gitblit.wicket.GitBlitWebSession;
-import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.panels.LinkPanel;
 
 public abstract class BasePage extends WebPage {
@@ -190,7 +189,7 @@
 		if (GitBlitWebSession.get().isLoggedIn()) {
 			error(message, true);
 		} else {
-			throw new RestartResponseAtInterceptPageException(LoginPage.class);
+			throw new RestartResponseAtInterceptPageException(RepositoriesPage.class);
 		}
 	}
 
@@ -216,8 +215,7 @@
 			} else {
 				// login
 				add(new Label("username").setVisible(false));
-				add(new LinkPanel("loginLink", null, markupProvider.getString("gb.login"),
-						LoginPage.class));
+				add(new Label("loginLink").setVisible(false));
 				add(new Label("separator").setVisible(false));
 				add(new Label("changePasswordLink").setVisible(false));
 			}
diff --git a/src/com/gitblit/wicket/pages/EditRepositoryPage.html b/src/com/gitblit/wicket/pages/EditRepositoryPage.html
index 4a9690b..f9a0f79 100644
--- a/src/com/gitblit/wicket/pages/EditRepositoryPage.html
+++ b/src/com/gitblit/wicket/pages/EditRepositoryPage.html
@@ -6,18 +6,13 @@
 
 <wicket:extend>
 <body onload="document.getElementById('name').focus();">
-	<!-- Push content down to preserve header image -->
-	<div style="padding-top:20px"></div>
-
-	<div style="text-align:center;" wicket:id="feedback">[Feedback Panel]</div>	
-
 	<!-- Repository Table -->
 	<form wicket:id="editForm">
 		<table class="plain">
 			<tbody>
-				<tr><th><wicket:message key="gb.name"></wicket:message></th><td class="edit"><input type="text" wicket:id="name" id="name" size="40" tabindex="1" /> &nbsp;<i><wicket:message key="gb.nameDescription"></wicket:message></i></td></tr>
-				<tr><th><wicket:message key="gb.description"></wicket:message></th><td class="edit"><input type="text" wicket:id="description" size="40" tabindex="2" /></td></tr>
-				<tr><th><wicket:message key="gb.origin"></wicket:message></th><td class="edit"><input type="text" wicket:id="origin" size="80" tabindex="3" /></td></tr>
+				<tr><th><wicket:message key="gb.name"></wicket:message></th><td class="edit"><input class="span6" type="text" wicket:id="name" id="name" size="40" tabindex="1" /> &nbsp;<i><wicket:message key="gb.nameDescription"></wicket:message></i></td></tr>
+				<tr><th><wicket:message key="gb.description"></wicket:message></th><td class="edit"><input class="span6" type="text" wicket:id="description" size="40" tabindex="2" /></td></tr>
+				<tr><th><wicket:message key="gb.origin"></wicket:message></th><td class="edit"><input class="span6" type="text" wicket:id="origin" size="80" tabindex="3" /></td></tr>
 				<tr><th><wicket:message key="gb.owner"></wicket:message></th><td class="edit"><select wicket:id="owner" tabindex="4" /> &nbsp;<i><wicket:message key="gb.ownerDescription"></wicket:message></i></td></tr>
 				<tr><th><wicket:message key="gb.enableTickets"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="useTickets" tabindex="5" /> &nbsp;<i><wicket:message key="gb.useTicketsDescription"></wicket:message></i></td></tr>
 				<tr><th><wicket:message key="gb.enableDocs"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="useDocs" tabindex="6" /> &nbsp;<i><wicket:message key="gb.useDocsDescription"></wicket:message></i></td></tr>
@@ -25,16 +20,15 @@
 				<tr><th><wicket:message key="gb.showReadme"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="showReadme" tabindex="8" /> &nbsp;<i><wicket:message key="gb.showReadmeDescription"></wicket:message></i></td></tr>
 				<tr><th><wicket:message key="gb.isFrozen"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="isFrozen" tabindex="9" /> &nbsp;<i><wicket:message key="gb.isFrozenDescription"></wicket:message></i></td></tr>
 				<tr><td style="padding-top:10px;" colspan="2"><hr></hr></td></tr>
-				<tr><th><wicket:message key="gb.accessRestriction"></wicket:message></th><td class="edit"><select wicket:id="accessRestriction" tabindex="10" /></td></tr>				
+				<tr><th><wicket:message key="gb.accessRestriction"></wicket:message></th><td class="edit"><select class="span6" wicket:id="accessRestriction" tabindex="10" /></td></tr>				
 				<tr><th style="vertical-align: top;"><wicket:message key="gb.permittedUsers"></wicket:message></th><td style="padding:2px;"><span wicket:id="users"></span></td></tr>
 				<tr><td style="padding-top:10px;" colspan="2"><hr></hr></td></tr>				
-				<tr><th><wicket:message key="gb.federationStrategy"></wicket:message></th><td class="edit"><select wicket:id="federationStrategy" tabindex="11" /></td></tr>
+				<tr><th><wicket:message key="gb.federationStrategy"></wicket:message></th><td class="edit"><select class="span6" wicket:id="federationStrategy" tabindex="11" /></td></tr>
 				<tr><th style="vertical-align: top;"><wicket:message key="gb.federationSets"></wicket:message></th><td style="padding:2px;"><span wicket:id="federationSets"></span></td></tr>				
-				<tr><th></th><td class="editButton"><input class="btn primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="12" /> <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="13" /></td></tr>
+				<tr><th></th><td class="editButton"><input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="12" /> &nbsp; <input class="btn primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="13" /> </td></tr>
 			</tbody>
 		</table>
 	</form>	
-
 </body>
 </wicket:extend>
 </html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/EditRepositoryPage.java b/src/com/gitblit/wicket/pages/EditRepositoryPage.java
index 7349ca5..ae7966d 100644
--- a/src/com/gitblit/wicket/pages/EditRepositoryPage.java
+++ b/src/com/gitblit/wicket/pages/EditRepositoryPage.java
@@ -47,7 +47,7 @@
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.WicketUtils;
 
-public class EditRepositoryPage extends BasePage {
+public class EditRepositoryPage extends StandardPage {
 
 	private final boolean isCreate;
 
@@ -76,15 +76,16 @@
 		List<String> federationSets = new ArrayList<String>();
 		List<String> repositoryUsers = new ArrayList<String>();
 		if (isCreate) {
-			super.setupPage("", getString("gb.newRepository"));
+			super.setupPage(getString("gb.newRepository"), "");
 		} else {
-			super.setupPage("", getString("gb.edit"));
+			super.setupPage(getString("gb.edit"), repositoryModel.name);
 			if (repositoryModel.accessRestriction.exceeds(AccessRestrictionType.NONE)) {
 				repositoryUsers.addAll(GitBlit.self().getRepositoryUsers(repositoryModel));
 				Collections.sort(repositoryUsers);
 			}
 			federationSets.addAll(repositoryModel.federationSets);
-		}
+		}		
+		
 
 		final String oldName = repositoryModel.name;
 		// users palette
diff --git a/src/com/gitblit/wicket/pages/EditUserPage.html b/src/com/gitblit/wicket/pages/EditUserPage.html
index 2f90bbf..ceda3cb 100644
--- a/src/com/gitblit/wicket/pages/EditUserPage.html
+++ b/src/com/gitblit/wicket/pages/EditUserPage.html
@@ -6,12 +6,7 @@
 
 <wicket:extend>
 <body onload="document.getElementById('username').focus();">
-	<!-- Push content down to preserve header image -->
-	<div style="padding-top:20px"></div>
-
-	<div style="text-align:center;" wicket:id="feedback">[Feedback Panel]</div>	
-
-	<!-- Repository Table -->
+	<!-- User Table -->
 	<form wicket:id="editForm">
 		<table class="plain">
 			<tbody>
@@ -21,7 +16,7 @@
 				<tr><th><wicket:message key="gb.canAdmin"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="canAdmin" tabindex="6" /> &nbsp;<i><wicket:message key="gb.canAdminDescription"></wicket:message></i></td></tr>				
 				<tr><th><wicket:message key="gb.excludeFromFederation"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="excludeFromFederation" tabindex="7" /> &nbsp;<i><wicket:message key="gb.excludeFromFederationDescription"></wicket:message></i></td></tr>				
 				<tr><th style="vertical-align: top;"><wicket:message key="gb.restrictedRepositories"></wicket:message></th><td style="padding:2px;"><span wicket:id="repositories"></span></td></tr>
-				<tr><th></th><td class="editButton"><input class="btn primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="8" /> <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="9" /></td></tr>
+				<tr><th></th><td class="editButton"><input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="8" /> &nbsp; <input class="btn primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="9" /></td></tr>
 			</tbody>
 		</table>
 	</form>	
diff --git a/src/com/gitblit/wicket/pages/EditUserPage.java b/src/com/gitblit/wicket/pages/EditUserPage.java
index a358911..8dbb0d9 100644
--- a/src/com/gitblit/wicket/pages/EditUserPage.java
+++ b/src/com/gitblit/wicket/pages/EditUserPage.java
@@ -44,7 +44,7 @@
 import com.gitblit.wicket.WicketUtils;
 
 @RequiresAdminRole
-public class EditUserPage extends BasePage {
+public class EditUserPage extends StandardPage {
 
 	private final boolean isCreate;
 
@@ -66,10 +66,11 @@
 
 	protected void setupPage(final UserModel userModel) {
 		if (isCreate) {
-			super.setupPage("", getString("gb.newUser"));
+			super.setupPage(getString("gb.newUser"), "");
 		} else {
-			super.setupPage("", getString("gb.edit"));
+			super.setupPage(getString("gb.edit"), userModel.username);
 		}
+		
 		final Model<String> confirmPassword = new Model<String>(
 				StringUtils.isEmpty(userModel.password) ? "" : userModel.password);
 		CompoundPropertyModel<UserModel> model = new CompoundPropertyModel<UserModel>(userModel);
diff --git a/src/com/gitblit/wicket/pages/FederationPage.html b/src/com/gitblit/wicket/pages/FederationPage.html
new file mode 100644
index 0000000..ab8a941
--- /dev/null
+++ b/src/com/gitblit/wicket/pages/FederationPage.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"  
+      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"  
+      xml:lang="en"  
+      lang="en"> 
+<body>
+<wicket:extend>
+
+	<div wicket:id="federationProposalsPanel">[federation proposals panel]</div>
+
+	<div style="padding-top: 10px;" wicket:id="federationRegistrationsPanel">[federation registrations panel]</div>
+
+	<div wicket:id="federationTokensPanel">[federation tokens panel]</div>
+		
+</wicket:extend>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/FederationPage.java b/src/com/gitblit/wicket/pages/FederationPage.java
new file mode 100644
index 0000000..b993f71
--- /dev/null
+++ b/src/com/gitblit/wicket/pages/FederationPage.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011 gitblit.com.
+ *
+ * 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 com.gitblit.wicket.pages;
+
+import com.gitblit.GitBlit;
+import com.gitblit.Keys;
+import com.gitblit.wicket.panels.FederationProposalsPanel;
+import com.gitblit.wicket.panels.FederationRegistrationsPanel;
+import com.gitblit.wicket.panels.FederationTokensPanel;
+
+public class FederationPage extends RootPage {
+
+	public FederationPage() {
+		super();
+
+		boolean showFederation = showAdmin && GitBlit.canFederate();
+		add(new FederationTokensPanel("federationTokensPanel", showFederation)
+				.setVisible(showFederation));
+		FederationProposalsPanel proposalsPanel = new FederationProposalsPanel(
+				"federationProposalsPanel");
+		if (showFederation) {
+			proposalsPanel.hideIfEmpty();
+		} else {
+			proposalsPanel.setVisible(false);
+		}
+
+		boolean showRegistrations = GitBlit.getBoolean(Keys.web.showFederationRegistrations, false);
+		FederationRegistrationsPanel registrationsPanel = new FederationRegistrationsPanel(
+				"federationRegistrationsPanel");
+		if (showAdmin || showRegistrations) {
+			registrationsPanel.hideIfEmpty();
+		} else {
+			registrationsPanel.setVisible(false);
+		}
+		add(proposalsPanel);
+		add(registrationsPanel);
+	}
+}
diff --git a/src/com/gitblit/wicket/pages/FederationRegistrationPage.html b/src/com/gitblit/wicket/pages/FederationRegistrationPage.html
index c7c5bde..de30cf3 100644
--- a/src/com/gitblit/wicket/pages/FederationRegistrationPage.html
+++ b/src/com/gitblit/wicket/pages/FederationRegistrationPage.html
@@ -6,11 +6,6 @@
 
 <body>
 <wicket:extend>
-
-	<div style="padding-top:20px"></div>
-
-	<div style="text-align:center;" wicket:id="feedback">[Feedback Panel]</div>	
-
 	<!-- registration info -->
 	<table class="plain">
 		<tr><th><wicket:message key="gb.url">url</wicket:message></th><td><img style="border:0px;vertical-align:middle;" wicket:id="typeIcon" /> <span wicket:id="url">[url]</span></td></tr>
diff --git a/src/com/gitblit/wicket/pages/FederationRegistrationPage.java b/src/com/gitblit/wicket/pages/FederationRegistrationPage.java
index 00cc2eb..aed94a4 100644
--- a/src/com/gitblit/wicket/pages/FederationRegistrationPage.java
+++ b/src/com/gitblit/wicket/pages/FederationRegistrationPage.java
@@ -31,7 +31,7 @@
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.WicketUtils;
 
-public class FederationRegistrationPage extends BasePage {
+public class FederationRegistrationPage extends StandardPage {
 
 	public FederationRegistrationPage(PageParameters params) {
 		super(params);
@@ -53,8 +53,8 @@
 			error("Could not find federation registration!", true);
 		}
 
-		setupPage("", registration.isResultData() ? getString("gb.federationResults")
-				: getString("gb.federationRegistration"));
+		setupPage(registration.isResultData() ? getString("gb.federationResults")
+				: getString("gb.federationRegistration"), registration.url);
 
 		add(new Label("url", registration.url));
 		add(WicketUtils.getRegistrationImage("typeIcon", registration, this));
diff --git a/src/com/gitblit/wicket/pages/LoginPage.html b/src/com/gitblit/wicket/pages/LoginPage.html
deleted file mode 100644
index 5f9b779..0000000
--- a/src/com/gitblit/wicket/pages/LoginPage.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"  
-      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"  
-      xml:lang="en"  
-      lang="en"> 
-      
-	<!-- Head with Wicket-controlled resources in this package -->
-	<wicket:head>
-   		<title wicket:id="title">[page title]</title>
-		<link rel="stylesheet" type="text/css" href="gitblit.css"/>
-		<link rel="shortcut icon" href="gitblt-favicon.png" type="image/png" />
-	</wicket:head>
-	
-	<body onload="document.getElementById('username').focus();">
-		<div>
-			<div style="padding-top: 10px;text-align:center;">
-				<img src="gitblt_25.png" alt="Gitblit"/><br/>
-				<div style="padding-top:30px;font-weight:bold;" wicket:id="name">[name]</div>
-			</div>
-
-			<form style="text-align:center;" wicket:id="loginForm">
-				<div>
-					<p/>
-					<wicket:message key="gb.username"></wicket:message> &nbsp;
-					<input type="text" id="username" wicket:id="username" value=""/>
-					<p/>
-					<wicket:message key="gb.password"></wicket:message> &nbsp;
-					<input type="password"  wicket:id="password" value=""/>
-					<p/>
-					<input type="submit" value="Login" wicket:message="value:gb.login" />
-					<div style="padding-top:10px;" wicket:id="feedback"></div>
-				</div>
-			</form>					
-		</div>
-	</body>
-</html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/LoginPage.java b/src/com/gitblit/wicket/pages/LoginPage.java
deleted file mode 100644
index 45e1e2d..0000000
--- a/src/com/gitblit/wicket/pages/LoginPage.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright 2011 gitblit.com.
- *
- * 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 com.gitblit.wicket.pages;
-
-import javax.servlet.http.Cookie;
-
-import org.apache.wicket.PageParameters;
-import org.apache.wicket.RestartResponseException;
-import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.form.PasswordTextField;
-import org.apache.wicket.markup.html.form.StatelessForm;
-import org.apache.wicket.markup.html.form.TextField;
-import org.apache.wicket.markup.html.panel.FeedbackPanel;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.protocol.http.WebRequest;
-import org.apache.wicket.protocol.http.WebResponse;
-
-import com.gitblit.Constants;
-import com.gitblit.GitBlit;
-import com.gitblit.Keys;
-import com.gitblit.models.UserModel;
-import com.gitblit.wicket.GitBlitWebSession;
-
-public class LoginPage extends WebPage {
-
-	IModel<String> username = new Model<String>("");
-	IModel<String> password = new Model<String>("");
-
-	public LoginPage(PageParameters params) {
-		super(params);
-
-		// If we are already logged in because user directly accessed
-		// the login url, redirect to the home page
-		if (GitBlitWebSession.get().isLoggedIn()) {
-			throw new RestartResponseException(getApplication().getHomePage());
-		}
-
-		if (GitBlit.getBoolean(Keys.web.allowCookieAuthentication, false)) {
-			loginByCookie();
-		}
-
-		add(new Label("title", GitBlit.getString(Keys.web.siteName, Constants.NAME)));
-		add(new Label("name", GitBlit.getString(Keys.web.siteName, Constants.NAME)));
-
-		StatelessForm<Void> loginForm = new StatelessForm<Void>("loginForm") {
-
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public void onSubmit() {
-				String username = LoginPage.this.username.getObject();
-				char[] password = LoginPage.this.password.getObject().toCharArray();
-
-				UserModel user = GitBlit.self().authenticate(username, password);
-				if (user == null) {
-					error("Invalid username or password!");
-				} else if (user.username.equals(Constants.FEDERATION_USER)) {
-					// disallow the federation user from logging in via the
-					// web ui
-					error("Invalid username or password!");
-					user = null;
-				} else {
-					loginUser(user);
-				}
-			}
-		};
-		loginForm.add(new TextField<String>("username", username));
-		loginForm.add(new PasswordTextField("password", password));
-		loginForm.add(new FeedbackPanel("feedback"));
-		add(loginForm);
-	}
-
-	private void loginByCookie() {
-		UserModel user = null;
-
-		// Grab cookie from Browser Session
-		Cookie[] cookies = ((WebRequest) getRequestCycle().getRequest()).getCookies();
-		if (cookies != null && cookies.length > 0) {
-			user = GitBlit.self().authenticate(cookies);
-		}
-
-		// Login the user
-		loginUser(user);
-	}
-
-	private void loginUser(UserModel user) {
-		if (user != null) {
-			// Set the user into the session
-			GitBlitWebSession.get().setUser(user);
-
-			// Set Cookie
-			if (GitBlit.getBoolean(Keys.web.allowCookieAuthentication, false)) {
-				WebResponse response = (WebResponse) getRequestCycle().getResponse();
-				GitBlit.self().setCookie(response, user);
-			}
-
-			if (!continueToOriginalDestination()) {
-				// Redirect to home page
-				setResponsePage(getApplication().getHomePage());
-			}
-		}
-	}
-}
diff --git a/src/com/gitblit/wicket/pages/RepositoriesPage.html b/src/com/gitblit/wicket/pages/RepositoriesPage.html
index 6aa55de..c883099 100644
--- a/src/com/gitblit/wicket/pages/RepositoriesPage.html
+++ b/src/com/gitblit/wicket/pages/RepositoriesPage.html
@@ -9,34 +9,9 @@
 
 <body>
 <wicket:extend>
-<div class="topbar">
-			<div class="fill">
-			<div class="container">
-			<a class="brand" title="gitblit homepage" href="http://gitblit.com/">
-				<img src="gitblt_25.png" width="79" height="25" alt="gitblit" class="logo"/>				
-			</a>
-<form class="pull-right" action="">
-<input class="input-small" type="text" placeholder="Username">
-<input class="input-small" type="password" placeholder="Password">
-<button class="btn primary" type="submit">Sign in</button>
-</form>
-</div>
-</div>
-</div>
-	<div style="text-align:center;padding-top:5px;" wicket:id="feedback">[Feedback Panel]</div>
-	
 	<div class="markdown" style="margin-top:-1em;padding-bottom:5px;" wicket:id="repositoriesMessage">[repositories message]</div>
 	
 	<div wicket:id="repositoriesPanel">[repositories panel]</div>
-
-	<div style="padding-top: 10px;"wicket:id="usersPanel">[users panel]</div>
-	
-	<div style="padding-top: 10px;"wicket:id="federationTokensPanel">[federation tokens panel]</div>
-
-	<div style="padding-top: 10px;"wicket:id="federationProposalsPanel">[federation proposals panel]</div>
-
-	<div style="padding-top: 10px;"wicket:id="federationRegistrationsPanel">[federation registrations panel]</div>
-		
 </wicket:extend>
 </body>
 </html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/RepositoriesPage.java b/src/com/gitblit/wicket/pages/RepositoriesPage.java
index 619d42e..ce532a7 100644
--- a/src/com/gitblit/wicket/pages/RepositoriesPage.java
+++ b/src/com/gitblit/wicket/pages/RepositoriesPage.java
@@ -19,7 +19,6 @@
 import java.io.FileReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.text.MessageFormat;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.markup.html.basic.Label;
@@ -29,50 +28,13 @@
 import com.gitblit.Keys;
 import com.gitblit.utils.MarkdownUtils;
 import com.gitblit.utils.StringUtils;
-import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.WicketUtils;
-import com.gitblit.wicket.panels.FederationProposalsPanel;
-import com.gitblit.wicket.panels.FederationRegistrationsPanel;
-import com.gitblit.wicket.panels.FederationTokensPanel;
 import com.gitblit.wicket.panels.RepositoriesPanel;
-import com.gitblit.wicket.panels.UsersPanel;
 
-public class RepositoriesPage extends BasePage {
+public class RepositoriesPage extends RootPage {
 
 	public RepositoriesPage() {
-		super();
-		setupPage("", "");
-
-		final boolean showAdmin;
-		if (GitBlit.getBoolean(Keys.web.authenticateAdminPages, true)) {
-			boolean allowAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
-			showAdmin = allowAdmin && GitBlitWebSession.get().canAdmin();
-			// authentication requires state and session
-			setStatelessHint(false);
-		} else {
-			showAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
-			if (GitBlit.getBoolean(Keys.web.authenticateViewPages, false)) {
-				// authentication requires state and session
-				setStatelessHint(false);
-			} else {
-				// no authentication required, no state and no session required
-				setStatelessHint(true);
-			}
-		}
-
-		// display an error message cached from a redirect
-		String cachedMessage = GitBlitWebSession.get().clearErrorMessage();
-		if (!StringUtils.isEmpty(cachedMessage)) {
-			error(cachedMessage);
-		} else if (showAdmin) {
-			int pendingProposals = GitBlit.self().getPendingFederationProposals().size();
-			if (pendingProposals == 1) {
-				info("There is 1 federation proposal awaiting review.");
-			} else if (pendingProposals > 1) {
-				info(MessageFormat.format("There are {0} federation proposals awaiting review.",
-						pendingProposals));
-			}
-		}
+		super();		
 
 		// Load the markdown welcome message
 		String messageSource = GitBlit.getString(Keys.web.repositoriesMessage, "gitblit");
@@ -109,28 +71,6 @@
 		Component repositoriesMessage = new Label("repositoriesMessage", message)
 				.setEscapeModelStrings(false);
 		add(repositoriesMessage);
-		add(new RepositoriesPanel("repositoriesPanel", showAdmin, null, getAccessRestrictions()));
-		add(new UsersPanel("usersPanel", showAdmin).setVisible(showAdmin));
-		boolean showFederation = showAdmin && GitBlit.canFederate();
-		add(new FederationTokensPanel("federationTokensPanel", showFederation)
-				.setVisible(showFederation));
-		FederationProposalsPanel proposalsPanel = new FederationProposalsPanel(
-				"federationProposalsPanel");
-		if (showFederation) {
-			proposalsPanel.hideIfEmpty();
-		} else {
-			proposalsPanel.setVisible(false);
-		}
-
-		boolean showRegistrations = GitBlit.getBoolean(Keys.web.showFederationRegistrations, false);
-		FederationRegistrationsPanel registrationsPanel = new FederationRegistrationsPanel(
-				"federationRegistrationsPanel");
-		if (showAdmin || showRegistrations) {
-			registrationsPanel.hideIfEmpty();
-		} else {
-			registrationsPanel.setVisible(false);
-		}
-		add(proposalsPanel);
-		add(registrationsPanel);
+		add(new RepositoriesPanel("repositoriesPanel", showAdmin, null, getAccessRestrictions()));		
 	}
 }
diff --git a/src/com/gitblit/wicket/pages/ReviewProposalPage.html b/src/com/gitblit/wicket/pages/ReviewProposalPage.html
index d4244ea..7f26f28 100644
--- a/src/com/gitblit/wicket/pages/ReviewProposalPage.html
+++ b/src/com/gitblit/wicket/pages/ReviewProposalPage.html
@@ -6,11 +6,6 @@
 
 <body>
 <wicket:extend>
-
-	<div style="padding-top:20px"></div>
-
-	<div style="text-align:center;" wicket:id="feedback">[Feedback Panel]</div>	
-
 	<!-- proposal info -->
 	<table class="plain">
 		<tr><th><wicket:message key="gb.received">received</wicket:message></th><td><span wicket:id="received">[received]</span></td></tr>
diff --git a/src/com/gitblit/wicket/pages/ReviewProposalPage.java b/src/com/gitblit/wicket/pages/ReviewProposalPage.java
index b006d80..2f2d6f3 100644
--- a/src/com/gitblit/wicket/pages/ReviewProposalPage.java
+++ b/src/com/gitblit/wicket/pages/ReviewProposalPage.java
@@ -33,7 +33,7 @@
 import com.gitblit.wicket.panels.RepositoriesPanel;
 
 @RequiresAdminRole
-public class ReviewProposalPage extends BasePage {
+public class ReviewProposalPage extends StandardPage {
 
 	private final String PROPS_PATTERN = "{0} = {1}\n";
 
@@ -42,9 +42,6 @@
 	public ReviewProposalPage(PageParameters params) {
 		super(params);
 
-		setupPage("", getString("gb.proposals"));
-		setStatelessHint(true);
-
 		final String token = WicketUtils.getToken(params);
 
 		FederationProposal proposal = GitBlit.self().getPendingFederationProposal(token);
@@ -52,13 +49,15 @@
 			error("Could not find federation proposal!", true);
 		}
 
+		setupPage(getString("gb.proposals"), proposal.url);
+		
+
 		add(new Label("url", proposal.url));
 		add(new Label("message", proposal.message));
 		add(WicketUtils.createTimestampLabel("received", proposal.received, getTimeZone()));
 		add(new Label("token", proposal.token));
 		add(new Label("tokenType", proposal.tokenType.name()));
-
-		boolean go = true;
+		
 		String p;
 		if (GitBlit.isGO()) {
 			// gitblit.properties definition
diff --git a/src/com/gitblit/wicket/pages/RootPage.html b/src/com/gitblit/wicket/pages/RootPage.html
new file mode 100644
index 0000000..59a0fe1
--- /dev/null
+++ b/src/com/gitblit/wicket/pages/RootPage.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"  
+      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"  
+      xml:lang="en"  
+      lang="en"> 
+<body>
+<wicket:extend>
+	<div class="topbar">
+		<div class="fill">
+			<div class="container">
+				<a class="brand" title="gitblit homepage" href="http://gitblit.com/">
+					<img src="gitblt_25.png" width="79" height="25" alt="gitblit" class="logo"/>				
+				</a>
+				
+				<ul class="nav">				
+					<li><a wicket:id="repositories"><wicket:message key="gb.repositories"></wicket:message></a></li>
+					<li><a wicket:id="users"><wicket:message key="gb.users"></wicket:message></a></li>
+					<li><a wicket:id="federation"><wicket:message key="gb.federation"></wicket:message></a></li>
+				</ul>
+				
+				<form class="pull-right" wicket:id="loginForm">
+					<input  wicket:id="username" class="input-small" type="text" placeholder="Username">
+					<input  wicket:id="password" class="input-small" type="password" placeholder="Password">
+					<button class="btn primary" type="submit">Sign in</button>
+				</form>
+			</div>
+		</div>
+	</div>
+	
+	<div style="text-align:center;padding-top:5px;" wicket:id="feedback">[Feedback Panel]</div>
+	
+	<!-- subclass content -->
+	<wicket:child/>		
+</wicket:extend>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/RootPage.java b/src/com/gitblit/wicket/pages/RootPage.java
new file mode 100644
index 0000000..dd64de6
--- /dev/null
+++ b/src/com/gitblit/wicket/pages/RootPage.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2011 gitblit.com.
+ *
+ * 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 com.gitblit.wicket.pages;
+
+import java.text.MessageFormat;
+
+import javax.servlet.http.Cookie;
+
+import org.apache.wicket.markup.html.form.PasswordTextField;
+import org.apache.wicket.markup.html.form.StatelessForm;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.protocol.http.WebRequest;
+import org.apache.wicket.protocol.http.WebResponse;
+
+import com.gitblit.Constants;
+import com.gitblit.GitBlit;
+import com.gitblit.Keys;
+import com.gitblit.models.UserModel;
+import com.gitblit.utils.StringUtils;
+import com.gitblit.wicket.GitBlitWebSession;
+
+public abstract class RootPage extends BasePage {
+
+	final boolean showAdmin;
+
+	IModel<String> username = new Model<String>("");
+	IModel<String> password = new Model<String>("");
+
+	public RootPage() {
+		super();
+		setupPage("", "");
+
+		// try to automatically login from cookie
+		if (!GitBlitWebSession.get().isLoggedIn()
+				&& GitBlit.getBoolean(Keys.web.allowCookieAuthentication, false)) {
+			loginByCookie();
+		}
+
+		if (GitBlit.getBoolean(Keys.web.authenticateAdminPages, true)) {
+			boolean allowAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
+			showAdmin = allowAdmin && GitBlitWebSession.get().canAdmin();
+			// authentication requires state and session
+			setStatelessHint(false);
+		} else {
+			showAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
+			if (GitBlit.getBoolean(Keys.web.authenticateViewPages, false)) {
+				// authentication requires state and session
+				setStatelessHint(false);
+			} else {
+				// no authentication required, no state and no session required
+				setStatelessHint(true);
+			}
+		}
+		boolean showRegistrations = GitBlit.canFederate()
+				&& GitBlit.getBoolean(Keys.web.showFederationRegistrations, false);
+
+		// navigation links
+		add(new BookmarkablePageLink<Void>("repositories", RepositoriesPage.class));
+		add(new BookmarkablePageLink<Void>("users", UsersPage.class).setVisible(showAdmin));
+		add(new BookmarkablePageLink<Void>("federation", FederationPage.class).setVisible(showAdmin
+				|| showRegistrations));
+
+		// login form
+		StatelessForm<Void> loginForm = new StatelessForm<Void>("loginForm") {
+
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void onSubmit() {
+				String username = RootPage.this.username.getObject();
+				char[] password = RootPage.this.password.getObject().toCharArray();
+
+				UserModel user = GitBlit.self().authenticate(username, password);
+				if (user == null) {
+					error("Invalid username or password!");
+				} else if (user.username.equals(Constants.FEDERATION_USER)) {
+					// disallow the federation user from logging in via the
+					// web ui
+					error("Invalid username or password!");
+					user = null;
+				} else {
+					loginUser(user);
+				}
+			}
+		};
+		loginForm.add(new TextField<String>("username", username));
+		loginForm.add(new PasswordTextField("password", password));
+		add(loginForm);
+		if (GitBlit.getBoolean(Keys.web.authenticateViewPages, true)
+				|| GitBlit.getBoolean(Keys.web.authenticateAdminPages, true)) {
+			loginForm.setVisible(!GitBlitWebSession.get().isLoggedIn());
+		} else {
+			loginForm.setVisible(false);
+		}
+
+		// display an error message cached from a redirect
+		String cachedMessage = GitBlitWebSession.get().clearErrorMessage();
+		if (!StringUtils.isEmpty(cachedMessage)) {
+			error(cachedMessage);
+		} else if (showAdmin) {
+			int pendingProposals = GitBlit.self().getPendingFederationProposals().size();
+			if (pendingProposals == 1) {
+				info("There is 1 federation proposal awaiting review.");
+			} else if (pendingProposals > 1) {
+				info(MessageFormat.format("There are {0} federation proposals awaiting review.",
+						pendingProposals));
+			}
+		}
+	}
+
+	private void loginByCookie() {
+		UserModel user = null;
+
+		// Grab cookie from Browser Session
+		Cookie[] cookies = ((WebRequest) getRequestCycle().getRequest()).getCookies();
+		if (cookies != null && cookies.length > 0) {
+			user = GitBlit.self().authenticate(cookies);
+		}
+
+		// Login the user
+		loginUser(user);
+	}
+
+	private void loginUser(UserModel user) {
+		if (user != null) {
+			// Set the user into the session
+			GitBlitWebSession.get().setUser(user);
+
+			// Set Cookie
+			if (GitBlit.getBoolean(Keys.web.allowCookieAuthentication, false)) {
+				WebResponse response = (WebResponse) getRequestCycle().getResponse();
+				GitBlit.self().setCookie(response, user);
+			}
+
+			if (!continueToOriginalDestination()) {
+				// Redirect to home page
+				setResponsePage(getApplication().getHomePage());
+			}
+		}
+	}
+}
diff --git a/src/com/gitblit/wicket/pages/SendProposalPage.html b/src/com/gitblit/wicket/pages/SendProposalPage.html
index 90fe0a2..794cb70 100644
--- a/src/com/gitblit/wicket/pages/SendProposalPage.html
+++ b/src/com/gitblit/wicket/pages/SendProposalPage.html
@@ -6,21 +6,15 @@
 
 <wicket:extend>
 <body onload="document.getElementById('myUrl').focus();">
-
-
-	<div style="padding-top:20px"></div>
-
-	<div style="text-align:center;" wicket:id="feedback">[Feedback Panel]</div>	
-
 	<!-- proposal info -->
 	<form wicket:id="editForm">
 	<table class="plain">
-		<tr><th><wicket:message key="gb.url">url</wicket:message></th><td class="edit"><input type="text" wicket:id="myUrl" id="myUrl" size="60" />  &nbsp;<i><wicket:message key="gb.myUrlDescription"></wicket:message></i></td></tr>
-		<tr><th><wicket:message key="gb.destinationUrl">destination url</wicket:message></th><td class="edit"><input type="text" wicket:id="destinationUrl" size="60" /> &nbsp;<i><wicket:message key="gb.destinationUrlDescription"></wicket:message></i></td></tr>
-		<tr><th valign="top"><wicket:message key="gb.message">message</wicket:message></th><td class="edit"><input type="text" wicket:id="message" size="80" /></td></tr>
+		<tr><th><wicket:message key="gb.url">url</wicket:message></th><td class="edit"><input class="span6" type="text" wicket:id="myUrl" id="myUrl" size="60" />  &nbsp;<i><wicket:message key="gb.myUrlDescription"></wicket:message></i></td></tr>
+		<tr><th><wicket:message key="gb.destinationUrl">destination url</wicket:message></th><td class="edit"><input class="span6" type="text" wicket:id="destinationUrl" size="60" /> &nbsp;<i><wicket:message key="gb.destinationUrlDescription"></wicket:message></i></td></tr>
+		<tr><th valign="top"><wicket:message key="gb.message">message</wicket:message></th><td class="edit"><input class="span8" type="text" wicket:id="message" size="80" /></td></tr>
 		<tr><th><wicket:message key="gb.type">type</wicket:message></th><td><span wicket:id="tokenType">[token type]</span></td></tr>
 		<tr><th><wicket:message key="gb.token">token</wicket:message></th><td><span class="sha1" wicket:id="token">[token]</span></td></tr>
-		<tr><th></th><td class="editButton"><input type="submit" value="propose" wicket:message="value:gb.sendProposal" wicket:id="save" /> <input type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" /></td></tr>
+		<tr><th></th><td class="editButton"><input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" /> <input class="btn primary" type="submit" value="propose" wicket:message="value:gb.sendProposal" wicket:id="save" /> </td></tr>
 	</table>
 	</form>
 	
diff --git a/src/com/gitblit/wicket/pages/SendProposalPage.java b/src/com/gitblit/wicket/pages/SendProposalPage.java
index 635b432..11f97a0 100644
--- a/src/com/gitblit/wicket/pages/SendProposalPage.java
+++ b/src/com/gitblit/wicket/pages/SendProposalPage.java
@@ -37,7 +37,7 @@
 import com.gitblit.wicket.panels.RepositoriesPanel;
 
 @RequiresAdminRole
-public class SendProposalPage extends BasePage {
+public class SendProposalPage extends StandardPage {
 
 	public String myUrl;
 
@@ -48,7 +48,7 @@
 	public SendProposalPage(PageParameters params) {
 		super(params);
 
-		setupPage("", getString("gb.sendProposal"));
+		setupPage(getString("gb.sendProposal"), "");
 		setStatelessHint(true);
 
 		final String token = WicketUtils.getToken(params);
diff --git a/src/com/gitblit/wicket/pages/StandardPage.html b/src/com/gitblit/wicket/pages/StandardPage.html
new file mode 100644
index 0000000..cb6dcd5
--- /dev/null
+++ b/src/com/gitblit/wicket/pages/StandardPage.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"  
+      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"  
+      xml:lang="en"  
+      lang="en"> 
+
+<body>
+<wicket:extend>
+	<!-- topbar header -->
+	<div class="topbar">
+		<div class="fill">
+			<div class="container">
+				<a class="brand" title="gitblit homepage" href="http://gitblit.com/">
+					<img src="gitblt_25.png" width="79" height="25" alt="gitblit" class="logo"/>				
+				</a>				
+			</div>
+		</div>
+	</div>
+	
+	<!-- feedback panel -->
+	<div style="text-align:center;padding-top:5px;" wicket:id="feedback">[Feedback Panel]</div>
+	
+	<!-- page header -->
+	<div class="page-header">
+		<h2><span wicket:id="pageName">[page name]</span> <small><span wicket:id="pageSubName">[sub name]</span></small></h2>
+	</div>
+	
+	<!-- Subclass Content -->
+	<wicket:child/>
+</wicket:extend>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/StandardPage.java b/src/com/gitblit/wicket/pages/StandardPage.java
new file mode 100644
index 0000000..ff16b63
--- /dev/null
+++ b/src/com/gitblit/wicket/pages/StandardPage.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 gitblit.com.
+ *
+ * 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 com.gitblit.wicket.pages;
+
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.markup.html.basic.Label;
+
+public abstract class StandardPage extends BasePage {
+	
+	public StandardPage() {
+		// create constructor
+		super();
+		setStatelessHint(true);
+	}
+
+	public StandardPage(PageParameters params) {
+		// edit constructor
+		super(params);
+		setStatelessHint(true);
+	}
+
+	protected void setupPage(String pageName, String subName) {		
+		add(new Label("pageName", pageName));
+		add(new Label("pageSubName", "/ " + subName));
+		super.setupPage("", pageName);
+	}
+}
diff --git a/src/com/gitblit/wicket/pages/UsersPage.html b/src/com/gitblit/wicket/pages/UsersPage.html
new file mode 100644
index 0000000..4d14496
--- /dev/null
+++ b/src/com/gitblit/wicket/pages/UsersPage.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"  
+      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"  
+      xml:lang="en"  
+      lang="en"> 
+<body>
+<wicket:extend>
+	<div wicket:id="usersPanel">[users panel]</div>
+</wicket:extend>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/UsersPage.java b/src/com/gitblit/wicket/pages/UsersPage.java
new file mode 100644
index 0000000..9a7f8a5
--- /dev/null
+++ b/src/com/gitblit/wicket/pages/UsersPage.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2011 gitblit.com.
+ *
+ * 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 com.gitblit.wicket.pages;
+
+import com.gitblit.wicket.RequiresAdminRole;
+import com.gitblit.wicket.panels.UsersPanel;
+
+@RequiresAdminRole
+public class UsersPage extends RootPage {
+
+	public UsersPage() {
+		super();		
+
+		add(new UsersPanel("usersPanel", showAdmin).setVisible(showAdmin));
+	}
+}

--
Gitblit v1.9.1