]> source.dussan.org Git - gitblit.git/commitdiff
Improve transparency of permissions by indicating permission source
authorJames Moger <james.moger@gitblit.com>
Thu, 1 Nov 2012 03:16:24 +0000 (23:16 -0400)
committerJames Moger <james.moger@gitblit.com>
Thu, 1 Nov 2012 03:16:24 +0000 (23:16 -0400)
12 files changed:
src/com/gitblit/Constants.java
src/com/gitblit/GitBlit.java
src/com/gitblit/client/GitblitClient.java
src/com/gitblit/client/RegistrantPermissionsPanel.java
src/com/gitblit/client/RegistrantPermissionsTableModel.java
src/com/gitblit/models/RegistrantAccessPermission.java
src/com/gitblit/models/TeamModel.java
src/com/gitblit/models/UserModel.java
src/com/gitblit/wicket/GitBlitWebApp.properties
src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.html
src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java
tests/com/gitblit/tests/RpcTests.java

index e7812ee35cf7bc6f904e279bbca2e465c97e79a8..426d2df00056cbf337460224901e57d139d35c54 100644 (file)
@@ -387,7 +387,7 @@ public class Constants {
        }\r
        \r
        public static enum PermissionType {\r
-               EXPLICIT, OWNER, REGEX;\r
+               EXPLICIT, OWNER, ADMINISTRATOR, TEAM, REGEX;\r
        }\r
        \r
        public static enum GCStatus {\r
index 35451f622946de1da7fb15f2c8fa7102fb2c1280..a5d8b9e5c39c6af0894079fc80ba68ec2e9f35d1 100644 (file)
@@ -80,7 +80,6 @@ import com.gitblit.Constants.FederationRequest;
 import com.gitblit.Constants.FederationStrategy;\r
 import com.gitblit.Constants.FederationToken;\r
 import com.gitblit.Constants.PermissionType;\r
-import com.gitblit.Constants.RegistrantType;\r
 import com.gitblit.models.FederationModel;\r
 import com.gitblit.models.FederationProposal;\r
 import com.gitblit.models.FederationSet;\r
@@ -665,41 +664,22 @@ public class GitBlit implements ServletContextListener {
        }\r
 \r
        /**\r
-        * Returns the list of users and their access permissions for the specified repository.\r
+        * Returns the list of users and their access permissions for the specified\r
+        * repository including permission source information such as the team or\r
+        * regular expression which sets the permission.\r
         * \r
         * @param repository\r
-        * @return a list of User-AccessPermission tuples\r
+        * @return a list of RegistrantAccessPermissions\r
         */\r
        public List<RegistrantAccessPermission> getUserAccessPermissions(RepositoryModel repository) {\r
-               Set<RegistrantAccessPermission> permissions = new LinkedHashSet<RegistrantAccessPermission>();\r
-               if (!StringUtils.isEmpty(repository.owner)) {\r
-                       UserModel owner = userService.getUserModel(repository.owner);\r
-                       if (owner != null) {\r
-                               permissions.add(new RegistrantAccessPermission(owner.username, AccessPermission.REWIND, PermissionType.OWNER, RegistrantType.USER, false));\r
-                       }\r
-               }\r
-               if (repository.isPersonalRepository()) {\r
-                       UserModel owner = userService.getUserModel(repository.projectPath.substring(1));\r
-                       if (owner != null) {\r
-                               permissions.add(new RegistrantAccessPermission(owner.username, AccessPermission.REWIND, PermissionType.OWNER, RegistrantType.USER, false));\r
-                       }\r
-               }\r
-               for (String user : userService.getUsernamesForRepositoryRole(repository.name)) {\r
-                       UserModel model = userService.getUserModel(user);\r
-                       AccessPermission ap = model.getRepositoryPermission(repository);\r
-                       PermissionType pType = PermissionType.REGEX;\r
-                       boolean editable = false;\r
-                       if (repository.isOwner(model.username)) {\r
-                               pType = PermissionType.OWNER;\r
-                       } else if (repository.isUsersPersonalRepository(model.username)) {\r
-                               pType = PermissionType.OWNER;\r
-                       } else if (model.hasExplicitRepositoryPermission(repository.name)) {\r
-                               pType = PermissionType.EXPLICIT;\r
-                               editable = true;\r
-                       }                       \r
-                       permissions.add(new RegistrantAccessPermission(user, ap, pType, RegistrantType.USER, editable));\r
-               }\r
-               return new ArrayList<RegistrantAccessPermission>(permissions);\r
+               List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();            \r
+               for (UserModel user : userService.getAllUsers()) {\r
+                       RegistrantAccessPermission ap = user.getRepositoryPermission(repository);\r
+                       if (ap.permission.exceeds(AccessPermission.NONE)) {\r
+                               list.add(ap);\r
+                       }\r
+               }\r
+               return list;\r
        }\r
        \r
        /**\r
@@ -823,25 +803,23 @@ public class GitBlit implements ServletContextListener {
        }\r
        \r
        /**\r
-        * Returns the list of teams and their access permissions for the specified repository.\r
+        * Returns the list of teams and their access permissions for the specified\r
+        * repository including the source of the permission such as the admin flag\r
+        * or a regular expression.\r
         * \r
         * @param repository\r
-        * @return a list of Team-AccessPermission tuples\r
+        * @return a list of RegistrantAccessPermissions\r
         */\r
        public List<RegistrantAccessPermission> getTeamAccessPermissions(RepositoryModel repository) {\r
-               List<RegistrantAccessPermission> permissions = new ArrayList<RegistrantAccessPermission>();\r
-               for (String team : userService.getTeamnamesForRepositoryRole(repository.name)) {\r
-                       TeamModel model = userService.getTeamModel(team);\r
-                       AccessPermission ap = model.getRepositoryPermission(repository);\r
-                       PermissionType pType = PermissionType.REGEX;\r
-                       boolean editable = false;\r
-                       if (model.hasExplicitRepositoryPermission(repository.name)) {\r
-                               pType = PermissionType.EXPLICIT;\r
-                               editable = true;\r
-                       }\r
-                       permissions.add(new RegistrantAccessPermission(team, ap, pType, RegistrantType.TEAM, editable));\r
-               }\r
-               return permissions;\r
+               List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();\r
+               for (TeamModel team : userService.getAllTeams()) {\r
+                       RegistrantAccessPermission ap = team.getRepositoryPermission(repository);\r
+                       if (ap.permission.exceeds(AccessPermission.NONE)) {\r
+                               list.add(ap);\r
+                       }\r
+               }\r
+               Collections.sort(list);\r
+               return list;\r
        }\r
        \r
        /**\r
index b7047d7fbfaac6a9e7d7586436999dad9731be3d..56078fc3bb474a47a57dbb49eac6ba2299d864dc 100644 (file)
@@ -31,8 +31,6 @@ import com.gitblit.Constants;
 import com.gitblit.Constants.AccessPermission;\r
 import com.gitblit.Constants.AccessRestrictionType;\r
 import com.gitblit.Constants.AuthorizationControl;\r
-import com.gitblit.Constants.PermissionType;\r
-import com.gitblit.Constants.RegistrantType;\r
 import com.gitblit.GitBlitException.ForbiddenException;\r
 import com.gitblit.GitBlitException.NotAllowedException;\r
 import com.gitblit.GitBlitException.UnauthorizedException;\r
@@ -508,38 +506,15 @@ public class GitblitClient implements Serializable {
        }\r
        \r
        public List<RegistrantAccessPermission> getUserAccessPermissions(RepositoryModel repository) {\r
-               Set<RegistrantAccessPermission> list = new LinkedHashSet<RegistrantAccessPermission>();\r
-               if (!StringUtils.isEmpty(repository.owner)) {\r
-                       UserModel owner = getUser(repository.owner);\r
-                       if (owner != null) {\r
-                               list.add(new RegistrantAccessPermission(owner.username, AccessPermission.REWIND, PermissionType.OWNER, RegistrantType.USER, false));\r
-                       }\r
-               }\r
-               if (repository.isPersonalRepository()) {\r
-                       UserModel owner = getUser(repository.projectPath.substring(1));\r
-                       if (owner != null) {\r
-                               list.add(new RegistrantAccessPermission(owner.username, AccessPermission.REWIND, PermissionType.OWNER, RegistrantType.USER, false));\r
-                       }\r
-               }\r
+               List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();            \r
                for (UserModel user : getUsers()) {\r
-                       if (user.hasRepositoryPermission(repository.name)) {\r
-                               AccessPermission ap = user.getRepositoryPermission(repository);\r
-                               PermissionType pType = PermissionType.REGEX;\r
-                               boolean editable = false;\r
-                               if (repository.isOwner(user.username)) {\r
-                                       pType = PermissionType.OWNER;\r
-                               } else if (repository.isUsersPersonalRepository(user.username)) {\r
-                                       pType = PermissionType.OWNER;\r
-                               } else if (user.hasExplicitRepositoryPermission(repository.name)) {\r
-                                       pType = PermissionType.EXPLICIT;\r
-                                       editable = true;\r
-                               }                       \r
-                               list.add(new RegistrantAccessPermission(user.username, ap, pType, RegistrantType.USER, editable));\r
+                       RegistrantAccessPermission ap = user.getRepositoryPermission(repository);\r
+                       if (ap.permission.exceeds(AccessPermission.NONE)) {\r
+                               list.add(ap);\r
                        }\r
                }\r
-               List<RegistrantAccessPermission> raps = new ArrayList<RegistrantAccessPermission>(list);\r
-               Collections.sort(raps);\r
-               return raps;\r
+               Collections.sort(list);\r
+               return list;\r
        }\r
 \r
        public boolean setUserAccessPermissions(RepositoryModel repository, List<RegistrantAccessPermission> permissions) throws IOException {\r
@@ -572,15 +547,9 @@ public class GitblitClient implements Serializable {
        public List<RegistrantAccessPermission> getTeamAccessPermissions(RepositoryModel repository) {\r
                List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();\r
                for (TeamModel team : allTeams) {\r
-                       if (team.hasRepositoryPermission(repository.name)) {\r
-                               AccessPermission ap = team.getRepositoryPermission(repository);\r
-                               PermissionType pType = PermissionType.REGEX;\r
-                               boolean editable = false;\r
-                               if (team.hasExplicitRepositoryPermission(repository.name)) {\r
-                                       pType = PermissionType.EXPLICIT;\r
-                                       editable = true;\r
-                               }\r
-                               list.add(new RegistrantAccessPermission(team.name, ap, pType, RegistrantType.TEAM, editable));\r
+                       RegistrantAccessPermission ap = team.getRepositoryPermission(repository);\r
+                       if (ap.permission.exceeds(AccessPermission.NONE)) {\r
+                               list.add(ap);\r
                        }\r
                }\r
                Collections.sort(list);\r
index b8ab9399c1760894b01af631cf064982261ff88a..8ae23e9a51b5418fab9a4d922984f1251323c264 100644 (file)
@@ -19,6 +19,7 @@ import java.awt.BorderLayout;
 import java.awt.Dimension;\r
 import java.awt.event.ActionEvent;\r
 import java.awt.event.ActionListener;\r
+import java.text.MessageFormat;\r
 import java.util.ArrayList;\r
 import java.util.List;\r
 \r
@@ -136,6 +137,12 @@ public class RegistrantPermissionsPanel extends JPanel {
                                // only remove editable duplicates\r
                                // this allows for specifying an explicit permission\r
                                filtered.remove(rp.registrant);\r
+                       } else if (rp.isAdmin()) {\r
+                               // administrators can not have their permission changed\r
+                               filtered.remove(rp.registrant);\r
+                       } else if (rp.isOwner()) {\r
+                               // owners can not have their permission changed\r
+                               filtered.remove(rp.registrant);\r
                        }\r
                }\r
                for (String registrant : filtered) {\r
@@ -172,15 +179,23 @@ public class RegistrantPermissionsPanel extends JPanel {
 \r
                @Override\r
                protected void setValue(Object value) {\r
-                       PermissionType pType = (PermissionType) value;\r
-                       switch (pType) {\r
+                       RegistrantAccessPermission ap = (RegistrantAccessPermission) value;\r
+                       switch (ap.permissionType) {\r
+                       case ADMINISTRATOR:\r
+                               setText(ap.source == null ? Translation.get("gb.administrator") : ap.source);\r
+                               setToolTipText(Translation.get("gb.administratorPermission"));\r
+                               break;\r
                        case OWNER:\r
-                               setText("owner");\r
+                               setText(Translation.get("gb.owner"));\r
                                setToolTipText(Translation.get("gb.ownerPermission"));\r
                                break;\r
+                       case TEAM:\r
+                               setText(ap.source == null ? Translation.get("gb.team") : ap.source);\r
+                               setToolTipText(MessageFormat.format(Translation.get("gb.teamPermission"), ap.source));\r
+                               break;\r
                        case REGEX:\r
                                setText("regex");\r
-                               setToolTipText(Translation.get("gb.regexPermission"));\r
+                               setToolTipText(MessageFormat.format(Translation.get("gb.regexPermission"), ap.source));\r
                                break;\r
                        default:\r
                                setText("");\r
index 9ed8db4a9c972be42e4cca6c8dbb5adc3ae9cfa3..1df6bbc2644aee98b732e325bbdc0f700113bebb 100644 (file)
@@ -91,7 +91,7 @@ public class RegistrantPermissionsTableModel extends AbstractTableModel {
                if (columnIndex == Columns.Permission.ordinal()) {\r
                        return AccessPermission.class;\r
                } else if (columnIndex == Columns.Type.ordinal()) {\r
-                       return Boolean.class;\r
+                       return RegistrantAccessPermission.class;\r
                }\r
                return String.class;\r
        }\r
@@ -117,7 +117,7 @@ public class RegistrantPermissionsTableModel extends AbstractTableModel {
                case Registrant:\r
                        return rp.registrant;\r
                case Type:\r
-                       return rp.permissionType;\r
+                       return rp;\r
                case Permission:\r
                        return rp.permission;\r
                }\r
index 7346d310ab78abfd5906de7bb75ff078f0eb2f38..2d0b90b828a189a4cb5c02fef2543e57c3f864e6 100644 (file)
@@ -36,6 +36,10 @@ public class RegistrantAccessPermission implements Serializable, Comparable<Regi
        public RegistrantType registrantType;
        public PermissionType permissionType;
        public boolean isEditable;
+       public String source;
+       
+       public RegistrantAccessPermission() {
+       }
 
        public RegistrantAccessPermission(RegistrantType registrantType) {
                this.registrantType = registrantType;
@@ -43,14 +47,23 @@ public class RegistrantAccessPermission implements Serializable, Comparable<Regi
                this.isEditable = true;
        }
        
-       public RegistrantAccessPermission(String registrant, AccessPermission permission, PermissionType permissionType, RegistrantType registrantType, boolean isEditable) {
+       public RegistrantAccessPermission(String registrant, AccessPermission permission, PermissionType permissionType, RegistrantType registrantType, String source, boolean isEditable) {
                this.registrant = registrant;
                this.permission = permission;
                this.permissionType = permissionType;
                this.registrantType = registrantType;
+               this.source = source;
                this.isEditable = isEditable;
        }
        
+       public boolean isAdmin() {
+               return PermissionType.ADMINISTRATOR.equals(permissionType);
+       }
+
+       public boolean isOwner() {
+               return PermissionType.OWNER.equals(permissionType);
+       }
+
        @Override
        public int compareTo(RegistrantAccessPermission p) {
                switch (registrantType) {
index e5e3b097fc0369a9482cb092062ad83d775a00bd..acdb07540339d6ddcd6f35e5348a676d109bb1e0 100644 (file)
@@ -100,13 +100,15 @@ public class TeamModel implements Serializable, Comparable<TeamModel> {
                List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();\r
                for (Map.Entry<String, AccessPermission> entry : permissions.entrySet()) {\r
                        String registrant = entry.getKey();\r
+                       String source = null;\r
                        boolean editable = true;\r
                        PermissionType pType = PermissionType.EXPLICIT;\r
                        if (StringUtils.findInvalidCharacter(registrant) != null) {\r
                                // a regex will have at least 1 invalid character\r
                                pType = PermissionType.REGEX;\r
+                               source = registrant;\r
                        }\r
-                       list.add(new RegistrantAccessPermission(registrant, entry.getValue(), pType, RegistrantType.REPOSITORY, editable));\r
+                       list.add(new RegistrantAccessPermission(registrant, entry.getValue(), pType, RegistrantType.REPOSITORY, source, editable));\r
                }\r
                Collections.sort(list);\r
                return list;\r
@@ -184,13 +186,27 @@ public class TeamModel implements Serializable, Comparable<TeamModel> {
                repositories.add(repository.toLowerCase());\r
        }\r
        \r
-       public AccessPermission getRepositoryPermission(RepositoryModel repository) {\r
-               AccessPermission permission = AccessPermission.NONE;\r
+       public RegistrantAccessPermission getRepositoryPermission(RepositoryModel repository) {\r
+               RegistrantAccessPermission ap = new RegistrantAccessPermission();\r
+               ap.registrant = name;\r
+               ap.registrantType = RegistrantType.TEAM;\r
+               ap.permission = AccessPermission.NONE;\r
+               ap.isEditable = false;\r
+               \r
+               if (canAdmin) {\r
+                       ap.permissionType = PermissionType.ADMINISTRATOR;\r
+                       ap.permission = AccessPermission.REWIND;\r
+                       return ap;\r
+               }\r
+               \r
                if (permissions.containsKey(repository.name.toLowerCase())) {\r
                        // exact repository permission specified\r
                        AccessPermission p = permissions.get(repository.name.toLowerCase());\r
                        if (p != null) {\r
-                               permission = p;\r
+                               ap.permissionType = PermissionType.EXPLICIT;\r
+                               ap.permission = p;\r
+                               ap.isEditable = true;\r
+                               return ap;\r
                        }\r
                } else {\r
                        // search for case-insensitive regex permission match\r
@@ -198,20 +214,22 @@ public class TeamModel implements Serializable, Comparable<TeamModel> {
                                if (StringUtils.matchesIgnoreCase(repository.name, key)) {\r
                                        AccessPermission p = permissions.get(key);\r
                                        if (p != null) {\r
-                                               permission = p;\r
                                                // take first match\r
-                                               break;\r
+                                               ap.permissionType = PermissionType.REGEX;\r
+                                               ap.permission = p;\r
+                                               ap.source = key;\r
+                                               return ap;\r
                                        }\r
                                }\r
                        }\r
                }\r
-               return permission;\r
+               return ap;\r
        }\r
        \r
        protected boolean canAccess(RepositoryModel repository, AccessRestrictionType ifRestriction, AccessPermission requirePermission) {\r
                if (repository.accessRestriction.atLeast(ifRestriction)) {\r
-                       AccessPermission permission = getRepositoryPermission(repository);\r
-                       return permission.atLeast(requirePermission);\r
+                       RegistrantAccessPermission ap = getRepositoryPermission(repository);\r
+                       return ap.permission.atLeast(requirePermission);\r
                }\r
                return true;\r
        }\r
index d7e8f57b040b60427b08f1c55f0390496d48e780..e81d7ca27fe0facc0c04dd84d25bcf832b8af568 100644 (file)
@@ -140,16 +140,25 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
                List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();\r
                for (Map.Entry<String, AccessPermission> entry : permissions.entrySet()) {\r
                        String registrant = entry.getKey();\r
+                       String source = null;\r
                        boolean editable = true;\r
                        PermissionType pType = PermissionType.EXPLICIT;\r
-                       if (isMyPersonalRepository(registrant)) {\r
+                       if (canAdmin()) {\r
+                               pType = PermissionType.ADMINISTRATOR;\r
+                               editable = false;\r
+                       } else if (isMyPersonalRepository(registrant)) {\r
                                pType = PermissionType.OWNER;\r
                                editable = false;\r
                        } else if (StringUtils.findInvalidCharacter(registrant) != null) {\r
                                // a regex will have at least 1 invalid character\r
                                pType = PermissionType.REGEX;\r
+                               source = registrant;\r
+                       }\r
+                       if (AccessPermission.MISSING.equals(entry.getValue())) {\r
+                               // repository can not be found, permission is not editable\r
+                               editable = false;\r
                        }\r
-                       list.add(new RegistrantAccessPermission(registrant, entry.getValue(), pType, RegistrantType.REPOSITORY, editable));\r
+                       list.add(new RegistrantAccessPermission(registrant, entry.getValue(), pType, RegistrantType.REPOSITORY, source, editable));\r
                }\r
                Collections.sort(list);\r
                return list;\r
@@ -193,6 +202,24 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
                return permissions.containsKey(repository);\r
        }\r
        \r
+       /**\r
+        * Returns true if the user's team memberships specify an access permission for\r
+        * this repository.\r
+        * \r
+        * @param name\r
+        * @return if the user's team memberships specifi an access permission\r
+        */\r
+       public boolean hasTeamRepositoryPermission(String name) {\r
+               if (teams != null) {\r
+                       for (TeamModel team : teams) {\r
+                               if (team.hasRepositoryPermission(name)) {\r
+                                       return true;\r
+                               }\r
+                       }\r
+               }\r
+               return false;\r
+       }\r
+       \r
        /**\r
         * Adds a repository permission to the team.\r
         * <p>\r
@@ -220,23 +247,52 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
                permissions.put(repository.toLowerCase(), permission);\r
        }\r
 \r
-       public AccessPermission getRepositoryPermission(RepositoryModel repository) {\r
-               if (canAdmin() || repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {\r
-                       return AccessPermission.REWIND;\r
+       public RegistrantAccessPermission getRepositoryPermission(RepositoryModel repository) {\r
+               RegistrantAccessPermission ap = new RegistrantAccessPermission();\r
+               ap.registrant = username;\r
+               ap.registrantType = RegistrantType.USER;\r
+               ap.permission = AccessPermission.NONE;\r
+               ap.isEditable = false;\r
+\r
+               // administrator\r
+               if (canAdmin()) {\r
+                       ap.permissionType = PermissionType.ADMINISTRATOR;\r
+                       ap.permission = AccessPermission.REWIND;\r
+                       if (!canAdmin) {\r
+                               // administator permission from team membership\r
+                               for (TeamModel team : teams) {\r
+                                       if (team.canAdmin) {\r
+                                               ap.source = team.name;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+                       return ap;\r
+               }\r
+               \r
+               // repository owner - either specified owner or personal repository\r
+               if (repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {\r
+                       ap.permissionType = PermissionType.OWNER;\r
+                       ap.permission = AccessPermission.REWIND;\r
+                       return ap;\r
                }\r
+               \r
                if (AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl) && isAuthenticated) {\r
                        // AUTHENTICATED is a shortcut for authorizing all logged-in users RW access\r
-                       return AccessPermission.REWIND;\r
+                       ap.permission = AccessPermission.REWIND;\r
+                       return ap;\r
                }\r
                \r
                // explicit user permission OR user regex match is used\r
                // if that fails, then the best team permission is used\r
-               AccessPermission permission = AccessPermission.NONE;\r
                if (permissions.containsKey(repository.name.toLowerCase())) {\r
                        // exact repository permission specified, use it\r
                        AccessPermission p = permissions.get(repository.name.toLowerCase());\r
                        if (p != null) {\r
-                               return p;\r
+                               ap.permissionType = PermissionType.EXPLICIT;\r
+                               ap.permission = p;\r
+                               ap.isEditable = true;\r
+                               return ap;\r
                        }\r
                } else {\r
                        // search for case-insensitive regex permission match\r
@@ -245,29 +301,33 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
                                        AccessPermission p = permissions.get(key);\r
                                        if (p != null) {\r
                                                // take first match\r
-                                               permission = p;\r
-                                               break;\r
+                                               ap.permissionType = PermissionType.REGEX;\r
+                                               ap.permission = p;\r
+                                               ap.source = key;\r
+                                               return ap;\r
                                        }\r
                                }\r
                        }\r
                }\r
                \r
-               if (AccessPermission.NONE.equals(permission)) {\r
-                       for (TeamModel team : teams) {\r
-                               AccessPermission p = team.getRepositoryPermission(repository);\r
-                               if (p.exceeds(permission)) {\r
-                                       // use highest team permission\r
-                                       permission = p;\r
-                               }\r
+               // try to find a team match\r
+               for (TeamModel team : teams) {\r
+                       RegistrantAccessPermission p = team.getRepositoryPermission(repository);\r
+                       if (p.permission.exceeds(ap.permission)) {\r
+                               // use highest team permission\r
+                               ap.permission = p.permission;\r
+                               ap.source = team.name;\r
+                               ap.permissionType = PermissionType.TEAM;\r
                        }\r
-               }\r
-               return permission;\r
+               }               \r
+               \r
+               return ap;\r
        }\r
        \r
        protected boolean canAccess(RepositoryModel repository, AccessRestrictionType ifRestriction, AccessPermission requirePermission) {\r
                if (repository.accessRestriction.atLeast(ifRestriction)) {\r
-                       AccessPermission permission = getRepositoryPermission(repository);\r
-                       return permission.atLeast(requirePermission);\r
+                       RegistrantAccessPermission ap = getRepositoryPermission(repository);\r
+                       return ap.permission.atLeast(requirePermission);\r
                }\r
                return true;\r
        }\r
index 94d9b53acccc1d56977adeeb03ace12c325440b9..1f338267348ade71582cbe2410ad21a897d3aa6f 100644 (file)
@@ -357,11 +357,15 @@ gb.createPermission = {0} (push, ref creation)
 gb.deletePermission = {0} (push, ref creation+deletion)\r
 gb.rewindPermission = {0} (push, ref creation+deletion+rewind)\r
 gb.permission = permission\r
-gb.regexPermission = this permission is set from a regular expression\r
+gb.regexPermission = this permission is set from regular expression \"{0}\"\r
 gb.accessDenied = access denied\r
 gb.busyCollectingGarbage = sorry, Gitblit is busy collecting garbage in {0}\r
 gb.gcPeriod = GC period\r
 gb.gcPeriodDescription = duration between garbage collections\r
 gb.gcThreshold = GC threshold\r
 gb.gcThresholdDescription = minimum total size of loose objects to trigger early garbage collection\r
-gb.ownerPermission = repository owner
\ No newline at end of file
+gb.ownerPermission = repository owner\r
+gb.administrator = admin\r
+gb.administratorPermission = Gitblit administrator\r
+gb.team = team\r
+gb.teamPermission = permission set by \"{0}\" team membership
\ No newline at end of file
index 8f85816b024d02af7f8fc1f9b08b1775cab3777e..ec8d43dd2ec94303b509f373261e536942794b12 100644 (file)
@@ -9,13 +9,13 @@
 \r
        <div wicket:id="permissionRow">\r
                <div style="padding-top:10px;border-left:1px solid #ccc;border-right:1px solid #ccc;" class="row-fluid">\r
-                       <div style="padding-top:5px;padding-left:5px" class="span6"><span wicket:id="registrant"></span></div><div style="padding-top:5px;padding-right:5px;text-align:right;" class="span2"><span class="label" wicket:id="pType">[permission type]</span></div> <select class="input-medium" wicket:id="permission"></select>\r
+                       <div style="padding-top:5px;padding-left:5px" class="span6"><span wicket:id="registrant"></span></div><div style="padding-top:5px;padding-right:5px;text-align:right;" class="span3"><span class="label" wicket:id="pType">[permission type]</span></div> <select class="input-medium" wicket:id="permission"></select>\r
                </div>\r
        </div>\r
 \r
        <div style="padding-top:15px;" class="row-fluid">\r
                <form style="padding: 20px 40px;" class="well form-inline" wicket:id="addPermissionForm">\r
-                       <select class="input-large" wicket:id="registrant"></select> <select class="input-medium" wicket:id="permission"></select> <input class="btn btn-success" type="submit" value="Add" wicket:message="value:gb.add" wicket:id="addPermissionButton"/>\r
+                       <select class="input-xlarge" wicket:id="registrant"></select> <select class="input-large" wicket:id="permission"></select> <input class="btn btn-success" type="submit" value="Add" wicket:message="value:gb.add" wicket:id="addPermissionButton"/>\r
                </form>\r
        </div>\r
        \r
index 805db9ddb4c768652cf12f9be942f926f67c4144..d6bd56526490bfbce91dfd6d02b36f1af0125bef 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.gitblit.wicket.panels;
 
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Iterator;
@@ -109,7 +110,7 @@ public class RegistrantPermissionsPanel extends BasePanel {
                                        }
 
                                        Fragment userFragment = new Fragment("registrant", "userRegistrant", RegistrantPermissionsPanel.this);
-                                       userFragment.add(new GravatarImage("userAvatar", ident, 16, false));
+                                       userFragment.add(new GravatarImage("userAvatar", ident, 20, false));
                                        userFragment.add(new Label("userName", entry.registrant));                                      
                                        item.add(userFragment);                                 
                                } else {
@@ -119,14 +120,30 @@ public class RegistrantPermissionsPanel extends BasePanel {
                                        item.add(teamFragment);
                                }
                                switch (entry.permissionType) {
+                               case ADMINISTRATOR:
+                                       Label administrator = new Label("pType", entry.source == null ? getString("gb.administrator") : entry.source);
+                                       WicketUtils.setHtmlTooltip(administrator, getString("gb.administratorPermission"));
+                                       WicketUtils.setCssClass(administrator, "label label-inverse");
+                                       item.add(administrator);
+                                       break;
                                case OWNER:
-                                       Label owner = new Label("pType", "owner");
+                                       Label owner = new Label("pType", getString("gb.owner"));
                                        WicketUtils.setHtmlTooltip(owner, getString("gb.ownerPermission"));
+                                       WicketUtils.setCssClass(owner, "label label-info");
                                        item.add(owner);
                                        break;
+                               case TEAM:
+                                       Label team = new Label("pType", entry.source == null ? getString("gb.team") : entry.source);
+                                       WicketUtils.setHtmlTooltip(team, MessageFormat.format(getString("gb.teamPermission"), entry.source));
+                                       WicketUtils.setCssClass(team, "label label-success");
+                                       item.add(team);
+                                       break;
                                case REGEX:
                                        Label regex = new Label("pType", "regex");
-                                       WicketUtils.setHtmlTooltip(regex, getString("gb.regexPermission"));
+                                       if (!StringUtils.isEmpty(entry.source)) {
+                                               WicketUtils.setHtmlTooltip(regex, MessageFormat.format(getString("gb.regexPermission"), entry.source));
+                                       }
+                                       WicketUtils.setCssClass(regex, "label");
                                        item.add(regex);
                                        break;
                                default:
@@ -165,9 +182,15 @@ public class RegistrantPermissionsPanel extends BasePanel {
                final List<String> registrants = new ArrayList<String>(allRegistrants);
                for (RegistrantAccessPermission rp : permissions) {
                        if (rp.isEditable) {
-                               // only remove editable duplicates
+                               // remove editable duplicates
                                // this allows for specifying an explicit permission
                                registrants.remove(rp.registrant);
+                       } else if (rp.isAdmin()) {
+                               // administrators can not have their permission changed
+                               registrants.remove(rp.registrant);
+                       } else if (rp.isOwner()) {
+                               // owners can not have their permission changed
+                               registrants.remove(rp.registrant);
                        }
                }
 
index 3df0ff8ebae7fd04ba852c94f450d68494ee53b1..62d87bf9aad1d255d4952283d0b4c957ef010919 100644 (file)
@@ -200,7 +200,7 @@ public class RpcTests {
                List<RegistrantAccessPermission> permissions = RpcUtils.getRepositoryMemberPermissions(retrievedRepository, url, account,\r
                                password.toCharArray());\r
                assertEquals("Membership permissions is not empty!", 0, permissions.size());\r
-               permissions.add(new RegistrantAccessPermission(testMember.username, AccessPermission.PUSH, PermissionType.EXPLICIT, RegistrantType.USER, true));\r
+               permissions.add(new RegistrantAccessPermission(testMember.username, AccessPermission.PUSH, PermissionType.EXPLICIT, RegistrantType.USER, null, true));\r
                assertTrue(\r
                                "Failed to set member permissions!",\r
                                RpcUtils.setRepositoryMemberPermissions(retrievedRepository, permissions, url, account,\r
@@ -289,7 +289,7 @@ public class RpcTests {
                // set no teams\r
                List<RegistrantAccessPermission> permissions = new ArrayList<RegistrantAccessPermission>();\r
                for (String team : helloworldTeams) {\r
-                       permissions.add(new RegistrantAccessPermission(team, AccessPermission.NONE, PermissionType.EXPLICIT, RegistrantType.TEAM, true));\r
+                       permissions.add(new RegistrantAccessPermission(team, AccessPermission.NONE, PermissionType.EXPLICIT, RegistrantType.TEAM, null, true));\r
                }\r
                assertTrue(RpcUtils.setRepositoryTeamPermissions(helloworld, permissions, url, account,\r
                                password.toCharArray()));\r