commit
c20191fc0931a19bec0df1ab2b56f287e5d8b7c7 enabled support
for hiding internal URLs, but didn't consider that it broke the
evaluation of permissions (used for tickets, etc.), and caused
a NPE on repoUrl.permission when trying to view the TicketPage.
With all internal mechanisms disabled, it would result in the
first URL being external with unknown permissions. This adds an
option to use internal permissions even for external URLs.
Note that this does not grant any additional permissions, but
does offer the option to have gitblit advertise the full set of
what is allowed, even if the external URL imposes additional
restrictions.
# SINCE 1.7.0
web.showSshDaemonUrls = true
+# Should effective permissions be advertised for access paths defined in web.otherUrls?
+# If false, gitblit will indicate unknown permissions for the external link. If true,
+# gitblit will indicate permissions as defined within gitblit (including limiting to clone
+# permission is the transport type is not a valid push mechaism in git.acceptedPushTransports).
+#
+# Configure with caution: Note that gitblit has no way of knowing if further restrictions
+# are imposed by an external forwarding agent, so this may cause user confusion due to
+# more rights being advertised than are available through the URL. It will NOT grant
+# additional rights, but may incorrectly offer actions that are unavailable externally.
+# default: false
+#
+# SINCE 1.7.0
+web.advertiseAccessPermissionForOtherUrls = false
+
# Should app-specific clone links be displayed for SourceTree, SparkleShare, etc?
#
# SINCE 1.3.0
// add all other urls
// {0} = repository
// {1} = username
+ boolean advertisePermsForOther = settings.getBoolean(Keys.web.advertiseAccessPermissionForOtherUrls, false);
for (String url : settings.getStrings(Keys.web.otherUrls)) {
+ String externalUrl = null;
+
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));
+ if (StringUtils.isEmpty(username)) {
+ continue;
+ } else {
+ externalUrl = MessageFormat.format(url, repository.name, username);
}
} else {
- // external url does not require username
- list.add(new RepositoryUrl(MessageFormat.format(url, repository.name), null));
+ // external url does not require username, just do repo name formatting
+ externalUrl = MessageFormat.format(url, repository.name);
+ }
+
+ AccessPermission permission = null;
+ if (advertisePermsForOther) {
+ permission = user.getRepositoryPermission(repository).permission;
+ if (permission.exceeds(AccessPermission.NONE)) {
+ Transport transport = Transport.fromUrl(externalUrl);
+ if (permission.atLeast(AccessPermission.PUSH) && !acceptsPush(transport)) {
+ // downgrade the repo permission for this transport
+ // because it is not an acceptable PUSH transport
+ permission = AccessPermission.CLONE;
+ }
+ }
}
+ list.add(new RepositoryUrl(externalUrl, permission));
}
// sort transports by highest permission and then by transport security
@Override
public int compare(RepositoryUrl o1, RepositoryUrl o2) {
- if (!o1.isExternal() && o2.isExternal()) {
- // prefer Gitblit over external
+ if (o1.hasPermission() && !o2.hasPermission()) {
+ // prefer known permission items over unknown
return -1;
- } else if (o1.isExternal() && !o2.isExternal()) {
- // prefer Gitblit over external
+ } else if (!o1.hasPermission() && o2.hasPermission()) {
+ // prefer known permission items over unknown
return 1;
- } else if (o1.isExternal() && o2.isExternal()) {
+ } else if (!o1.hasPermission() && !o2.hasPermission()) {
// sort by Transport ordinal
return o1.transport.compareTo(o2.transport);
} else if (o1.permission.exceeds(o2.permission)) {
this.permission = permission;\r
}\r
\r
- public boolean isExternal() {\r
- return permission == null;\r
+ public boolean hasPermission() {\r
+ return permission != null;\r
}\r
\r
@Override\r
if (currentPatchset == null) {\r
// no patchset available\r
RepositoryUrl repoUrl = getRepositoryUrl(user, repository);\r
- boolean canPropose = repoUrl != null && repoUrl.permission.atLeast(AccessPermission.CLONE) && !UserModel.ANONYMOUS.equals(user);\r
+ boolean canPropose = repoUrl != null && repoUrl.hasPermission() && repoUrl.permission.atLeast(AccessPermission.CLONE) && !UserModel.ANONYMOUS.equals(user);\r
if (ticket.isOpen() && app().tickets().isAcceptingNewPatchsets(repository) && canPropose) {\r
// ticket & repo will accept a proposal patchset\r
// show the instructions for proposing a patchset\r
// grab primary url from the top of the list\r
primaryUrl = repositoryUrls.size() == 0 ? null : repositoryUrls.get(0);\r
\r
- boolean canClone = primaryUrl != null && ((primaryUrl.permission == null) || primaryUrl.permission.atLeast(AccessPermission.CLONE));\r
+ boolean canClone = primaryUrl != null && (!primaryUrl.hasPermission() || primaryUrl.permission.atLeast(AccessPermission.CLONE));\r
\r
if (repositoryUrls.size() == 0 || !canClone) {\r
// no urls, nothing to show.\r
fragment.add(content);\r
item.add(fragment);\r
\r
- Label permissionLabel = new Label("permission", repoUrl.isExternal() ? externalPermission : repoUrl.permission.toString());\r
+ Label permissionLabel = new Label("permission", repoUrl.hasPermission() ? repoUrl.permission.toString() : externalPermission);\r
WicketUtils.setPermissionClass(permissionLabel, repoUrl.permission);\r
String tooltip = getProtocolPermissionDescription(repository, repoUrl);\r
WicketUtils.setHtmlTooltip(permissionLabel, tooltip);\r
\r
urlPanel.add(new Label("primaryUrl", primaryUrl.url).setRenderBodyOnly(true));\r
\r
- Label permissionLabel = new Label("primaryUrlPermission", primaryUrl.isExternal() ? externalPermission : primaryUrl.permission.toString());\r
+ Label permissionLabel = new Label("primaryUrlPermission", primaryUrl.hasPermission() ? primaryUrl.permission.toString() : externalPermission);\r
String tooltip = getProtocolPermissionDescription(repository, primaryUrl);\r
WicketUtils.setHtmlTooltip(permissionLabel, tooltip);\r
urlPanel.add(permissionLabel);\r
// filter the urls for the client app\r
List<RepositoryUrl> urls = new ArrayList<RepositoryUrl>();\r
for (RepositoryUrl repoUrl : repositoryUrls) {\r
- if (clientApp.minimumPermission == null || repoUrl.permission == null) {\r
- // no minimum permission or external permissions, assume it is satisfactory\r
+ if (clientApp.minimumPermission == null || !repoUrl.hasPermission()) {\r
+ // no minimum permission or untracked permissions, assume it is satisfactory\r
if (clientApp.supportsTransport(repoUrl.url)) {\r
urls.add(repoUrl);\r
}\r
}\r
\r
protected Label createPermissionBadge(String wicketId, RepositoryUrl repoUrl) {\r
- Label permissionLabel = new Label(wicketId, repoUrl.isExternal() ? externalPermission : repoUrl.permission.toString());\r
+ Label permissionLabel = new Label(wicketId, repoUrl.hasPermission() ? repoUrl.permission.toString() : externalPermission);\r
WicketUtils.setPermissionClass(permissionLabel, repoUrl.permission);\r
String tooltip = getProtocolPermissionDescription(repository, repoUrl);\r
WicketUtils.setHtmlTooltip(permissionLabel, tooltip);\r
RepositoryUrl repoUrl) {\r
if (!urlPermissionsMap.containsKey(repoUrl.url)) {\r
String note;\r
- if (repoUrl.isExternal()) {\r
- String protocol;\r
- int protocolIndex = repoUrl.url.indexOf("://");\r
- if (protocolIndex > -1) {\r
- // explicit protocol specified\r
- protocol = repoUrl.url.substring(0, protocolIndex);\r
- } else {\r
- // implicit SSH url\r
- protocol = "ssh";\r
- }\r
- note = MessageFormat.format(getString("gb.externalPermissions"), protocol);\r
- } else {\r
+ if (repoUrl.hasPermission()) {\r
note = null;\r
String key;\r
switch (repoUrl.permission) {\r
String description = MessageFormat.format(pattern, repoUrl.permission.toString());\r
note = description;\r
}\r
+ } else {\r
+ String protocol;\r
+ int protocolIndex = repoUrl.url.indexOf("://");\r
+ if (protocolIndex > -1) {\r
+ // explicit protocol specified\r
+ protocol = repoUrl.url.substring(0, protocolIndex);\r
+ } else {\r
+ // implicit SSH url\r
+ protocol = "ssh";\r
+ }\r
+ note = MessageFormat.format(getString("gb.externalPermissions"), protocol);\r
}\r
urlPermissionsMap.put(repoUrl.url, note);\r
}\r