]> source.dussan.org Git - gitblit.git/commitdiff
allow advertising gitblit privileges for external URLs 281/head
authorJoel Johnson <mrjoel@lixil.net>
Mon, 29 Jun 2015 23:13:19 +0000 (17:13 -0600)
committerJoel Johnson <mrjoel@lixil.net>
Wed, 1 Jul 2015 19:05:50 +0000 (13:05 -0600)
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.

src/main/distrib/data/defaults.properties
src/main/java/com/gitblit/manager/ServicesManager.java
src/main/java/com/gitblit/models/RepositoryUrl.java
src/main/java/com/gitblit/wicket/pages/TicketPage.java
src/main/java/com/gitblit/wicket/panels/RepositoryUrlPanel.java

index 60c914ba7194b79b1ebb0dcf2c3255b8dba97296..d4ebcc394364bed106941282e183a77f0053d5a1 100644 (file)
@@ -1203,6 +1203,20 @@ web.showGitDaemonUrls = true
 # 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
index c911f31a4ab8f1a5f1aa448dd618708746cba986..b993eb66b21768d4dbf621672640c40fa62dd8d1 100644 (file)
@@ -211,16 +211,35 @@ public class ServicesManager implements IServicesManager {
                // 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
@@ -228,13 +247,13 @@ public class ServicesManager implements IServicesManager {
 
                        @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)) {
index d155dbda2ef7e3856bc5b66fae73c9b1ed3f1e33..13f69175bb4f0c6b00ae9239a6be481cbfedca3e 100644 (file)
@@ -41,8 +41,8 @@ public class RepositoryUrl implements Serializable {
                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
index 1aa89540dd33983d4078907d240d64c1910d1f8e..2dbc8e9d27b35c13c62436f7da52a6367eb92143 100644 (file)
@@ -752,7 +752,7 @@ public class TicketPage extends RepositoryPage {
                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
index 0666fcd8c6f65950906eb8a25b3acd8cdf25c20f..207f125089f10d38a4dbeb8e979a28fcec7019ae 100644 (file)
@@ -84,7 +84,7 @@ public class RepositoryUrlPanel extends BasePanel {
                // 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
@@ -145,7 +145,7 @@ public class RepositoryUrlPanel extends BasePanel {
                                        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
@@ -201,7 +201,7 @@ public class RepositoryUrlPanel extends BasePanel {
 \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
@@ -234,8 +234,8 @@ public class RepositoryUrlPanel extends BasePanel {
                                // 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
@@ -339,7 +339,7 @@ public class RepositoryUrlPanel extends BasePanel {
        }\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
@@ -369,18 +369,7 @@ public class RepositoryUrlPanel extends BasePanel {
                        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
@@ -411,6 +400,17 @@ public class RepositoryUrlPanel extends BasePanel {
                                        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