]> source.dussan.org Git - gitblit.git/commitdiff
Support Team canAdmin, canCreate, and canFork (issue 36)
authorJames Moger <james.moger@gitblit.com>
Thu, 11 Oct 2012 02:29:36 +0000 (22:29 -0400)
committerJames Moger <james.moger@gitblit.com>
Thu, 11 Oct 2012 02:29:36 +0000 (22:29 -0400)
22 files changed:
src/com/gitblit/AccessRestrictionFilter.java
src/com/gitblit/AuthenticationFilter.java
src/com/gitblit/ConfigUserService.java
src/com/gitblit/FileUserService.java
src/com/gitblit/RpcFilter.java
src/com/gitblit/RpcServlet.java
src/com/gitblit/client/UsersTableModel.java
src/com/gitblit/models/TeamModel.java
src/com/gitblit/models/UserModel.java
src/com/gitblit/wicket/AuthorizationStrategy.java
src/com/gitblit/wicket/GitBlitWebApp.properties
src/com/gitblit/wicket/GitBlitWebSession.java
src/com/gitblit/wicket/pages/EditRepositoryPage.java
src/com/gitblit/wicket/pages/EditTeamPage.html
src/com/gitblit/wicket/pages/EditTeamPage.java
src/com/gitblit/wicket/pages/EditUserPage.html
src/com/gitblit/wicket/pages/RepositoryPage.java
src/com/gitblit/wicket/pages/UserPage.java
src/com/gitblit/wicket/panels/RepositoriesPanel.java
src/com/gitblit/wicket/panels/UsersPanel.java
test-users.conf
tests/com/gitblit/tests/PermissionsTest.java

index aeb6835c5deeebf1221b7d0d4fcdea2d4778fc19..3a104813aa1ef973cbf1a7af81629184561d05f0 100644 (file)
@@ -156,7 +156,7 @@ public abstract class AccessRestrictionFilter extends AuthenticationFilter {
                                return;\r
                        } else {\r
                                // check user access for request\r
-                               if (user.canAdmin || canAccess(model, user, urlRequestType)) {\r
+                               if (user.canAdmin() || canAccess(model, user, urlRequestType)) {\r
                                        // authenticated request permitted.\r
                                        // pass processing to the restricted servlet.\r
                                        newSession(authenticatedRequest, httpResponse);\r
index 259991c9e4182fd78f3fc544fd2bce7a978a5ec2..4762c428f4a5baf7d87f84fb71eb3d566bf2262b 100644 (file)
@@ -189,7 +189,7 @@ public abstract class AuthenticationFilter implements Filter {
                @Override\r
                public boolean isUserInRole(String role) {\r
                        if (role.equals(Constants.ADMIN_ROLE)) {\r
-                               return user.canAdmin;\r
+                               return user.canAdmin();\r
                        }\r
                        // Gitblit does not currently use actual roles in the traditional\r
                        // servlet container sense.  That is the reason this is marked\r
index d2740094a5a4c8350920afe8794c83a9bec3c122..82cd33e33b8a2ab160f7529ec48e1f7bca1c143d 100644 (file)
@@ -862,6 +862,24 @@ public class ConfigUserService implements IUserService {
 \r
                // write teams\r
                for (TeamModel model : teams.values()) {\r
+                       // team roles\r
+                       List<String> roles = new ArrayList<String>();\r
+                       if (model.canAdmin) {\r
+                               roles.add(Constants.ADMIN_ROLE);\r
+                       }\r
+                       if (model.canFork) {\r
+                               roles.add(Constants.FORK_ROLE);\r
+                       }\r
+                       if (model.canCreate) {\r
+                               roles.add(Constants.CREATE_ROLE);\r
+                       }\r
+                       if (roles.size() == 0) {\r
+                               // we do this to ensure that team record is written.\r
+                               // Otherwise, StoredConfig might optimizes that record away.\r
+                               roles.add(Constants.NO_ROLE);\r
+                       }\r
+                       config.setStringList(TEAM, model.name, ROLE, roles);\r
+                       \r
                        if (model.permissions == null) {\r
                                // null check on "final" repositories because JSON-sourced TeamModel\r
                                // can have a null repositories object\r
@@ -982,6 +1000,12 @@ public class ConfigUserService implements IUserService {
                                Set<String> teamnames = config.getSubsections(TEAM);\r
                                for (String teamname : teamnames) {\r
                                        TeamModel team = new TeamModel(teamname);\r
+                                       Set<String> roles = new HashSet<String>(Arrays.asList(config.getStringList(\r
+                                                       TEAM, teamname, ROLE)));\r
+                                       team.canAdmin = roles.contains(Constants.ADMIN_ROLE);\r
+                                       team.canFork = roles.contains(Constants.FORK_ROLE);\r
+                                       team.canCreate = roles.contains(Constants.CREATE_ROLE);\r
+                                       \r
                                        team.addRepositoryPermissions(Arrays.asList(config.getStringList(TEAM, teamname,\r
                                                        REPOSITORY)));\r
                                        team.addUsers(Arrays.asList(config.getStringList(TEAM, teamname, USER)));\r
index c06266dc395a664336d92db0fb6a532a297e232e..d411b68f47895ddf28bf689b433d9e175af4a8fa 100644 (file)
@@ -780,6 +780,20 @@ public class FileUserService extends FileSettings implements IUserService {
                                                } else if (role.charAt(0) == '%') {\r
                                                        postReceive.add(role.substring(1));\r
                                                } else {\r
+                                                       switch (role.charAt(0)) {\r
+                                                       case '#':\r
+                                                               // Permissions\r
+                                                               if (role.equalsIgnoreCase(Constants.ADMIN_ROLE)) {\r
+                                                                       team.canAdmin = true;\r
+                                                               } else if (role.equalsIgnoreCase(Constants.FORK_ROLE)) {\r
+                                                                       team.canFork = true;\r
+                                                               } else if (role.equalsIgnoreCase(Constants.CREATE_ROLE)) {\r
+                                                                       team.canCreate = true;\r
+                                                               }\r
+                                                               break;\r
+                                                       default:\r
+                                                               repositories.add(role);\r
+                                                       }\r
                                                        repositories.add(role);\r
                                                }\r
                                        }\r
@@ -1040,6 +1054,17 @@ public class FileUserService extends FileSettings implements IUserService {
                        }\r
                }\r
                \r
+               // Permissions\r
+               if (model.canAdmin) {\r
+                       roles.add(Constants.ADMIN_ROLE);\r
+               }\r
+               if (model.canFork) {\r
+                       roles.add(Constants.FORK_ROLE);\r
+               }\r
+               if (model.canCreate) {\r
+                       roles.add(Constants.CREATE_ROLE);\r
+               }\r
+\r
                for (String role : roles) {\r
                                sb.append(role);\r
                                sb.append(',');\r
index 4c0f03df6edd0bd18f57767dd48d9d5d8417f5fd..1de9fcc4b54462cc34ed6879feb7b8e6448f255b 100644 (file)
@@ -105,7 +105,7 @@ public class RpcFilter extends AuthenticationFilter {
                                return;\r
                        } else {\r
                                // check user access for request\r
-                               if (user.canAdmin || canAccess(user, requestType)) {\r
+                               if (user.canAdmin() || canAccess(user, requestType)) {\r
                                        // authenticated request permitted.\r
                                        // pass processing to the restricted servlet.\r
                                        newSession(authenticatedRequest, httpResponse);\r
@@ -140,7 +140,7 @@ public class RpcFilter extends AuthenticationFilter {
                case LIST_REPOSITORIES:\r
                        return true;\r
                default:\r
-                       return user.canAdmin;\r
+                       return user.canAdmin();\r
                }\r
        }\r
 }
\ No newline at end of file
index ff98ff55b0163af4ff4b3563a9db5929ccae262e..2a6ba26c7819f7fc8bc1c6ecbbfd59f98e716711 100644 (file)
@@ -73,10 +73,10 @@ public class RpcServlet extends JsonServlet {
 \r
                UserModel user = (UserModel) request.getUserPrincipal();\r
 \r
-               boolean allowManagement = user != null && user.canAdmin\r
+               boolean allowManagement = user != null && user.canAdmin()\r
                                && GitBlit.getBoolean(Keys.web.enableRpcManagement, false);\r
 \r
-               boolean allowAdmin = user != null && user.canAdmin\r
+               boolean allowAdmin = user != null && user.canAdmin()\r
                                && GitBlit.getBoolean(Keys.web.enableRpcAdministration, false);\r
 \r
                Object result = null;\r
index c05230ea256a3570e264a7267aa0384c9522164b..f635f7e8338657a32da0aa2c66ea6a00ebb416ae 100644 (file)
@@ -102,7 +102,7 @@ public class UsersTableModel extends AbstractTableModel {
                case Display_Name:\r
                        return model.displayName;\r
                case AccessLevel:\r
-                       if (model.canAdmin) {\r
+                       if (model.canAdmin()) {\r
                                return "administrator";\r
                        }\r
                        return "";\r
index 896adfe66a2f4c888997b334e5d5b93a395a868d..149c7659236d8d9cc1e57b8907e070e60fceeb2e 100644 (file)
@@ -41,6 +41,9 @@ public class TeamModel implements Serializable, Comparable<TeamModel> {
 \r
        // field names are reflectively mapped in EditTeam page\r
        public String name;\r
+       public boolean canAdmin;\r
+       public boolean canFork;\r
+       public boolean canCreate;\r
        public final Set<String> users = new HashSet<String>();\r
        // retained for backwards-compatibility with RPC clients\r
        @Deprecated\r
index d8c2abe3af52ef66b003ca4776abfdcbadbd42c2..6fe8df2ba09a3733e7f2a07cfa282ef88b3ca2c7 100644 (file)
@@ -26,6 +26,7 @@ import com.gitblit.Constants.AccessPermission;
 import com.gitblit.Constants.AccessRestrictionType;\r
 import com.gitblit.Constants.AuthorizationControl;\r
 import com.gitblit.Constants.Unused;\r
+import com.gitblit.utils.ArrayUtils;\r
 import com.gitblit.utils.StringUtils;\r
 \r
 /**\r
@@ -80,7 +81,7 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
         */\r
        @Deprecated\r
        public boolean canAccessRepository(String repositoryName) {\r
-               return canAdmin || repositories.contains(repositoryName.toLowerCase())\r
+               return canAdmin() || repositories.contains(repositoryName.toLowerCase())\r
                                || hasTeamAccess(repositoryName);\r
        }\r
 \r
@@ -90,7 +91,7 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
                boolean isOwner = !StringUtils.isEmpty(repository.owner)\r
                                && repository.owner.equals(username);\r
                boolean allowAuthenticated = isAuthenticated && AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl);\r
-               return canAdmin || isOwner || repositories.contains(repository.name.toLowerCase())\r
+               return canAdmin() || isOwner || repositories.contains(repository.name.toLowerCase())\r
                                || hasTeamAccess(repository.name) || allowAuthenticated;\r
        }\r
 \r
@@ -177,7 +178,7 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
        }\r
 \r
        public AccessPermission getRepositoryPermission(RepositoryModel repository) {\r
-               if (canAdmin || repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {\r
+               if (canAdmin() || repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {\r
                        return AccessPermission.REWIND;\r
                }\r
                if (AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl) && isAuthenticated) {\r
@@ -265,24 +266,84 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel>
                        // can not fork your own repository\r
                        return false;\r
                }\r
-               if (canAdmin || repository.isOwner(username)) {\r
+               if (canAdmin() || repository.isOwner(username)) {\r
                        return true;\r
                }\r
                if (!repository.allowForks) {\r
                        return false;\r
                }\r
-               if (!isAuthenticated || !canFork) {\r
+               if (!isAuthenticated || !canFork()) {\r
                        return false;\r
                }\r
                return canClone(repository);\r
        }\r
        \r
        public boolean canDelete(RepositoryModel model) {\r
-               return canAdmin || model.isUsersPersonalRepository(username);\r
+               return canAdmin() || model.isUsersPersonalRepository(username);\r
        }\r
        \r
        public boolean canEdit(RepositoryModel model) {\r
-               return canAdmin || model.isUsersPersonalRepository(username) || model.isOwner(username);\r
+               return canAdmin() || model.isUsersPersonalRepository(username) || model.isOwner(username);\r
+       }\r
+       \r
+       /**\r
+        * This returns true if the user has fork privileges or the user has fork\r
+        * privileges because of a team membership.\r
+        * \r
+        * @return true if the user can fork\r
+        */\r
+       public boolean canFork() {\r
+               if (canFork) {\r
+                       return true;\r
+               }\r
+               if (!ArrayUtils.isEmpty(teams)) {\r
+                       for (TeamModel team : teams) {\r
+                               if (team.canFork) {\r
+                                       return true;\r
+                               }\r
+                       }\r
+               }\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * This returns true if the user has admin privileges or the user has admin\r
+        * privileges because of a team membership.\r
+        * \r
+        * @return true if the user can admin\r
+        */\r
+       public boolean canAdmin() {\r
+               if (canAdmin) {\r
+                       return true;\r
+               }\r
+               if (!ArrayUtils.isEmpty(teams)) {\r
+                       for (TeamModel team : teams) {\r
+                               if (team.canAdmin) {\r
+                                       return true;\r
+                               }\r
+                       }\r
+               }\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * This returns true if the user has create privileges or the user has create\r
+        * privileges because of a team membership.\r
+        * \r
+        * @return true if the user can admin\r
+        */\r
+       public boolean canCreate() {\r
+               if (canCreate) {\r
+                       return true;\r
+               }\r
+               if (!ArrayUtils.isEmpty(teams)) {\r
+                       for (TeamModel team : teams) {\r
+                               if (team.canCreate) {\r
+                                       return true;\r
+                               }\r
+                       }\r
+               }\r
+               return false;\r
        }\r
 \r
        public boolean isTeamMember(String teamname) {\r
index 16a4ec80b5bc04fe18cde36cdd10afec3201b2ab..21bd1b70fb2a6446b27bdfc582d9e202d242b7c3 100644 (file)
@@ -60,7 +60,7 @@ public class AuthorizationStrategy extends AbstractPageAuthorizationStrategy imp
                                        if (authenticateAdmin) {\r
                                                // authenticate admin\r
                                                if (user != null) {\r
-                                                       return user.canAdmin;\r
+                                                       return user.canAdmin();\r
                                                }\r
                                                return false;\r
                                        } else {\r
index 97faf761586c921dfdcfa0d37ae89499a508a1f2..0c500648611264ede51d2a43b4ac37886cc915f6 100644 (file)
@@ -329,7 +329,7 @@ gb.allowForks = allow forks
 gb.allowForksDescription = allow authorized users to fork this repository\r
 gb.forkedFrom = forked from\r
 gb.canFork = can fork\r
-gb.canForkDescription = user is permitted to fork authorized repositories\r
+gb.canForkDescription = can fork authorized repositories to a personal repository\r
 gb.myFork = view my fork\r
 gb.forksProhibited = forks prohibited\r
 gb.forksProhibitedWarning = this repository forbids forks\r
index 0e1ae5123f1ea17bc7c33674f1c3144e374831a4..015d97ad9ac6258d0fc2e480c60530577c3ef792 100644 (file)
@@ -103,7 +103,7 @@ public final class GitBlitWebSession extends WebSession {
                if (user == null) {\r
                        return false;\r
                }\r
-               return user.canAdmin;\r
+               return user.canAdmin();\r
        }\r
        \r
        public String getUsername() {\r
index f7427eb587ee9bfdaddfcfa93bd9a1f4326dc4f1..8176c28b2af8ae3b1039698b51b248d7d5e871b0 100644 (file)
@@ -83,7 +83,7 @@ public class EditRepositoryPage extends RootSubPage {
                \r
                GitBlitWebSession session = GitBlitWebSession.get();\r
                UserModel user = session.getUser();\r
-               if (user != null && user.canCreate && !user.canAdmin) {\r
+               if (user != null && user.canCreate() && !user.canAdmin()) {\r
                        // personal create permissions, inject personal repository path\r
                        model.name = user.getPersonalPath() + "/";\r
                        model.projectPath = user.getPersonalPath();\r
@@ -120,7 +120,7 @@ public class EditRepositoryPage extends RootSubPage {
                final UserModel user = session.getUser() == null ? UserModel.ANONYMOUS : session.getUser();\r
 \r
                if (isCreate) {\r
-                       if (user.canAdmin) {\r
+                       if (user.canAdmin()) {\r
                                super.setupPage(getString("gb.newRepository"), "");\r
                        } else {\r
                                super.setupPage(getString("gb.newRepository"), user.getDisplayName());\r
@@ -253,7 +253,7 @@ public class EditRepositoryPage extends RootSubPage {
                                                return;\r
                                        }\r
                                        \r
-                                       if (user.canCreate && !user.canAdmin) {\r
+                                       if (user.canCreate() && !user.canAdmin()) {\r
                                                // ensure repository name begins with the user's path\r
                                                if (!repositoryModel.name.startsWith(user.getPersonalPath())) {\r
                                                        error(MessageFormat.format(getString("gb.illegalPersonalRepositoryLocation"),\r
@@ -474,13 +474,13 @@ public class EditRepositoryPage extends RootSubPage {
                                }\r
                                if (isCreate) {\r
                                        // Create Repository\r
-                                       if (!user.canCreate && !user.canAdmin) {\r
+                                       if (!user.canCreate() && !user.canAdmin()) {\r
                                                // Only administrators or permitted users may create\r
                                                error(getString("gb.errorOnlyAdminMayCreateRepository"), true);\r
                                        }\r
                                } else {\r
                                        // Edit Repository\r
-                                       if (user.canAdmin) {\r
+                                       if (user.canAdmin()) {\r
                                                // Admins can edit everything\r
                                                isAdmin = true;\r
                                                return;\r
index 5a2edaee9ad3c7466c732377249c066dce6161ff..30d2a94c53544a5639d6b593e75a6a9600802f80 100644 (file)
                        <tbody class="settings">\r
                                <tr><td colspan="2"><h3><wicket:message key="gb.general"></wicket:message> &nbsp;<small><wicket:message key="gb.generalDescription"></wicket:message></small></h3></td></tr>\r
                                <tr><th><wicket:message key="gb.teamName"></wicket:message></th><td class="edit"><input type="text" wicket:id="name" id="name" size="30" tabindex="1" /></td></tr>\r
-                               <tr><th><wicket:message key="gb.mailingLists"></wicket:message></th><td class="edit"><input class="span8" type="text" wicket:id="mailingLists" size="40" tabindex="2" /></td></tr>\r
+                               <tr><th><wicket:message key="gb.canAdmin"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canAdmin" tabindex="2" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canAdminDescription"></wicket:message></span></label></td></tr>                            \r
+                               <tr><th><wicket:message key="gb.canCreate"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canCreate" tabindex="3" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canCreateDescription"></wicket:message></span></label></td></tr>                         \r
+                               <tr><th><wicket:message key="gb.canFork"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canFork" tabindex="4" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canForkDescription"></wicket:message></span></label></td></tr>                               \r
+                               <tr><th><wicket:message key="gb.mailingLists"></wicket:message></th><td class="edit"><input class="span8" type="text" wicket:id="mailingLists" size="40" tabindex="5" /></td></tr>\r
                                <tr><td colspan="2" style="padding-top:15px;"><h3><wicket:message key="gb.accessPermissions"></wicket:message> &nbsp;<small><wicket:message key="gb.accessPermissionsForTeamDescription"></wicket:message></small></h3></td></tr>       \r
                                <tr><th style="vertical-align: top;"><wicket:message key="gb.teamMembers"></wicket:message></th><td style="padding:2px;"><span wicket:id="users"></span></td></tr>\r
                                <tr><td colspan="2"><hr></hr></td></tr>\r
@@ -20,7 +23,7 @@
                                <tr><td colspan="2" style="padding-top:10px;"><h3><wicket:message key="gb.hookScripts"></wicket:message> &nbsp;<small><wicket:message key="gb.hookScriptsDescription"></wicket:message></small></h3></td></tr>  \r
                                <tr><th style="vertical-align: top;"><wicket:message key="gb.preReceiveScripts"></wicket:message><p></p><span wicket:id="inheritedPreReceive"></span></th><td style="padding:2px;"><span wicket:id="preReceiveScripts"></span></td></tr>\r
                                <tr><th style="vertical-align: top;"><wicket:message key="gb.postReceiveScripts"></wicket:message><p></p><span wicket:id="inheritedPostReceive"></span></th><td style="padding:2px;"><span wicket:id="postReceiveScripts"></span></td></tr>\r
-                               <tr><td colspan='2'><div class="form-actions"><input class="btn btn-primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="3" /> &nbsp; <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="4" /></div></td></tr>\r
+                               <tr><td colspan='2'><div class="form-actions"><input class="btn btn-primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="6" /> &nbsp; <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="7" /></div></td></tr>\r
                        </tbody>\r
                </table>\r
        </form> \r
index 96bd188f8de4eafaef19b285fd6d4f47242dd809..9cbccb5933fc2aff889aabb652aa30332fd84ef5 100644 (file)
@@ -27,6 +27,7 @@ import org.apache.wicket.PageParameters;
 import org.apache.wicket.behavior.SimpleAttributeModifier;\r
 import org.apache.wicket.extensions.markup.html.form.palette.Palette;\r
 import org.apache.wicket.markup.html.form.Button;\r
+import org.apache.wicket.markup.html.form.CheckBox;\r
 import org.apache.wicket.markup.html.form.Form;\r
 import org.apache.wicket.markup.html.form.TextField;\r
 import org.apache.wicket.model.CompoundPropertyModel;\r
@@ -222,6 +223,9 @@ public class EditTeamPage extends RootSubPage {
                \r
                // field names reflective match TeamModel fields\r
                form.add(new TextField<String>("name"));\r
+               form.add(new CheckBox("canAdmin"));\r
+               form.add(new CheckBox("canFork"));\r
+               form.add(new CheckBox("canCreate"));\r
                form.add(users.setEnabled(editMemberships));\r
                mailingLists = new Model<String>(teamModel.mailingLists == null ? ""\r
                                : StringUtils.flattenStrings(teamModel.mailingLists, " "));\r
index 7793207954de401863c59837ee11b4ebc95fc118..9f178df8bc0cbcf205c9f7962ac30787cc911e11 100644 (file)
@@ -17,8 +17,8 @@
                                <tr><th><wicket:message key="gb.displayName"></wicket:message></th><td class="edit"><input type="text" wicket:id="displayName" size="30" tabindex="4" /></td></tr>\r
                                <tr><th><wicket:message key="gb.emailAddress"></wicket:message></th><td class="edit"><input type="text" wicket:id="emailAddress" size="30" tabindex="5" /></td></tr>\r
                                <tr><th><wicket:message key="gb.canAdmin"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canAdmin" tabindex="6" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canAdminDescription"></wicket:message></span></label></td></tr>                            \r
-                               <tr><th><wicket:message key="gb.canFork"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canFork" tabindex="7" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canForkDescription"></wicket:message></span></label></td></tr>                               \r
-                               <tr><th><wicket:message key="gb.canCreate"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canCreate" tabindex="8" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canCreateDescription"></wicket:message></span></label></td></tr>                         \r
+                               <tr><th><wicket:message key="gb.canCreate"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canCreate" tabindex="7" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canCreateDescription"></wicket:message></span></label></td></tr>                         \r
+                               <tr><th><wicket:message key="gb.canFork"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canFork" tabindex="8" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canForkDescription"></wicket:message></span></label></td></tr>                               \r
                                <tr><th><wicket:message key="gb.excludeFromFederation"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="excludeFromFederation" tabindex="9" /> &nbsp;<span class="help-inline"><wicket:message key="gb.excludeFromFederationDescription"></wicket:message></span></label></td></tr>                             \r
                                <tr><td colspan="2" style="padding-top:15px;"><h3><wicket:message key="gb.accessPermissions"></wicket:message> &nbsp;<small><wicket:message key="gb.accessPermissionsForUserDescription"></wicket:message></small></h3></td></tr>       \r
                                <tr><th style="vertical-align: top;"><wicket:message key="gb.teamMemberships"></wicket:message></th><td style="padding:2px;"><span wicket:id="teams"></span></td></tr>\r
index 9048eba34ca82efddbdecb62fca9238c632be3ad..b7cade6fd7474f97b91e6aa6cca89a6276c4ce82 100644 (file)
@@ -248,7 +248,7 @@ public abstract class RepositoryPage extends BasePage {
                                // user not allowed to fork or fork already exists or repo forbids forking\r
                                add(new ExternalLink("forkLink", "").setVisible(false));\r
                                \r
-                               if (user.canFork && !model.allowForks) {\r
+                               if (user.canFork() && !model.allowForks) {\r
                                        // show forks prohibited indicator\r
                                        Fragment wc = new Fragment("forksProhibitedIndicator", "forksProhibitedFragment", this);\r
                                        Label lbl = new Label("forksProhibited", getString("gb.forksProhibited"));\r
index e699d03f9df76064fea1d9d064136cbbcd7b910e..d3e93c616fa690705c2e907fe0308b6304dd811a 100644 (file)
@@ -101,7 +101,7 @@ public class UserPage extends RootPage {
                add(new GravatarImage("gravatar", person, 210));\r
                \r
                UserModel sessionUser = GitBlitWebSession.get().getUser();\r
-               if (sessionUser != null && user.canCreate && sessionUser.equals(user)) {\r
+               if (sessionUser != null && user.canCreate() && sessionUser.equals(user)) {\r
                        // user can create personal repositories\r
                        add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class));\r
                } else {\r
index 137fae6bd0e02e74ad12fe49e64084f3736c1d9e..5678b092e25b10021ad971b1d7a66d13924c1dcf 100644 (file)
@@ -92,7 +92,7 @@ public class RepositoriesPanel extends BasePanel {
                        }.setVisible(GitBlit.getBoolean(Keys.git.cacheRepositoryList, true)));\r
                        managementLinks.add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class));\r
                        add(managementLinks);\r
-               } else if (showManagement && user != null && user.canCreate) {\r
+               } else if (showManagement && user != null && user.canCreate()) {\r
                        // user can create personal repositories\r
                        managementLinks = new Fragment("managementPanel", "personalLinks", this);\r
                        managementLinks.add(new BookmarkablePageLink<Void>("newRepository", EditRepositoryPage.class));\r
index 6672c407ba34a09e19370f42b6b5d38568cf5526..c5dba847dfa0a8595a8c6d6d8808afa857e7136d 100644 (file)
@@ -81,7 +81,7 @@ public class UsersPanel extends BasePanel {
                                        item.add(editLink);\r
                                }\r
 \r
-                               item.add(new Label("accesslevel", entry.canAdmin ? "administrator" : ""));\r
+                               item.add(new Label("accesslevel", entry.canAdmin() ? "administrator" : ""));\r
                                item.add(new Label("teams", entry.teams.size() > 0 ? ("" + entry.teams.size()) : ""));\r
                                item.add(new Label("repositories",\r
                                                entry.repositories.size() > 0 ? ("" + entry.repositories.size()) : ""));\r
index 5551e47ab298a57b102758f144b5e8580ee91c55..4f94787233873cc80dffcd2d4df801d065a668f2 100644 (file)
@@ -4,4 +4,5 @@
        role = "#admin"
        role = "#notfederated"
 [team "admins"]
+       role = "#none"
        user = admin
index 41ff5a638aa9f2b48ee18f66cdaaa4ed677b2be0..2f47a4893a3801807caa8671d11cb385e39c7cf2 100644 (file)
@@ -2414,6 +2414,33 @@ public class PermissionsTest extends Assert {
                
                assertFalse("user CAN delete!", user.canDelete(repository));
                assertFalse("user CAN edit!", user.canEdit(repository));
+       }
+       
+       @Test
+       public void testAdminTeamInheritance() throws Exception {
+               UserModel user = new UserModel("test");
+               TeamModel team = new TeamModel("team");
+               team.canAdmin = true;
+               user.teams.add(team);
+               assertTrue("User did not inherit admin privileges", user.canAdmin());
+       }
+       
+       @Test
+       public void testForkTeamInheritance() throws Exception {
+               UserModel user = new UserModel("test");
+               TeamModel team = new TeamModel("team");
+               team.canFork = true;
+               user.teams.add(team);
+               assertTrue("User did not inherit fork privileges", user.canFork());
+       }
 
+       @Test
+       public void testCreateTeamInheritance() throws Exception {
+               UserModel user = new UserModel("test");
+               TeamModel team = new TeamModel("team");
+               team.canCreate= true;
+               user.teams.add(team);
+               assertTrue("User did not inherit create privileges", user.canCreate());
        }
+
 }