Add possibility to override permissions from parent project.

In case if local permissions have the same (category,group,ref) as a
permission from parent, then parent's permission is overriden by the
local one.

Here is an example

ParentProject (READ, group1, refs/*) -> [-1,1] # Allow groupA read project
ChildProject (READ, group1, refs/*) -> [-1,-1] # Override parent's permission.
                                               # Now group1 cannot read the project

Pay attention that is refspec is different from the parent's permission,
then the local permission *adds* rights. An example:

ParentProject (READ, group1, refs/*) -> [-1,1] # Allow groupA read project
ChildProject (READ, group1, refs/tags/*) -> [-1,-1]
 # This permission does nothing as it adds [-1,-1] for refs/tags/*

In this case if you want to disallow to group1 read refs/tags/* then you
need to override parent's permission first.

ParentProject (READ, group1, refs/*) -> [-1,1] # Allow groupA read project
ChildProject (READ, group1, refs/*) -> [-1,-1] # Override parent's permission
ChildProject (READ, group1, -refs/tags/*) -> [-1,1]
 # Explicitly says that group1 has access to everything except refs/tags/*

Change-Id: If183e6255e4a1625b557e3bbc024093b18740d04
This commit is contained in:
Anatol Pomazau
2010-08-30 15:45:26 -07:00
parent 70a7ca0726
commit 69796cb9b7
4 changed files with 144 additions and 74 deletions

View File

@@ -28,6 +28,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@@ -137,16 +139,59 @@ public class ProjectState {
}
/**
* Get the rights this project inherits from the wild project.
* Utility class that is needed to filter overridden refrights
*/
private static class Grant {
final AccountGroup.Id group;
final String pattern;
private Grant(AccountGroup.Id group, String pattern) {
this.group = group;
this.pattern = pattern;
}
@Override
public boolean equals(Object o) {
Grant grant = (Grant) o;
return group.equals(grant.group) && pattern.equals(grant.pattern);
}
@Override
public int hashCode() {
int result = group.hashCode();
result = 31 * result + pattern.hashCode();
return result;
}
}
/**
* Get the rights this project has and inherits from the wild project.
*
* @param action the category requested.
* @param dropOverridden whether to remove inherited permissions in case if we have a
* local one that matches (action,group,ref)
* @return immutable collection of rights for the requested category.
*/
public Collection<RefRight> getInheritedRights(ApprovalCategory.Id action) {
public Collection<RefRight> getAllRights(ApprovalCategory.Id action, boolean dropOverridden) {
Collection<RefRight> rights = new LinkedList<RefRight>(getLocalRights(action));
if (action.canInheritFromWildProject()) {
return filter(getInheritedRights(), action);
rights.addAll(filter(getInheritedRights(), action));
}
return Collections.emptyList();
if (dropOverridden) {
Set<Grant> grants = new HashSet<Grant>();
Iterator<RefRight> iter = rights.iterator();
while (iter.hasNext()) {
RefRight right = iter.next();
Grant grant = new Grant(right.getAccountGroupId(), right.getRefPattern());
if (grants.contains(grant)) {
iter.remove();
} else {
grants.add(grant);
}
}
}
return Collections.unmodifiableCollection(rights);
}
/** Is this the special wild project which manages inherited rights? */