\r
Gitblit also supports *case-insensitive* regex matching for repository permissions. The following permission grants push privileges to all repositories in the *mygroup* folder.\r
\r
- RW:mygroup/[a-z0-9-~_\\./]+\r
+ RW:mygroup/.*\r
+\r
+##### Exclusions\r
+\r
+When using regex matching it may also be useful to exclude specific repositories or to exclude regex repository matches. You may specify the **X** permission for exclusion. The following example grants clone permission to all repositories except the repositories in mygroup. The user/team will have no access whatsoever to these repositories.\r
+\r
+ X:mygroup/.*\r
+ R:.*\r
+\r
+##### Order is Important\r
+\r
+The preceding example should suggest that order of permissions is important with regex matching. Here are the rules for determining the permission that is applied to a repository request:\r
+\r
+1. If the user is an admin or repository owner, then RW+\r
+2. Else if user has an explicit permission, use that\r
+3. Else check for the first regex match in user permissions\r
+4. Else check for the HIGHEST permission from team memberships\r
+ 1. If the team is an admin team, then RW+\r
+ 2. Else if a team has an explicit permission, use that\r
+ 3. Else check for the first regex match in team permissions\r
\r
#### No-So-Discrete Permissions (Gitblit <= v1.1.0)\r
\r
* The access permissions available for a repository. \r
*/\r
public static enum AccessPermission {\r
- NONE("N"), VIEW("V"), CLONE("R"), PUSH("RW"), CREATE("RWC"), DELETE("RWD"), REWIND("RW+");\r
+ NONE("N"), EXCLUDE("X"), VIEW("V"), CLONE("R"), PUSH("RW"), CREATE("RWC"), DELETE("RWD"), REWIND("RW+");\r
\r
- public static final AccessPermission [] NEWPERMISSIONS = { VIEW, CLONE, PUSH, CREATE, DELETE, REWIND };\r
+ public static final AccessPermission [] NEWPERMISSIONS = { EXCLUDE, VIEW, CLONE, PUSH, CREATE, DELETE, REWIND };\r
\r
public static AccessPermission LEGACY = REWIND;\r
\r
gb.userPermissions = user permissions\r
gb.teamPermissions = team permissions\r
gb.add = add\r
-gb.noPermission = NO ACCESS\r
+gb.noPermission = DELETE PERMISSION\r
+gb.excludePermission = {0} (exclude)\r
gb.viewPermission = {0} (view)\r
gb.clonePermission = {0} (clone)\r
gb.pushPermission = {0} (push)\r
case NONE:\r
map.put(type, MessageFormat.format(getString("gb.noPermission"), type.code));\r
break;\r
+ case EXCLUDE:\r
+ map.put(type, MessageFormat.format(getString("gb.excludePermission"), type.code));\r
+ break;\r
case VIEW:\r
map.put(type, MessageFormat.format(getString("gb.viewPermission"), type.code));\r
break;\r
assertFalse("user CAN delete!", user.canDelete(personal));
assertFalse("user CAN edit!", user.canEdit(personal));
}
+
+ @Test
+ public void testExclusion() throws Exception {
+ RepositoryModel personal = new RepositoryModel("~ubercool/_my-r/e~po.git", null, null, new Date());
+ personal.authorizationControl = AuthorizationControl.NAMED;
+ personal.accessRestriction = AccessRestrictionType.VIEW;
+
+ UserModel user = new UserModel("test");
+ user.setRepositoryPermission("~ubercool/.*", AccessPermission.EXCLUDE);
+ user.setRepositoryPermission(".*", AccessPermission.PUSH);
+
+ // has EXCLUDE access because first match is EXCLUDE permission
+ assertTrue("user DOES NOT HAVE a repository permission!", user.hasRepositoryPermission(personal.name));
+ assertFalse("user CAN NOT view!", user.canView(personal));
+ assertFalse("user CAN NOT clone!", user.canClone(personal));
+ assertFalse("user CAN push!", user.canPush(personal));
+
+ assertFalse("user CAN create ref!", user.canCreateRef(personal));
+ assertFalse("user CAN delete ref!", user.canDeleteRef(personal));
+ assertFalse("user CAN rewind ref!", user.canRewindRef(personal));
+
+ assertFalse("user CAN fork!", user.canFork(personal));
+
+ assertFalse("user CAN delete!", user.canDelete(personal));
+ assertFalse("user CAN edit!", user.canEdit(personal));
+ }
@Test
public void testAdminTeamInheritance() throws Exception {