From 828add77e71a567be98490403bb92d6f1afb9930 Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 9 May 2013 22:43:57 -0400 Subject: Implemented application menus for repository url panel --- src/main/java/com/gitblit/GitBlit.java | 110 ++++- src/main/java/com/gitblit/git/GitDaemon.java | 14 + .../com/gitblit/models/GitClientApplication.java | 13 +- .../java/com/gitblit/models/RepositoryUrl.java | 49 ++ .../com/gitblit/wicket/GitBlitWebApp.properties | 7 +- src/main/java/com/gitblit/wicket/WicketUtils.java | 24 + .../java/com/gitblit/wicket/pages/BasePage.java | 59 --- .../gitblit/wicket/pages/EmptyRepositoryPage.java | 2 +- .../java/com/gitblit/wicket/pages/SummaryPage.html | 6 +- .../java/com/gitblit/wicket/pages/SummaryPage.java | 28 +- .../wicket/panels/DetailedRepositoryUrlPanel.html | 42 -- .../wicket/panels/DetailedRepositoryUrlPanel.java | 119 ----- .../wicket/panels/ProjectRepositoryPanel.html | 1 - .../wicket/panels/ProjectRepositoryPanel.java | 21 +- .../gitblit/wicket/panels/RepositoryUrlPanel.html | 81 +++- .../gitblit/wicket/panels/RepositoryUrlPanel.java | 506 ++++++++++++--------- 16 files changed, 542 insertions(+), 540 deletions(-) create mode 100644 src/main/java/com/gitblit/models/RepositoryUrl.java delete mode 100644 src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.html delete mode 100644 src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.java (limited to 'src/main/java/com/gitblit') diff --git a/src/main/java/com/gitblit/GitBlit.java b/src/main/java/com/gitblit/GitBlit.java index 42a1434b..9346e0ac 100644 --- a/src/main/java/com/gitblit/GitBlit.java +++ b/src/main/java/com/gitblit/GitBlit.java @@ -91,15 +91,16 @@ import com.gitblit.fanout.FanoutNioService; import com.gitblit.fanout.FanoutService; import com.gitblit.fanout.FanoutSocketService; import com.gitblit.git.GitDaemon; -import com.gitblit.models.GitClientApplication; import com.gitblit.models.FederationModel; import com.gitblit.models.FederationProposal; import com.gitblit.models.FederationSet; import com.gitblit.models.ForkModel; +import com.gitblit.models.GitClientApplication; import com.gitblit.models.Metric; import com.gitblit.models.ProjectModel; import com.gitblit.models.RegistrantAccessPermission; import com.gitblit.models.RepositoryModel; +import com.gitblit.models.RepositoryUrl; import com.gitblit.models.SearchResult; import com.gitblit.models.ServerSettings; import com.gitblit.models.ServerStatus; @@ -201,7 +202,7 @@ public class GitBlit implements ServletContextListener { private FanoutService fanoutService; private GitDaemon gitDaemon; - + public GitBlit() { if (gitblit == null) { // set the static singleton reference @@ -460,23 +461,106 @@ public class GitBlit implements ServletContextListener { serverStatus.heapFree = Runtime.getRuntime().freeMemory(); return serverStatus; } - + /** - * Returns the list of non-Gitblit clone urls. This allows Gitblit to - * advertise alternative urls for Git client repository access. + * Returns a list of repository URLs and the user access permission. * - * @param repositoryName - * @param userName - * @return list of non-gitblit clone urls + * @param request + * @param user + * @param repository + * @return a list of repository urls */ - public List getOtherCloneUrls(String repositoryName, String username) { - List cloneUrls = new ArrayList(); + public List getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) { + if (user == null) { + user = UserModel.ANONYMOUS; + } + String username = UserModel.ANONYMOUS.equals(user) ? "" : user.username; + + List list = new ArrayList(); + // http/https url + if (settings.getBoolean(Keys.git.enableGitServlet, true)) { + AccessPermission permission = user.getRepositoryPermission(repository).permission; + if (permission.exceeds(AccessPermission.NONE)) { + list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission)); + } + } + + // git daemon url + String gitDaemonUrl = getGitDaemonUrl(request, user, repository); + if (!StringUtils.isEmpty(gitDaemonUrl)) { + AccessPermission permission = getGitDaemonAccessPermission(user, repository); + if (permission.exceeds(AccessPermission.NONE)) { + list.add(new RepositoryUrl(gitDaemonUrl, permission)); + } + } + + // add all other urls + // {0} = repository + // {1} = username for (String url : settings.getStrings(Keys.web.otherUrls)) { - cloneUrls.add(MessageFormat.format(url, repositoryName, username)); + if (url.contains("{1}")) { + // external url requires username, only add url IF we have one + if(!StringUtils.isEmpty(username)) { + list.add(new RepositoryUrl(MessageFormat.format(url, repository.name, username), null)); + } + } else { + // external url does not require username + list.add(new RepositoryUrl(MessageFormat.format(url, repository.name), null)); + } } - return cloneUrls; + return list; } + protected String getRepositoryUrl(HttpServletRequest request, String username, RepositoryModel repository) { + StringBuilder sb = new StringBuilder(); + sb.append(HttpUtils.getGitblitURL(request)); + sb.append(Constants.GIT_PATH); + sb.append(repository.name); + + // inject username into repository url if authentication is required + if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE) + && !StringUtils.isEmpty(username)) { + sb.insert(sb.indexOf("://") + 3, username + "@"); + } + return sb.toString(); + } + + protected String getGitDaemonUrl(HttpServletRequest request, UserModel user, RepositoryModel repository) { + if (gitDaemon != null) { + String bindInterface = settings.getString(Keys.git.daemonBindInterface, "localhost"); + if (bindInterface.equals("localhost") + && (!request.getServerName().equals("localhost") && !request.getServerName().equals("127.0.0.1"))) { + // git daemon is bound to localhost and the request is from elsewhere + return null; + } + if (user.canClone(repository)) { + String servername = request.getServerName(); + String url = gitDaemon.formatUrl(servername, repository.name); + return url; + } + } + return null; + } + + protected AccessPermission getGitDaemonAccessPermission(UserModel user, RepositoryModel repository) { + if (gitDaemon != null && user.canClone(repository)) { + 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 + } + } + return gitDaemonPermission; + } + return AccessPermission.NONE; + } + /** * Returns the list of custom client applications to be used for the * repository url panel; @@ -3283,8 +3367,8 @@ public class GitBlit implements ServletContextListener { } protected void configureGitDaemon() { - String bindInterface = settings.getString(Keys.git.daemonBindInterface, "localhost"); int port = settings.getInteger(Keys.git.daemonPort, 0); + String bindInterface = settings.getString(Keys.git.daemonBindInterface, "localhost"); if (port > 0) { try { gitDaemon = new GitDaemon(bindInterface, port, getRepositoriesFolder()); diff --git a/src/main/java/com/gitblit/git/GitDaemon.java b/src/main/java/com/gitblit/git/GitDaemon.java index 7050f878..3c45171f 100644 --- a/src/main/java/com/gitblit/git/GitDaemon.java +++ b/src/main/java/com/gitblit/git/GitDaemon.java @@ -177,6 +177,20 @@ public class GitDaemon { } } }; } + + public int getPort() { + return myAddress.getPort(); + } + + public String formatUrl(String servername, String repository) { + if (getPort() == 9418) { + // standard port + return MessageFormat.format("git://{0}/{1}", servername, repository); + } else { + // non-standard port + return MessageFormat.format("git://{0}:{1,number,0}/{2}", servername, getPort(), repository); + } + } /** @return timeout (in seconds) before aborting an IO operation. */ public int getTimeout() { diff --git a/src/main/java/com/gitblit/models/GitClientApplication.java b/src/main/java/com/gitblit/models/GitClientApplication.java index dbdfa395..fd530593 100644 --- a/src/main/java/com/gitblit/models/GitClientApplication.java +++ b/src/main/java/com/gitblit/models/GitClientApplication.java @@ -31,13 +31,15 @@ public class GitClientApplication implements Serializable { private static final long serialVersionUID = 1L; public String name; + public String title; + public String description; + public String legal; + public String icon; public String cloneUrl; public String command; public String productUrl; - public String attribution; - public boolean isApplication = true; - public boolean isActive = true; public String[] platforms; + public boolean isActive; public boolean allowsPlatform(String p) { if (ArrayUtils.isEmpty(platforms)) { @@ -55,4 +57,9 @@ public class GitClientApplication implements Serializable { } return false; } + + @Override + public String toString() { + return StringUtils.isEmpty(title) ? name : title; + } } \ No newline at end of file diff --git a/src/main/java/com/gitblit/models/RepositoryUrl.java b/src/main/java/com/gitblit/models/RepositoryUrl.java new file mode 100644 index 00000000..d72959a2 --- /dev/null +++ b/src/main/java/com/gitblit/models/RepositoryUrl.java @@ -0,0 +1,49 @@ +/* + * 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.models; + +import java.io.Serializable; + +import com.gitblit.Constants.AccessPermission; + +/** + * Represents a git repository url and it's associated access permission for the + * current user. + * + * @author James Moger + * + */ +public class RepositoryUrl implements Serializable { + + private static final long serialVersionUID = 1L; + + public final String url; + public final AccessPermission permission; + + public RepositoryUrl(String url, AccessPermission permission) { + this.url = url; + this.permission = permission; + } + + public boolean isExternal() { + return permission == null; + } + + @Override + public String toString() { + return url; + } +} \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties index 9355b808..7ebea4eb 100644 --- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties @@ -449,8 +449,5 @@ 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 -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} -gb.cloneUrl = clone {0} -gb.visitSite = visit {0} website \ No newline at end of file +gb.externalPermissions = {0} access permissions are externally maintained +gb.viewAccess = You do not have Gitblit read or write access \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/WicketUtils.java b/src/main/java/com/gitblit/wicket/WicketUtils.java index 6e03032e..2170d0b7 100644 --- a/src/main/java/com/gitblit/wicket/WicketUtils.java +++ b/src/main/java/com/gitblit/wicket/WicketUtils.java @@ -41,6 +41,7 @@ import org.wicketstuff.googlecharts.AbstractChartData; import org.wicketstuff.googlecharts.IChartData; import com.gitblit.Constants; +import com.gitblit.Constants.AccessPermission; import com.gitblit.Constants.FederationPullStatus; import com.gitblit.GitBlit; import com.gitblit.Keys; @@ -107,6 +108,29 @@ public class WicketUtils { setCssClass(container, css); } } + + public static void setPermissionClass(Component container, AccessPermission permission) { + if (permission == null) { + setCssClass(container, "badge"); + return; + } + switch (permission) { + case REWIND: + case DELETE: + case CREATE: + setCssClass(container, "badge badge-success"); + break; + case PUSH: + setCssClass(container, "badge badge-info"); + break; + case CLONE: + setCssClass(container, "badge badge-inverse"); + break; + default: + setCssClass(container, "badge"); + break; + } + } public static void setAlternatingBackground(Component c, int i) { String clazz = i % 2 == 0 ? "light" : "dark"; diff --git a/src/main/java/com/gitblit/wicket/pages/BasePage.java b/src/main/java/com/gitblit/wicket/pages/BasePage.java index 19fa7493..ca3ea908 100644 --- a/src/main/java/com/gitblit/wicket/pages/BasePage.java +++ b/src/main/java/com/gitblit/wicket/pages/BasePage.java @@ -32,11 +32,9 @@ import java.util.regex.Pattern; 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; -import org.apache.wicket.RequestCycle; import org.apache.wicket.RestartResponseException; import org.apache.wicket.markup.html.CSSPackageResource; import org.apache.wicket.markup.html.basic.Label; @@ -45,7 +43,6 @@ import org.apache.wicket.markup.html.link.ExternalLink; 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; @@ -58,14 +55,12 @@ import com.gitblit.Constants.FederationStrategy; import com.gitblit.GitBlit; import com.gitblit.Keys; import com.gitblit.models.ProjectModel; -import com.gitblit.models.RepositoryModel; import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; import com.gitblit.utils.StringUtils; 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 { @@ -258,60 +253,6 @@ public abstract class BasePage extends SessionPage { return req.getServerName(); } - public static String getRepositoryUrl(RepositoryModel repository) { - StringBuilder sb = new StringBuilder(); - sb.append(WicketUtils.getGitblitURL(RequestCycle.get().getRequest())); - sb.append(Constants.GIT_PATH); - sb.append(repository.name); - - // inject username into repository url if authentication is required - if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE) - && GitBlitWebSession.get().isLoggedIn()) { - String username = GitBlitWebSession.get().getUsername(); - sb.insert(sb.indexOf("://") + 3, username + "@"); - } - 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 getProjectModels() { final UserModel user = GitBlitWebSession.get().getUser(); List 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 f7e88489..f7042030 100644 --- a/src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java +++ b/src/main/java/com/gitblit/wicket/pages/EmptyRepositoryPage.java @@ -53,7 +53,7 @@ public class EmptyRepositoryPage extends RootPage { user = UserModel.ANONYMOUS; } - RepositoryUrlPanel urlPanel = new RepositoryUrlPanel("pushurl", false, user, repository, getLocalizer(), this); + RepositoryUrlPanel urlPanel = new RepositoryUrlPanel("pushurl", false, user, repository); String primaryUrl = urlPanel.getPrimaryUrl(); add(new Label("repository", repositoryName)); diff --git a/src/main/java/com/gitblit/wicket/pages/SummaryPage.html b/src/main/java/com/gitblit/wicket/pages/SummaryPage.html index 1527436f..78c8f4df 100644 --- a/src/main/java/com/gitblit/wicket/pages/SummaryPage.html +++ b/src/main/java/com/gitblit/wicket/pages/SummaryPage.html @@ -19,10 +19,8 @@ [owner] [last change][repository last change] [stats][branch stats] [metrics] - [URL]  - -
[repository url panel]
- + [URL] +
[repository url panel]
diff --git a/src/main/java/com/gitblit/wicket/pages/SummaryPage.java b/src/main/java/com/gitblit/wicket/pages/SummaryPage.java index 54445f8e..321dff3d 100644 --- a/src/main/java/com/gitblit/wicket/pages/SummaryPage.java +++ b/src/main/java/com/gitblit/wicket/pages/SummaryPage.java @@ -42,7 +42,6 @@ import org.wicketstuff.googlecharts.LineStyle; import org.wicketstuff.googlecharts.MarkerType; import org.wicketstuff.googlecharts.ShapeMarker; -import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.GitBlit; import com.gitblit.Keys; import com.gitblit.models.Metric; @@ -124,32 +123,7 @@ public class SummaryPage extends RepositoryPage { add(new BookmarkablePageLink("metrics", MetricsPage.class, WicketUtils.newRepositoryParameter(repositoryName))); - if (GitBlit.getBoolean(Keys.git.enableGitServlet, true)) { - AccessRestrictionType accessRestriction = getRepositoryModel().accessRestriction; - switch (accessRestriction) { - case NONE: - add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); - break; - case PUSH: - add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", - getAccessRestrictions().get(accessRestriction))); - break; - case CLONE: - add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", - getAccessRestrictions().get(accessRestriction))); - break; - case VIEW: - add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", - getAccessRestrictions().get(accessRestriction))); - break; - default: - add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); - } - } else { - add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); - } - - add(new RepositoryUrlPanel("repositoryUrlPanel", false, user, model, getLocalizer(), this)); + add(new RepositoryUrlPanel("repositoryUrlPanel", false, user, model)); 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 deleted file mode 100644 index e671435b..00000000 --- a/src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - [protocol] - - [repository url] - - - [repository url permission] - - - - - - - - - - - - - - - - \ 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 deleted file mode 100644 index 92c51e41..00000000 --- a/src/main/java/com/gitblit/wicket/panels/DetailedRepositoryUrlPanel.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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); - Label protocolLabel = new Label("repositoryProtocol", protocol + "://"); - WicketUtils.setHtmlTooltip(protocolLabel, note); - fragment.add(protocolLabel); - fragment.add(new Label("repositoryUrl", url.substring(url.indexOf("://") + 3))); - Label permissionLabel = new Label("repositoryUrlPermission", permission); - WicketUtils.setHtmlTooltip(permissionLabel, note); - fragment.add(permissionLabel); - - 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("{0}", 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 e67e6416..e9196cda 100644 --- a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.html +++ b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.html @@ -59,7 +59,6 @@
[repository name] -
[origin repository] diff --git a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java index 7cce74f7..e7fe017e 100644 --- a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java +++ b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java @@ -103,25 +103,6 @@ public class ProjectRepositoryPanel extends BasePanel { } else { add(WicketUtils.newClearPixel("federatedIcon").setVisible(false)); } - switch (entry.accessRestriction) { - case NONE: - add(WicketUtils.newBlankImage("accessRestrictionIcon").setVisible(false)); - break; - case PUSH: - add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", - accessRestrictions.get(entry.accessRestriction))); - break; - case CLONE: - add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", - accessRestrictions.get(entry.accessRestriction))); - break; - case VIEW: - add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", - accessRestrictions.get(entry.accessRestriction))); - break; - default: - add(WicketUtils.newBlankImage("accessRestrictionIcon")); - } if (ArrayUtils.isEmpty(entry.owners)) { add(new Label("repositoryOwner").setVisible(false)); @@ -212,6 +193,6 @@ public class ProjectRepositoryPanel extends BasePanel { add(new ExternalLink("syndication", SyndicationServlet.asLink("", entry.name, null, 0))); - add(new RepositoryUrlPanel("repositoryPrimaryUrl", true, user, entry, localizer, parent)); + add(new RepositoryUrlPanel("repositoryPrimaryUrl", true, user, entry)); } } diff --git a/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.html b/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.html index 675ebb58..b22aa714 100644 --- a/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.html +++ b/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.html @@ -5,33 +5,66 @@ lang="en"> -
[repository primary url]
-
-
- - - - - - +
+
+ - - + + + URLs + + + - - - + + + diff --git a/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java b/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java index 9640ab00..00c7cf7a 100644 --- a/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java +++ b/src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java @@ -15,13 +15,15 @@ */ package com.gitblit.wicket.panels; -import java.io.Serializable; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; import org.apache.wicket.Component; -import org.apache.wicket.Localizer; import org.apache.wicket.RequestCycle; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.image.ContextImage; @@ -32,7 +34,6 @@ import org.apache.wicket.markup.repeater.data.ListDataProvider; import org.apache.wicket.protocol.http.WebRequest; import org.apache.wicket.protocol.http.request.WebClientInfo; -import com.gitblit.Constants; import com.gitblit.Constants.AccessPermission; import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.GitBlit; @@ -40,6 +41,7 @@ import com.gitblit.Keys; import com.gitblit.SparkleShareInviteServlet; import com.gitblit.models.GitClientApplication; import com.gitblit.models.RepositoryModel; +import com.gitblit.models.RepositoryUrl; import com.gitblit.models.UserModel; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.GitBlitWebSession; @@ -55,260 +57,314 @@ import com.gitblit.wicket.WicketUtils; public class RepositoryUrlPanel extends BasePanel { private static final long serialVersionUID = 1L; - - private final RepoUrl primaryUrl; - public RepositoryUrlPanel(String wicketId, boolean onlyPrimary, UserModel user, - final RepositoryModel repository, Localizer localizer, Component owner) { + private final String externalPermission = "?"; + + private boolean onlyUrls; + private UserModel user; + private RepositoryModel repository; + private RepositoryUrl primaryUrl; + private Map urlPermissionsMap; + private Map accessRestrictionsMap; + + public RepositoryUrlPanel(String wicketId, boolean onlyUrls, UserModel user, RepositoryModel repository) { super(wicketId); - if (user == null) { - user = UserModel.ANONYMOUS; - } - List repositoryUrls = new ArrayList(); + this.onlyUrls = onlyUrls; + this.user = user == null ? UserModel.ANONYMOUS : user; + this.repository = repository; + this.urlPermissionsMap = new HashMap(); + } + + @Override + protected void onInitialize() { + super.onInitialize(); - // http/https url - if (GitBlit.getBoolean(Keys.git.enableGitServlet, true)) { - AccessPermission permission = user.getRepositoryPermission(repository).permission; - if (permission.exceeds(AccessPermission.NONE)) { - repositoryUrls.add(new RepoUrl(getRepositoryUrl(repository), permission)); - } - } - - // git daemon url - String gitDaemonUrl = getGitDaemonUrl(user, repository); - if (!StringUtils.isEmpty(gitDaemonUrl)) { - AccessPermission permission = getGitDaemonAccessPermission(user, repository); - if (permission.exceeds(AccessPermission.NONE)) { - repositoryUrls.add(new RepoUrl(gitDaemonUrl, permission)); - } - } - - // add all other urls - for (String url : GitBlit.self().getOtherCloneUrls(repository.name, UserModel.ANONYMOUS.equals(user) ? "" : user.username)) { - repositoryUrls.add(new RepoUrl(url, null)); - } - + HttpServletRequest req = ((WebRequest) getRequest()).getHttpServletRequest(); + + List repositoryUrls = GitBlit.self().getRepositoryUrls(req, user, repository); // grab primary url from the top of the list primaryUrl = repositoryUrls.size() == 0 ? null : repositoryUrls.get(0); - add(new DetailedRepositoryUrlPanel("repositoryPrimaryUrl", localizer, owner, - repository.name, primaryUrl == null ? "" : primaryUrl.url, - primaryUrl == null ? null : primaryUrl.permission)); - - if (onlyPrimary) { - // only displaying the primary url - add(new Label("urlMenus").setVisible(false)); + boolean canClone = ((primaryUrl.permission == null) || primaryUrl.permission.atLeast(AccessPermission.CLONE)); + + if (repositoryUrls.size() == 0 || !canClone) { + // no urls, nothing to show. + add(new Label("repositoryUrlPanel").setVisible(false)); + add(new Label("applicationMenusPanel").setVisible(false)); return; } - final String clonePattern = localizer.getString("gb.cloneUrl", owner); - final String visitSitePattern = localizer.getString("gb.visitSite", owner); - - GitClientApplication URLS = new GitClientApplication(); - URLS.name = "URLs"; - URLS.command = "{0}"; - URLS.attribution = "Repository URLs"; - URLS.isApplication = false; - URLS.isActive = true; + // display primary url + add(createPrimaryUrlPanel("repositoryUrlPanel", repository, repositoryUrls)); + + boolean allowAppLinks = GitBlit.getBoolean(Keys.web.allowAppCloneLinks, true); + if (onlyUrls || !canClone || !allowAppLinks) { + // only display the url(s) + add(new Label("applicationMenusPanel").setVisible(false)); + return; + } + // create the git client application menus + add(createApplicationMenus("applicationMenusPanel", user, repository, repositoryUrls)); + } + + public String getPrimaryUrl() { + return primaryUrl == null ? "" : primaryUrl.url; + } + + protected Fragment createPrimaryUrlPanel(String wicketId, final RepositoryModel repository, List repositoryUrls) { + + Fragment urlPanel = new Fragment(wicketId, "repositoryUrlFragment", this); + urlPanel.setRenderBodyOnly(true); - GitClientApplication GIT = new GitClientApplication(); - GIT.name = "Git"; - GIT.command = "git clone {0}"; - GIT.productUrl = "http://git-scm.org"; - GIT.attribution = "Git Syntax"; - GIT.isApplication = false; - GIT.isActive = true; + if (repositoryUrls.size() == 1) { + // + // Single repository url, no dropdown menu + // + urlPanel.add(new Label("menu").setVisible(false)); + } else { + // + // Multiple repository urls, show url drop down menu + // + ListDataProvider urlsDp = new ListDataProvider(repositoryUrls); + DataView repoUrlMenuItems = new DataView("repoUrls", urlsDp) { + private static final long serialVersionUID = 1L; + + public void populateItem(final Item item) { + RepositoryUrl repoUrl = item.getModelObject(); + // repository url + Fragment fragment = new Fragment("repoUrl", "actionFragment", this); + Component content = new Label("content", repoUrl.url).setRenderBodyOnly(true); + WicketUtils.setCssClass(content, "commandMenuItem"); + fragment.add(content); + item.add(fragment); + + Label permissionLabel = new Label("permission", repoUrl.isExternal() ? externalPermission : repoUrl.permission.toString()); + WicketUtils.setPermissionClass(permissionLabel, repoUrl.permission); + String tooltip = getProtocolPermissionDescription(repository, repoUrl); + WicketUtils.setHtmlTooltip(permissionLabel, tooltip); + fragment.add(permissionLabel); + fragment.add(createCopyFragment(repoUrl.url)); + } + }; + + Fragment urlMenuFragment = new Fragment("menu", "urlProtocolMenuFragment", this); + urlMenuFragment.setRenderBodyOnly(true); + urlMenuFragment.add(new Label("menuText", getString("gb.url"))); + urlMenuFragment.add(repoUrlMenuItems); + urlPanel.add(urlMenuFragment); + } + + // access restriction icon and tooltip + if (isGitblitServingRepositories()) { + switch (repository.accessRestriction) { + case NONE: + urlPanel.add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); + break; + case PUSH: + urlPanel.add(WicketUtils.newImage("accessRestrictionIcon", "lock_go_16x16.png", + getAccessRestrictions().get(repository.accessRestriction))); + break; + case CLONE: + urlPanel.add(WicketUtils.newImage("accessRestrictionIcon", "lock_pull_16x16.png", + getAccessRestrictions().get(repository.accessRestriction))); + break; + case VIEW: + urlPanel.add(WicketUtils.newImage("accessRestrictionIcon", "shield_16x16.png", + getAccessRestrictions().get(repository.accessRestriction))); + break; + default: + urlPanel.add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); + } + } else { + urlPanel.add(WicketUtils.newClearPixel("accessRestrictionIcon").setVisible(false)); + } - final List clientApps = new ArrayList(); - clientApps.add(URLS); - clientApps.add(GIT); + urlPanel.add(new Label("primaryUrl", primaryUrl.url).setRenderBodyOnly(true)); + + Label permissionLabel = new Label("primaryUrlPermission", primaryUrl.isExternal() ? externalPermission : primaryUrl.permission.toString()); + String tooltip = getProtocolPermissionDescription(repository, primaryUrl); + WicketUtils.setHtmlTooltip(permissionLabel, tooltip); + urlPanel.add(permissionLabel); + urlPanel.add(createCopyFragment(primaryUrl.url)); + return urlPanel; + } + + protected Fragment createApplicationMenus(String wicketId, UserModel user, final RepositoryModel repository, List repositoryUrls) { + final List displayedApps = new ArrayList(); final String userAgent = ((WebClientInfo) GitBlitWebSession.get().getClientInfo()).getUserAgent(); - boolean allowAppLinks = GitBlit.getBoolean(Keys.web.allowAppCloneLinks, true); + if (user.canClone(repository)) { for (GitClientApplication app : GitBlit.self().getClientApplications()) { - if (app.isActive && app.allowsPlatform(userAgent) && (!app.isApplication || (app.isApplication && allowAppLinks))) { - clientApps.add(app); + if (app.isActive && app.allowsPlatform(userAgent)) { + displayedApps.add(app); } } - // sparkleshare invite url - String sparkleshareUrl = getSparkleShareInviteUrl(user, repository); - if (!StringUtils.isEmpty(sparkleshareUrl) && allowAppLinks) { - GitClientApplication link = new GitClientApplication(); - link.name = "SparkleShare"; - link.cloneUrl = sparkleshareUrl; - link.attribution = "SparkleShare\u2122"; - link.platforms = new String [] { "windows", "macintosh", "linux" }; - link.productUrl = "http://sparkleshare.org"; - link.isApplication = true; - link.isActive = true; - clientApps.add(link); + GitClientApplication sparkleshare = getSparkleShareAppMenu(user, repository); + if (sparkleshare != null) { + displayedApps.add(sparkleshare); } } - - final ListDataProvider repoUrls = new ListDataProvider(repositoryUrls); - // app clone links - ListDataProvider appLinks = new ListDataProvider(clientApps); - DataView urlMenus = new DataView("urlMenus", appLinks) { + final ListDataProvider urlsDp = new ListDataProvider(repositoryUrls); + ListDataProvider displayedAppsDp = new ListDataProvider(displayedApps); + DataView appMenus = new DataView("appMenus", displayedAppsDp) { private static final long serialVersionUID = 1L; - + public void populateItem(final Item item) { - final GitClientApplication cloneLink = item.getModelObject(); - item.add(new Label("productName", cloneLink.name)); + final GitClientApplication clientApp = item.getModelObject(); + + // menu button + item.add(new Label("applicationName", clientApp.name)); + + // application icon + Component img; + if (StringUtils.isEmpty(clientApp.icon)) { + img = WicketUtils.newClearPixel("applicationIcon").setVisible(false); + } else { + img = WicketUtils.newImage("applicationIcon", clientApp.icon); + } + item.add(img); + + // application menu title, may be a link + if (StringUtils.isEmpty(clientApp.productUrl)) { + item.add(new Label("applicationTitle", clientApp.toString())); + } else { + item.add(new LinkPanel("applicationTitle", null, clientApp.toString(), clientApp.productUrl, true)); + } + + // brief application description + if (StringUtils.isEmpty(clientApp.description)) { + item.add(new Label("applicationDescription").setVisible(false)); + } else { + item.add(new Label("applicationDescription", clientApp.description)); + } + + // brief application legal info, copyright, license, etc + if (StringUtils.isEmpty(clientApp.legal)) { + item.add(new Label("applicationLegal").setVisible(false)); + } else { + item.add(new Label("applicationLegal", clientApp.legal)); + } - // a nested repeater for all repo links - DataView repoLinks = new DataView("repoLinks", repoUrls) { + // a nested repeater for all action items + DataView actionItems = new DataView("actionItems", urlsDp) { private static final long serialVersionUID = 1L; - public void populateItem(final Item repoLinkItem) { - RepoUrl repoUrl = repoLinkItem.getModelObject(); - if (!StringUtils.isEmpty(cloneLink.cloneUrl)) { + public void populateItem(final Item repoLinkItem) { + RepositoryUrl repoUrl = repoLinkItem.getModelObject(); + + Fragment fragment = new Fragment("actionItem", "actionFragment", this); + fragment.add(createPermissionBadge("permission", repoUrl)); + + if (!StringUtils.isEmpty(clientApp.cloneUrl)) { // custom registered url - Fragment fragment = new Fragment("repoLink", "linkFragment", this); - String name; - if (repoUrl.permission != null) { - name = MessageFormat.format("{0} ({1})", repoUrl.url, repoUrl.permission); - } else { - name = repoUrl.url; - } - String url = MessageFormat.format(cloneLink.cloneUrl, repoUrl); - fragment.add(new LinkPanel("content", null, MessageFormat.format(clonePattern, name), url)); + String url = MessageFormat.format(clientApp.cloneUrl, repoUrl); + fragment.add(new LinkPanel("content", "applicationMenuItem", getString("gb.clone") + " " + repoUrl.url, url)); repoLinkItem.add(fragment); - String tooltip = getProtocolPermissionDescription(repository, repoUrl); - WicketUtils.setHtmlTooltip(fragment, tooltip); - } else if (!StringUtils.isEmpty(cloneLink.command)) { + fragment.add(new Label("copyFunction").setVisible(false)); + } else if (!StringUtils.isEmpty(clientApp.command)) { // command-line - Fragment fragment = new Fragment("repoLink", "commandFragment", this); - WicketUtils.setCssClass(fragment, "repositoryUrlMenuItem"); - String command = MessageFormat.format(cloneLink.command, repoUrl); - fragment.add(new Label("content", command)); + String command = MessageFormat.format(clientApp.command, repoUrl); + Label content = new Label("content", command); + WicketUtils.setCssClass(content, "commandMenuItem"); + fragment.add(content); repoLinkItem.add(fragment); - String tooltip = getProtocolPermissionDescription(repository, repoUrl); - WicketUtils.setHtmlTooltip(fragment, tooltip); // copy function for command - 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(command)); - 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)", command)); - copyFragment.add(img); - fragment.add(copyFragment); - } + fragment.add(createCopyFragment(command)); } }}; - item.add(repoLinks); - - item.add(new Label("productAttribution", cloneLink.attribution)); - if (!StringUtils.isEmpty(cloneLink.productUrl)) { - LinkPanel productlinkPanel = new LinkPanel("productLink", null, - MessageFormat.format(visitSitePattern, cloneLink.name), cloneLink.productUrl, true); - item.add(productlinkPanel); - } else { - item.add(new Label("productLink").setVisible(false)); - } + item.add(actionItems); } }; - add(urlMenus); - } - - public String getPrimaryUrl() { - return primaryUrl == null ? "" : primaryUrl.url; - } - - protected String getRepositoryUrl(RepositoryModel repository) { - StringBuilder sb = new StringBuilder(); - sb.append(WicketUtils.getGitblitURL(RequestCycle.get().getRequest())); - sb.append(Constants.GIT_PATH); - sb.append(repository.name); - // inject username into repository url if authentication is required - if (repository.accessRestriction.exceeds(AccessRestrictionType.NONE) - && GitBlitWebSession.get().isLoggedIn()) { - String username = GitBlitWebSession.get().getUsername(); - sb.insert(sb.indexOf("://") + 3, username + "@"); - } - return sb.toString(); - } - - protected String getGitDaemonUrl(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); - } - return gitDaemonUrl; - } - return null; + Fragment applicationMenus = new Fragment(wicketId, "applicationMenusFragment", this); + applicationMenus.add(appMenus); + return applicationMenus; } - protected AccessPermission getGitDaemonAccessPermission(UserModel user, RepositoryModel repository) { - int gitDaemonPort = GitBlit.getInteger(Keys.git.daemonPort, 0); - if (gitDaemonPort > 0 && user.canClone(repository)) { - 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 - } - } - return gitDaemonPermission; - } - return AccessPermission.NONE; - } - - protected String getSparkleShareInviteUrl(UserModel user, RepositoryModel repository) { + protected GitClientApplication getSparkleShareAppMenu(UserModel user, RepositoryModel repository) { + String url = null; if (repository.isBare && repository.isSparkleshared()) { String username = null; if (UserModel.ANONYMOUS != user) { username = user.username; } - if (GitBlit.getBoolean(Keys.git.enableGitServlet, true) || (GitBlit.getInteger(Keys.git.daemonPort, 0) > 0)) { + if (isGitblitServingRepositories()) { // Gitblit as server // ensure user can rewind if (user.canRewindRef(repository)) { String baseURL = WicketUtils.getGitblitURL(RequestCycle.get().getRequest()); - return SparkleShareInviteServlet.asLink(baseURL, repository.name, username); + url = SparkleShareInviteServlet.asLink(baseURL, repository.name, username); } } else { // Gitblit as viewer, assume RW+ permission String baseURL = WicketUtils.getGitblitURL(RequestCycle.get().getRequest()); - return SparkleShareInviteServlet.asLink(baseURL, repository.name, username); + url = SparkleShareInviteServlet.asLink(baseURL, repository.name, username); } } + + // sparkleshare invite url + if (!StringUtils.isEmpty(url)) { + GitClientApplication app = new GitClientApplication(); + app.name = "SparkleShare"; + app.title = "SparkleShare\u2122"; + app.description = "an open source collaboration and sharing tool"; + app.legal = "released under the GPLv3 open source license"; + app.cloneUrl = url; + app.platforms = new String [] { "windows", "macintosh", "linux" }; + app.productUrl = "http://sparkleshare.org"; + app.icon = "star_32x32.png"; + app.isActive = true; + return app; + } return null; } - protected String getProtocolPermissionDescription(RepositoryModel repository, RepoUrl repoUrl) { - String protocol = repoUrl.url.substring(0, repoUrl.url.indexOf("://")); - String note; - if (repoUrl.permission == null) { - note = MessageFormat.format(getString("gb.externalPermissions"), protocol, repository.name); + protected boolean isGitblitServingRepositories() { + return GitBlit.getBoolean(Keys.git.enableGitServlet, true) || (GitBlit.getInteger(Keys.git.daemonPort, 0) > 0); + } + + protected Label createPermissionBadge(String wicketId, RepositoryUrl repoUrl) { + Label permissionLabel = new Label(wicketId, repoUrl.isExternal() ? externalPermission : repoUrl.permission.toString()); + WicketUtils.setPermissionClass(permissionLabel, repoUrl.permission); + String tooltip = getProtocolPermissionDescription(repository, repoUrl); + WicketUtils.setHtmlTooltip(permissionLabel, tooltip); + return permissionLabel; + } + + protected Fragment createCopyFragment(String text) { + 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(text)); + copyFragment.add(clippy); + return copyFragment; } else { - note = null; - String key; - switch (repoUrl.permission) { + // 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)", text)); + copyFragment.add(img); + return copyFragment; + } + } + + protected String getProtocolPermissionDescription(RepositoryModel repository, + RepositoryUrl repoUrl) { + if (!urlPermissionsMap.containsKey(repoUrl.url)) { + String note; + if (repoUrl.isExternal()) { + String protocol = repoUrl.url.substring(0, repoUrl.url.indexOf("://")); + note = MessageFormat.format(getString("gb.externalPermissions"), protocol); + } else { + note = null; + String key; + switch (repoUrl.permission) { case OWNER: case REWIND: key = "gb.rewindPermission"; @@ -329,33 +385,39 @@ public class RepositoryUrlPanel extends BasePanel { key = null; note = getString("gb.viewAccess"); break; + } + + if (note == null) { + String pattern = getString(key); + String description = MessageFormat.format(pattern, repoUrl.permission.toString()); + note = description; + } } - - if (note == null) { - String pattern = getString(key); - String description = MessageFormat.format(pattern, repoUrl.permission.toString()); - String permissionPattern = getString("gb.yourProtocolPermissionIs"); - note = MessageFormat.format(permissionPattern, protocol.toUpperCase(), repository, description); - } + urlPermissionsMap.put(repoUrl.url, note); } - return note; + return urlPermissionsMap.get(repoUrl.url); } - private class RepoUrl implements Serializable { - - private static final long serialVersionUID = 1L; - - final String url; - final AccessPermission permission; - - RepoUrl(String url, AccessPermission permission) { - this.url = url; - this.permission = permission; - } - - @Override - public String toString() { - return url; + protected Map getAccessRestrictions() { + if (accessRestrictionsMap == null) { + accessRestrictionsMap = new HashMap(); + for (AccessRestrictionType type : AccessRestrictionType.values()) { + switch (type) { + case NONE: + accessRestrictionsMap.put(type, getString("gb.notRestricted")); + break; + case PUSH: + accessRestrictionsMap.put(type, getString("gb.pushRestricted")); + break; + case CLONE: + accessRestrictionsMap.put(type, getString("gb.cloneRestricted")); + break; + case VIEW: + accessRestrictionsMap.put(type, getString("gb.viewRestricted")); + break; + } + } } + return accessRestrictionsMap; } } -- cgit v1.2.3