James Moger
2013-05-02 9715e11fe30eccafa4c8272316883c80ba036a6e
Improve permission determination when repo is frozen or is not bare
5 files modified
122 ■■■■ changed files
src/main/java/com/gitblit/Constants.java 6 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/models/RepositoryModel.java 1 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/models/TeamModel.java 33 ●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/models/UserModel.java 47 ●●●● patch | view | raw | blame | history
src/test/java/com/gitblit/tests/PermissionsTest.java 35 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/Constants.java
@@ -385,7 +385,11 @@
        private AccessPermission(String code) {
            this.code = code;
        }
        public boolean atMost(AccessPermission perm) {
            return ordinal() <= perm.ordinal();
        }
        public boolean atLeast(AccessPermission perm) {
            return ordinal() >= perm.ordinal();
        }
src/main/java/com/gitblit/models/RepositoryModel.java
@@ -101,6 +101,7 @@
        this.federationStrategy = FederationStrategy.FEDERATE_THIS;    
        this.projectPath = StringUtils.getFirstPathElement(name);
        this.owners = new ArrayList<String>();
        this.isBare = true;
        
        addOwner(owner);
    }
src/main/java/com/gitblit/models/TeamModel.java
@@ -197,16 +197,29 @@
        ap.permission = AccessPermission.NONE;
        ap.mutable = false;
        
        // determine maximum permission for the repository
        final AccessPermission maxPermission =
                (repository.isFrozen || !repository.isBare) ?
                        AccessPermission.CLONE : AccessPermission.REWIND;
        if (AccessRestrictionType.NONE.equals(repository.accessRestriction)) {
            // anonymous rewind
            ap.permissionType = PermissionType.ANONYMOUS;
            ap.permission = AccessPermission.REWIND;
            if (AccessPermission.REWIND.atMost(maxPermission)) {
                ap.permission = AccessPermission.REWIND;
            } else {
                ap.permission = maxPermission;
            }
            return ap;
        }
        
        if (canAdmin) {
            ap.permissionType = PermissionType.ADMINISTRATOR;
            ap.permission = AccessPermission.REWIND;
            if (AccessPermission.REWIND.atMost(maxPermission)) {
                ap.permission = AccessPermission.REWIND;
            } else {
                ap.permission = maxPermission;
            }
            return ap;
        }
        
@@ -215,7 +228,11 @@
            AccessPermission p = permissions.get(repository.name.toLowerCase());
            if (p != null && repository.accessRestriction.isValidPermission(p)) {
                ap.permissionType = PermissionType.EXPLICIT;
                ap.permission = p;
                if (p.atMost(maxPermission)) {
                    ap.permission = p;
                } else {
                    ap.permission = maxPermission;
                }
                ap.mutable = true;
                return ap;
            }
@@ -227,7 +244,11 @@
                    if (p != null && repository.accessRestriction.isValidPermission(p)) {
                        // take first match
                        ap.permissionType = PermissionType.REGEX;
                        ap.permission = p;
                        if (p.atMost(maxPermission)) {
                            ap.permission = p;
                        } else {
                            ap.permission = maxPermission;
                        }
                        ap.source = key;
                        return ap;
                    }
@@ -252,8 +273,8 @@
                ap.permissionType = PermissionType.ANONYMOUS;
                break;
            case NONE:
                // implied REWIND or CLONE if frozen
                ap.permission = repository.isFrozen ? AccessPermission.CLONE : AccessPermission.REWIND;
                // implied REWIND or CLONE
                ap.permission = maxPermission;
                ap.permissionType = PermissionType.ANONYMOUS;
                break;
            }
src/main/java/com/gitblit/models/UserModel.java
@@ -278,18 +278,31 @@
        ap.registrantType = RegistrantType.USER;
        ap.permission = AccessPermission.NONE;
        ap.mutable = false;
        // determine maximum permission for the repository
        final AccessPermission maxPermission =
                (repository.isFrozen || !repository.isBare) ?
                        AccessPermission.CLONE : AccessPermission.REWIND;
        if (AccessRestrictionType.NONE.equals(repository.accessRestriction)) {
            // anonymous rewind
            ap.permissionType = PermissionType.ANONYMOUS;
            ap.permission = AccessPermission.REWIND;
            if (AccessPermission.REWIND.atMost(maxPermission)) {
                ap.permission = AccessPermission.REWIND;
            } else {
                ap.permission = maxPermission;
            }
            return ap;
        }
        // administrator
        if (canAdmin()) {
            ap.permissionType = PermissionType.ADMINISTRATOR;
            ap.permission = AccessPermission.REWIND;
            if (AccessPermission.REWIND.atMost(maxPermission)) {
                ap.permission = AccessPermission.REWIND;
            } else {
                ap.permission = maxPermission;
            }
            if (!canAdmin) {
                // administator permission from team membership
                for (TeamModel team : teams) {
@@ -305,13 +318,21 @@
        // repository owner - either specified owner or personal repository
        if (repository.isOwner(username) || repository.isUsersPersonalRepository(username)) {
            ap.permissionType = PermissionType.OWNER;
            ap.permission = AccessPermission.REWIND;
            if (AccessPermission.REWIND.atMost(maxPermission)) {
                ap.permission = AccessPermission.REWIND;
            } else {
                ap.permission = maxPermission;
            }
            return ap;
        }
        
        if (AuthorizationControl.AUTHENTICATED.equals(repository.authorizationControl) && isAuthenticated) {
            // AUTHENTICATED is a shortcut for authorizing all logged-in users RW+ access
            ap.permission = AccessPermission.REWIND;
            if (AccessPermission.REWIND.atMost(maxPermission)) {
                ap.permission = AccessPermission.REWIND;
            } else {
                ap.permission = maxPermission;
            }
            return ap;
        }
        
@@ -322,7 +343,11 @@
            AccessPermission p = permissions.get(repository.name.toLowerCase());
            if (p != null && repository.accessRestriction.isValidPermission(p)) {
                ap.permissionType = PermissionType.EXPLICIT;
                ap.permission = p;
                if (p.atMost(maxPermission)) {
                    ap.permission = p;
                } else {
                    ap.permission = maxPermission;
                }
                ap.mutable = true;
                return ap;
            }
@@ -334,7 +359,11 @@
                    if (p != null && repository.accessRestriction.isValidPermission(p)) {
                        // take first match
                        ap.permissionType = PermissionType.REGEX;
                        ap.permission = p;
                        if (p.atMost(maxPermission)) {
                            ap.permission = p;
                        } else {
                            ap.permission = maxPermission;
                        }
                        ap.source = key;
                        return ap;
                    }
@@ -345,7 +374,7 @@
        // try to find a team match
        for (TeamModel team : teams) {
            RegistrantAccessPermission p = team.getRepositoryPermission(repository);
            if (p.permission.exceeds(ap.permission) && PermissionType.ANONYMOUS != p.permissionType) {
            if (p.permission.atMost(maxPermission) && p.permission.exceeds(ap.permission) && PermissionType.ANONYMOUS != p.permissionType) {
                // use highest team permission that is not an implicit permission
                ap.permission = p.permission;
                ap.source = team.name;
@@ -370,8 +399,8 @@
                ap.permissionType = PermissionType.ANONYMOUS;
                break;
            case NONE:
                // implied REWIND or CLONE if frozen
                ap.permission = repository.isFrozen ? AccessPermission.CLONE : AccessPermission.REWIND;
                // implied REWIND or CLONE
                ap.permission = maxPermission;
                ap.permissionType = PermissionType.ANONYMOUS;
                break;
            }
src/test/java/com/gitblit/tests/PermissionsTest.java
@@ -2843,4 +2843,39 @@
        assertTrue("User did not inherit create privileges", user.canCreate());
    }
    @Test
    public void testIsFrozen() throws Exception {
        RepositoryModel repo = new RepositoryModel("somerepo.git", null, null, new Date());
        repo.authorizationControl = AuthorizationControl.NAMED;
        repo.accessRestriction = AccessRestrictionType.NONE;
        UserModel user = new UserModel("test");
        TeamModel team = new TeamModel("team");
        assertEquals("user has wrong permission!", AccessPermission.REWIND, user.getRepositoryPermission(repo).permission);
        assertEquals("team has wrong permission!", AccessPermission.REWIND, team.getRepositoryPermission(repo).permission);
        // freeze repo
        repo.isFrozen = true;
        assertEquals("user has wrong permission!", AccessPermission.CLONE, user.getRepositoryPermission(repo).permission);
        assertEquals("team has wrong permission!", AccessPermission.CLONE, team.getRepositoryPermission(repo).permission);
    }
    @Test
    public void testIsBare() throws Exception {
        RepositoryModel repo = new RepositoryModel("somerepo.git", null, null, new Date());
        repo.authorizationControl = AuthorizationControl.NAMED;
        repo.accessRestriction = AccessRestrictionType.NONE;
        UserModel user = new UserModel("test");
        TeamModel team = new TeamModel("team");
        assertEquals("user has wrong permission!", AccessPermission.REWIND, user.getRepositoryPermission(repo).permission);
        assertEquals("team has wrong permission!", AccessPermission.REWIND, team.getRepositoryPermission(repo).permission);
        // set repo to have a working copy, pushes prohibited
        repo.isBare = false;
        assertEquals("user has wrong permission!", AccessPermission.CLONE, user.getRepositoryPermission(repo).permission);
        assertEquals("team has wrong permission!", AccessPermission.CLONE, team.getRepositoryPermission(repo).permission);
    }
}