@@ -385,7 +385,11 @@ public class Constants { | |||
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(); | |||
} |
@@ -101,6 +101,7 @@ public class RepositoryModel implements Serializable, Comparable<RepositoryModel | |||
this.federationStrategy = FederationStrategy.FEDERATE_THIS; | |||
this.projectPath = StringUtils.getFirstPathElement(name); | |||
this.owners = new ArrayList<String>(); | |||
this.isBare = true; | |||
addOwner(owner); | |||
} |
@@ -197,16 +197,29 @@ public class TeamModel implements Serializable, Comparable<TeamModel> { | |||
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 @@ public class TeamModel implements Serializable, Comparable<TeamModel> { | |||
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 @@ public class TeamModel implements Serializable, Comparable<TeamModel> { | |||
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 @@ public class TeamModel implements Serializable, Comparable<TeamModel> { | |||
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; | |||
} |
@@ -278,18 +278,31 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel> | |||
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 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel> | |||
// 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 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel> | |||
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 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel> | |||
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 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel> | |||
// 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 @@ public class UserModel implements Principal, Serializable, Comparable<UserModel> | |||
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; | |||
} |
@@ -2843,4 +2843,39 @@ public class PermissionsTest extends Assert { | |||
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); | |||
} | |||
} |