From 264ba908941414ea5e750524b2472f7ad0670563 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 02 May 2013 21:37:58 -0400
Subject: [PATCH] Improved the repository url panel and show git daemon url, appropriately

---
 src/main/java/com/gitblit/wicket/pages/BasePage.java                    |   42 ++++++++
 src/main/java/com/gitblit/wicket/pages/ProjectPage.html                 |    2 
 src/main/java/com/gitblit/wicket/pages/SummaryPage.java                 |   34 +++++-
 src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.html     |    2 
 src/main/resources/gitblit.css                                          |   24 ++++
 src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.java |  115 +++++++++++++++++++++++
 src/main/java/com/gitblit/wicket/GitBlitWebApp.properties               |    7 +
 src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.html |   42 ++++++++
 src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java         |   12 +
 src/main/java/com/gitblit/wicket/pages/SummaryPage.html                 |   10 +
 src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java     |    6 
 11 files changed, 279 insertions(+), 17 deletions(-)

diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
index f2d4a36..aa5a415 100644
--- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
+++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
@@ -445,7 +445,10 @@
 gb.owners = owners
 gb.sessionEnded = Session has been closed
 gb.closeBrowser = Please close the browser to properly end the session.
-gb.doesNotExistInTree = {0} does not exist in tree {1}
+gb.doesNotExistInTree = {0} does not exist in tree {1}
 gb.enableIncrementalPushTags = enable incremental push tags
 gb.useIncrementalPushTagsDescription = on push, automatically tag each branch tip with an incremental revision number
-gb.incrementalPushTagMessage = Auto-tagged [{0}] branch on push
\ No newline at end of file
+gb.incrementalPushTagMessage = Auto-tagged [{0}] branch on push
+gb.externalPermissions = {0} access permissions for {1} are externally maintained
+gb.viewAccess = You do not have Gitblit read or write access
+gb.yourProtocolPermissionIs = Your {0} access permission for {1} is {2}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/wicket/pages/BasePage.java b/src/main/java/com/gitblit/wicket/pages/BasePage.java
index bb7d8c9..b2dcce3 100644
--- a/src/main/java/com/gitblit/wicket/pages/BasePage.java
+++ b/src/main/java/com/gitblit/wicket/pages/BasePage.java
@@ -32,6 +32,7 @@
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.wicket.Application;
+import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.PageParameters;
 import org.apache.wicket.RedirectToUrlException;
@@ -44,6 +45,7 @@
 import org.apache.wicket.markup.html.panel.FeedbackPanel;
 import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.protocol.http.RequestUtils;
+import org.apache.wicket.protocol.http.WebRequest;
 import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,6 +65,7 @@
 import com.gitblit.utils.TimeUtils;
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.WicketUtils;
+import com.gitblit.wicket.panels.DetailedRepositoryUrlPanel;
 import com.gitblit.wicket.panels.LinkPanel;
 
 public abstract class BasePage extends SessionPage {
@@ -270,6 +273,45 @@
 		return sb.toString();
 	}
 	
+	protected Component createGitDaemonUrlPanel(String wicketId, UserModel user, RepositoryModel repository) {
+		int gitDaemonPort = GitBlit.getInteger(Keys.git.daemonPort, 0);
+		if (gitDaemonPort > 0 && user.canClone(repository)) {
+			String servername = ((WebRequest) getRequest()).getHttpServletRequest().getServerName();
+			String gitDaemonUrl;
+			if (gitDaemonPort == 9418) {
+				// standard port
+				gitDaemonUrl = MessageFormat.format("git://{0}/{1}", servername, repository.name);
+			} else {
+				// non-standard port
+				gitDaemonUrl = MessageFormat.format("git://{0}:{1,number,0}/{2}", servername, gitDaemonPort, repository.name);
+			}
+			
+			AccessPermission gitDaemonPermission = user.getRepositoryPermission(repository).permission;;
+			if (gitDaemonPermission.atLeast(AccessPermission.CLONE)) {
+				if (repository.accessRestriction.atLeast(AccessRestrictionType.CLONE)) {
+					// can not authenticate clone via anonymous git protocol
+					gitDaemonPermission = AccessPermission.NONE;
+				} else if (repository.accessRestriction.atLeast(AccessRestrictionType.PUSH)) {
+					// can not authenticate push via anonymous git protocol
+					gitDaemonPermission = AccessPermission.CLONE;
+				} else {
+					// normal user permission
+				}
+			}
+			
+			if (AccessPermission.NONE.equals(gitDaemonPermission)) {
+				// repository prohibits all anonymous access
+				return new Label(wicketId).setVisible(false);
+			} else {
+				// repository allows some form of anonymous access
+				return new DetailedRepositoryUrlPanel(wicketId, getLocalizer(), this, repository.name, gitDaemonUrl, gitDaemonPermission);
+			}
+		} else {
+			// git daemon is not running
+			return new Label(wicketId).setVisible(false);
+		}
+	}
+	
 	protected List<ProjectModel> getProjectModels() {
 		final UserModel user = GitBlitWebSession.get().getUser();
 		List<ProjectModel> projects = GitBlit.self().getProjectModels(user, true);
diff --git a/src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java b/src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java
index cccf8a6..a2264c4 100644
--- a/src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java
@@ -22,6 +22,7 @@
 import org.apache.wicket.PageParameters;
 import org.apache.wicket.markup.html.basic.Label;
 
+import com.gitblit.Constants.AccessPermission;
 import com.gitblit.GitBlit;
 import com.gitblit.Keys;
 import com.gitblit.models.RepositoryModel;
@@ -30,7 +31,7 @@
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.GitblitRedirectException;
 import com.gitblit.wicket.WicketUtils;
-import com.gitblit.wicket.panels.RepositoryUrlPanel;
+import com.gitblit.wicket.panels.DetailedRepositoryUrlPanel;
 
 public class EmptyRepositoryPage extends RootPage {
 
@@ -59,11 +60,16 @@
 			repositoryUrls.add(getRepositoryUrl(repository));
 		}
 		UserModel user = GitBlitWebSession.get().getUser();
-		repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(repositoryName, user == null ? "" : user.username));
+		if (user == null) {
+			user = UserModel.ANONYMOUS;
+		}
+		repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(repositoryName, UserModel.ANONYMOUS.equals(user) ? "" : user.username));
 		
 		String primaryUrl = ArrayUtils.isEmpty(repositoryUrls) ? "" : repositoryUrls.get(0);
+		AccessPermission accessPermission = user.getRepositoryPermission(repository).permission;
+		
 		add(new Label("repository", repositoryName));
-		add(new RepositoryUrlPanel("pushurl", primaryUrl));
+		add(new DetailedRepositoryUrlPanel("pushurl", getLocalizer(), this, repository.name, primaryUrl, accessPermission));
 		add(new Label("cloneSyntax", MessageFormat.format("git clone {0}", repositoryUrls.get(0))));
 		add(new Label("remoteSyntax", MessageFormat.format("git remote add gitblit {0}\ngit push gitblit master", primaryUrl)));
 	}
diff --git a/src/main/java/com/gitblit/wicket/pages/ProjectPage.html b/src/main/java/com/gitblit/wicket/pages/ProjectPage.html
index 3e73ba5..6c16195 100644
--- a/src/main/java/com/gitblit/wicket/pages/ProjectPage.html
+++ b/src/main/java/com/gitblit/wicket/pages/ProjectPage.html
@@ -38,7 +38,7 @@
 					</div>
 				</div>
 				<div class="row">
-					<div class="span6" style="border-bottom:1px solid #eee;" wicket:id="repositoryList">
+					<div class="span6" wicket:id="repositoryList">
 						<span wicket:id="repository"></span>
 					</div>
 				</div>				
diff --git a/src/main/java/com/gitblit/wicket/pages/SummaryPage.html b/src/main/java/com/gitblit/wicket/pages/SummaryPage.html
index 3e85df9..a751d1f 100644
--- a/src/main/java/com/gitblit/wicket/pages/SummaryPage.html
+++ b/src/main/java/com/gitblit/wicket/pages/SummaryPage.html
@@ -19,7 +19,15 @@
 				<tr><th><wicket:message key="gb.owners">[owner]</wicket:message></th><td><span wicket:id="repositoryOwners"><span wicket:id="owner"></span><span wicket:id="comma"></span></span></td></tr>
 				<tr><th><wicket:message key="gb.lastChange">[last change]</wicket:message></th><td><span wicket:id="repositoryLastChange">[repository last change]</span></td></tr>
 				<tr><th><wicket:message key="gb.stats">[stats]</wicket:message></th><td><span wicket:id="branchStats">[branch stats]</span> <span class="link"><a wicket:id="metrics"><wicket:message key="gb.metrics">[metrics]</wicket:message></a></span></td></tr>
-				<tr><th style="vertical-align:top;"><wicket:message key="gb.repositoryUrl">[URL]</wicket:message>&nbsp;<img style="vertical-align: top;padding-left:3px;" wicket:id="accessRestrictionIcon" /></th><td><span wicket:id="repositoryCloneUrl">[repository clone url]</span><div wicket:id="otherUrls"></div></td></tr>
+				<tr><th style="vertical-align:top;padding-top:4px;"><wicket:message key="gb.repositoryUrl">[URL]</wicket:message>&nbsp;<img style="vertical-align: top;padding-left:3px;" wicket:id="accessRestrictionIcon" /></th>
+				    <td style="padding-top:4px;">
+				    	<div wicket:id="repositoryPrimaryUrl">[repository primary url]</div>
+				    	<div wicket:id="repositoryGitDaemonUrl">[repository git daemon url]</div>
+				    	<div wicket:id="otherUrls" >
+				    		<div wicket:id="otherUrl" style="padding-top:10px"></div>
+				    	</div>
+				    </td>
+				</tr>
 			</table>
 		</div>
 	</div>
diff --git a/src/main/java/com/gitblit/wicket/pages/SummaryPage.java b/src/main/java/com/gitblit/wicket/pages/SummaryPage.java
index d68add0..863974b 100644
--- a/src/main/java/com/gitblit/wicket/pages/SummaryPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/SummaryPage.java
@@ -42,6 +42,7 @@
 import org.wicketstuff.googlecharts.MarkerType;
 import org.wicketstuff.googlecharts.ShapeMarker;
 
+import com.gitblit.Constants.AccessPermission;
 import com.gitblit.Constants.AccessRestrictionType;
 import com.gitblit.GitBlit;
 import com.gitblit.Keys;
@@ -56,9 +57,9 @@
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.panels.BranchesPanel;
+import com.gitblit.wicket.panels.DetailedRepositoryUrlPanel;
 import com.gitblit.wicket.panels.LinkPanel;
 import com.gitblit.wicket.panels.LogPanel;
-import com.gitblit.wicket.panels.RepositoryUrlPanel;
 import com.gitblit.wicket.panels.TagsPanel;
 
 public class SummaryPage extends RepositoryPage {
@@ -73,8 +74,11 @@
 		int numberRefs = GitBlit.getInteger(Keys.web.summaryRefsCount, 5);
 
 		Repository r = getRepository();
-		RepositoryModel model = getRepositoryModel();
+		final RepositoryModel model = getRepositoryModel();
 		UserModel user = GitBlitWebSession.get().getUser();
+		if (user == null) {
+			user = UserModel.ANONYMOUS;
+		}
 
 		List<Metric> metrics = null;
 		Metric metricsTotal = null;
@@ -124,7 +128,9 @@
 
 		List<String> repositoryUrls = new ArrayList<String>();
 
-		if (GitBlit.getBoolean(Keys.git.enableGitServlet, true)) {
+		AccessPermission accessPermission = null;
+		if (GitBlit.getBoolean(Keys.git.enableGitServlet, true)) {			
+			accessPermission = user.getRepositoryPermission(model).permission;
 			AccessRestrictionType accessRestriction = getRepositoryModel().accessRestriction;
 			switch (accessRestriction) {
 			case NONE:
@@ -150,13 +156,27 @@
 		} else {
 			add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false));
 		}
-		repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(repositoryName, user == null ? "" : user.username));
+		repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(repositoryName, UserModel.ANONYMOUS.equals(user) ? "" : user.username));
 		
 		String primaryUrl = ArrayUtils.isEmpty(repositoryUrls) ? "" : repositoryUrls.remove(0);
-		add(new RepositoryUrlPanel("repositoryCloneUrl", primaryUrl));
+		add(new DetailedRepositoryUrlPanel("repositoryPrimaryUrl", getLocalizer(), this, model.name, primaryUrl, accessPermission));
 
-		add(new Label("otherUrls", StringUtils.flattenStrings(repositoryUrls, "<br/>"))
-		.setEscapeModelStrings(false));
+		Component gitDaemonUrlPanel = createGitDaemonUrlPanel("repositoryGitDaemonUrl", user, model);
+		if (!StringUtils.isEmpty(primaryUrl) && gitDaemonUrlPanel instanceof DetailedRepositoryUrlPanel) {
+			WicketUtils.setCssStyle(gitDaemonUrlPanel, "padding-top: 10px");
+		}
+		add(gitDaemonUrlPanel);
+		
+		ListDataProvider<String> urls = new ListDataProvider<String>(repositoryUrls);
+		DataView<String> otherUrlsView = new DataView<String>("otherUrls", urls) {
+			private static final long serialVersionUID = 1L;
+
+			public void populateItem(final Item<String> item) {
+				final String url = item.getModelObject();
+				item.add(new DetailedRepositoryUrlPanel("otherUrl", getLocalizer(), this, model.name, url));
+			}
+		};
+		add(otherUrlsView);
 
 		add(new LogPanel("commitsPanel", repositoryName, getRepositoryModel().HEAD, r, numberCommits, 0, getRepositoryModel().showRemoteBranches));
 		add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs).hideIfEmpty());
diff --git a/src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.html b/src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.html
new file mode 100644
index 0000000..e671435
--- /dev/null
+++ b/src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.html
@@ -0,0 +1,42 @@
+<!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"> 
+
+<wicket:panel>
+	<span wicket:id="urlPanel"></span>
+    
+    <!--  Repository url panel -->
+    <wicket:fragment wicket:id="repositoryUrlPanel">
+    	<span class="repositoryUrlContainer">
+			<span wicket:id="repositoryProtocol" class="repositoryUrlEndCap">[protocol]</span>
+			<span class="repositoryUrl">
+				<span wicket:id="repositoryUrl">[repository url]</span>
+				<span class="hidden-phone hidden-tablet" wicket:id="copyFunction"></span>
+			</span>
+			<span class="hidden-phone hidden-tablet repositoryUrlEndCap" wicket:id="repositoryUrlPermission">[repository url permission]</span>
+		</span>
+	</wicket:fragment>
+	
+    <!-- Plain JavaScript manual copy & paste -->
+    <wicket:fragment wicket:id="jsPanel">
+    	<span style="vertical-align:baseline;">
+    		<img wicket:id="copyIcon" wicket:message="title:gb.copyToClipboard"></img>
+    	</span>
+    </wicket:fragment>
+    
+    <!-- flash-based button-press copy & paste -->
+    <wicket:fragment wicket:id="clippyPanel">
+   		<object wicket:message="title:gb.copyToClipboard" style="vertical-align:middle;"
+   			wicket:id="clippy"
+   			width="14" 
+   			height="14"
+   			bgcolor="#ffffff" 
+       		quality="high"
+       		wmode="transparent"
+       		scale="noscale"
+       		allowScriptAccess="always"></object>
+	</wicket:fragment>
+</wicket:panel>
+</html>
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.java b/src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.java
new file mode 100644
index 0000000..afeee1d
--- /dev/null
+++ b/src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2013 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.panels;
+
+import java.text.MessageFormat;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.Localizer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.image.ContextImage;
+import org.apache.wicket.markup.html.panel.Fragment;
+
+import com.gitblit.Constants.AccessPermission;
+import com.gitblit.GitBlit;
+import com.gitblit.Keys;
+import com.gitblit.utils.StringUtils;
+import com.gitblit.wicket.WicketUtils;
+
+public class DetailedRepositoryUrlPanel extends BasePanel {
+
+	private static final long serialVersionUID = 1L;
+	public DetailedRepositoryUrlPanel(String wicketId, Localizer localizer, Component parent, String repository, String url) {
+		this(wicketId, localizer, parent, repository, url, null);
+	}
+	
+	public DetailedRepositoryUrlPanel(String wicketId, Localizer localizer, Component parent, String repository, String url, AccessPermission ap) {
+		super(wicketId);
+		
+		String protocol = url.substring(0, url.indexOf(':'));
+		String note;
+		String permission;
+		
+		if (ap == null) {
+			note = MessageFormat.format(localizer.getString("gb.externalPermissions", parent), protocol, repository);
+			permission = "";
+		} else {
+			note = null;
+			permission = ap.toString();
+			String key;
+			switch (ap) {
+				case OWNER:
+				case REWIND:
+					key = "gb.rewindPermission";
+					break;
+				case DELETE:
+					key = "gb.deletePermission";
+					break;
+				case CREATE:
+					key = "gb.createPermission";
+					break;
+				case PUSH:
+					key = "gb.pushPermission";
+					break;
+				case CLONE:
+					key = "gb.clonePermission";
+					break;
+				default:
+					key = null;
+					note = localizer.getString("gb.viewAccess", parent);
+					break;
+			}
+			
+			if (note == null) {
+				String pattern = localizer.getString(key, parent);
+				String description = MessageFormat.format(pattern, permission);
+				String permissionPattern = localizer.getString("gb.yourProtocolPermissionIs", parent);
+				note = MessageFormat.format(permissionPattern, protocol.toUpperCase(), repository, description);
+			}
+		}
+		
+		if (!StringUtils.isEmpty(url) && ((ap == null) || ap.atLeast(AccessPermission.CLONE))) {
+			// valid repository url
+			Fragment fragment = new Fragment("urlPanel", "repositoryUrlPanel", this);
+			add(fragment);
+			fragment.add(WicketUtils.setHtmlTooltip(new Label("repositoryProtocol", protocol + "://"), note));
+			fragment.add(new Label("repositoryUrl", url.substring(url.indexOf("://") + 3)));
+			fragment.add(WicketUtils.setHtmlTooltip(new Label("repositoryUrlPermission", permission), note));
+
+			if (StringUtils.isEmpty(url)) {
+				fragment.add(new Label("copyFunction").setVisible(false));
+			} else if (GitBlit.getBoolean(Keys.web.allowFlashCopyToClipboard, true)) {
+				// clippy: flash-based copy & paste
+				Fragment copyFragment = new Fragment("copyFunction", "clippyPanel", this);
+				String baseUrl = WicketUtils.getGitblitURL(getRequest());
+				ShockWaveComponent clippy = new ShockWaveComponent("clippy", baseUrl + "/clippy.swf");
+				clippy.setValue("flashVars", "text=" + StringUtils.encodeURL(url));
+				copyFragment.add(clippy);
+				fragment.add(copyFragment);
+			} else {
+				// javascript: manual copy & paste with modal browser prompt dialog
+				Fragment copyFragment = new Fragment("copyFunction", "jsPanel", this);
+				ContextImage img = WicketUtils.newImage("copyIcon", "clippy.png");
+				img.add(new JavascriptTextPrompt("onclick", "Copy to Clipboard (Ctrl+C, Enter)", url));
+				copyFragment.add(img);
+				fragment.add(copyFragment);
+			}
+		} else {
+			// no Git url, there may be a message
+			add(new Label("urlPanel", MessageFormat.format("<i>{0}</i>", note)).setEscapeModelStrings(false).setVisible(!StringUtils.isEmpty(note)));
+		}
+	}
+}
diff --git a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.html b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.html
index 9b621d5..e67e641 100644
--- a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.html
+++ b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.html
@@ -72,7 +72,7 @@
 					<span style="font-size:0.8em;" wicket:id="repositorySize">[repository size]</span>
 				</div>
         
-				<div class="hidden-phone hidden-tablet" wicket:id="repositoryCloneUrl">[repository clone url]</div>
+				<div class="hidden-phone hidden-tablet" style="padding-top: 5px;" wicket:id="repositoryPrimaryUrl">[repository primary url]</div>
 			</div>
 		</div>
 	</div>
diff --git a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
index f2b56e1..822a9b2 100644
--- a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
+++ b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
@@ -29,6 +29,7 @@
 import org.apache.wicket.markup.html.link.Link;
 import org.apache.wicket.markup.html.panel.Fragment;
 
+import com.gitblit.Constants.AccessPermission;
 import com.gitblit.Constants.AccessRestrictionType;
 import com.gitblit.GitBlit;
 import com.gitblit.Keys;
@@ -221,9 +222,10 @@
 			// add the Gitblit repository url
 			repositoryUrls.add(BasePage.getRepositoryUrl(entry));
 		}
-		repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(entry.name, user == null ? "" : user.username));
+		repositoryUrls.addAll(GitBlit.self().getOtherCloneUrls(entry.name, UserModel.ANONYMOUS.equals(user) ? "" : user.username));
 
+		AccessPermission ap = user.getRepositoryPermission(entry).permission;
 		String primaryUrl = ArrayUtils.isEmpty(repositoryUrls) ? "" : repositoryUrls.remove(0);
-		add(new RepositoryUrlPanel("repositoryCloneUrl", primaryUrl));
+		add(new DetailedRepositoryUrlPanel("repositoryPrimaryUrl",localizer, parent, entry.name, primaryUrl, ap));
 	}
 }
diff --git a/src/main/resources/gitblit.css b/src/main/resources/gitblit.css
index 811b08a..c93f6a6 100644
--- a/src/main/resources/gitblit.css
+++ b/src/main/resources/gitblit.css
@@ -179,6 +179,30 @@
 	vertical-align: middle;
 }
 
+span.repositoryUrlContainer {
+	color: black;
+	background-color: #eee; 
+	padding: 4px;
+	border: 1px solid #ccc;
+	border-radius: 3px 
+}
+
+span.repositoryUrlEndCap {	
+	padding: 4px;
+	font-weight: bold;
+	font-size: 0.85em;
+	font-family:menlo,consolas,monospace;
+}
+
+span.repositoryUrl {
+	font-size: 1em;
+	padding: 4px;
+	color: blue;
+	background-color: #fff;
+	border-left: 1px solid #ccc;
+	border-right: 1px solid #ccc;
+}
+
 div.odd {
 	
 }

--
Gitblit v1.9.1