diff options
Diffstat (limited to 'gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java')
-rw-r--r-- | gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java | 377 |
1 files changed, 253 insertions, 124 deletions
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java index 6b0f13a62e..cd6fa699a0 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java +++ b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java @@ -14,44 +14,58 @@ package com.google.gerrit.server.project; -import static com.google.gerrit.reviewdb.ApprovalCategory.OWN; -import static com.google.gerrit.reviewdb.ApprovalCategory.READ; -import static com.google.gerrit.reviewdb.ApprovalCategory.SUBMIT; - -import com.google.gerrit.reviewdb.AccountGroup; -import com.google.gerrit.reviewdb.AccountProjectWatch; -import com.google.gerrit.reviewdb.ApprovalCategory; -import com.google.gerrit.reviewdb.Change; -import com.google.gerrit.reviewdb.Project; -import com.google.gerrit.reviewdb.RefRight; -import com.google.gerrit.reviewdb.SystemConfig; -import com.google.gerrit.reviewdb.RefRight.RefPattern; +import static com.google.gerrit.common.data.Permission.LABEL; +import static com.google.gerrit.common.data.Permission.OWNER; +import static com.google.gerrit.common.data.Permission.PUSH; +import static com.google.gerrit.common.data.Permission.READ; +import static com.google.gerrit.common.data.Permission.SUBMIT; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.gerrit.common.data.Capable; +import com.google.gerrit.common.data.GroupReference; +import com.google.gerrit.common.data.PermissionRange; +import com.google.gerrit.common.data.PermissionRule; +import com.google.gerrit.reviewdb.client.AccountGroup; +import com.google.gerrit.reviewdb.client.AccountProjectWatch; +import com.google.gerrit.reviewdb.client.Change; +import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.reviewdb.server.ReviewDb; +import com.google.gerrit.rules.PrologEnvironment; +import com.google.gerrit.rules.RulesCache; import com.google.gerrit.server.AccessPath; -import com.google.gerrit.server.AnonymousUser; import com.google.gerrit.server.CurrentUser; -import com.google.gerrit.server.config.AuthConfig; +import com.google.gerrit.server.account.CapabilityControl; +import com.google.gerrit.server.account.GroupCache; +import com.google.gerrit.server.account.GroupMembership; +import com.google.gerrit.server.account.ListGroupMembership; +import com.google.gerrit.server.cache.ConcurrentHashMapCache; +import com.google.gerrit.server.config.AllProjectsName; +import com.google.gerrit.server.config.FactoryModule; import com.google.gerrit.server.config.GerritServerConfig; -import com.google.inject.AbstractModule; +import com.google.gerrit.server.git.GitRepositoryManager; +import com.google.gerrit.server.git.ProjectConfig; +import com.google.gwtorm.server.SchemaFactory; import com.google.inject.Guice; import com.google.inject.Injector; import junit.framework.TestCase; -import org.apache.commons.codec.binary.Base64; import org.eclipse.jgit.lib.Config; -import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; -import java.util.List; +import java.util.Map; import java.util.Set; public class RefControlTest extends TestCase { public void testOwnerProject() { - grant(local, OWN, admin, "refs/*", 1); + grant(local, OWNER, admin, "refs/*"); ProjectControl uBlah = user(devs); ProjectControl uAdmin = user(devs, admin); @@ -61,8 +75,8 @@ public class RefControlTest extends TestCase { } public void testBranchDelegation1() { - grant(local, OWN, admin, "refs/*", 1); - grant(local, OWN, devs, "refs/heads/x/*", 1); + grant(local, OWNER, admin, "refs/*"); + grant(local, OWNER, devs, "refs/heads/x/*"); ProjectControl uDev = user(devs); assertFalse("not owner", uDev.isOwner()); @@ -77,9 +91,10 @@ public class RefControlTest extends TestCase { } public void testBranchDelegation2() { - grant(local, OWN, admin, "refs/*", 1); - grant(local, OWN, devs, "refs/heads/x/*", 1); - grant(local, OWN, fixers, "-refs/heads/x/y/*", 1); + grant(local, OWNER, admin, "refs/*"); + grant(local, OWNER, devs, "refs/heads/x/*"); + grant(local, OWNER, fixers, "refs/heads/x/y/*"); + doNotInherit(local, OWNER, "refs/heads/x/y/*"); ProjectControl uDev = user(devs); assertFalse("not owner", uDev.isOwner()); @@ -104,11 +119,14 @@ public class RefControlTest extends TestCase { } public void testInheritRead_SingleBranchDeniesUpload() { - grant(parent, READ, registered, "refs/*", 1, 2); - grant(local, READ, registered, "-refs/heads/foobar", 1); + grant(parent, READ, registered, "refs/*"); + grant(parent, PUSH, registered, "refs/for/refs/*"); + grant(local, READ, registered, "refs/heads/foobar"); + doNotInherit(local, READ, "refs/heads/foobar"); + doNotInherit(local, PUSH, "refs/for/refs/heads/foobar"); ProjectControl u = user(); - assertTrue("can upload", u.canPushToAtLeastOneRef()); + assertTrue("can upload", u.canPushToAtLeastOneRef() == Capable.OK); assertTrue("can upload refs/heads/master", // u.controlForRef("refs/heads/master").canUpload()); @@ -118,11 +136,12 @@ public class RefControlTest extends TestCase { } public void testInheritRead_SingleBranchDoesNotOverrideInherited() { - grant(parent, READ, registered, "refs/*", 1, 2); - grant(local, READ, registered, "refs/heads/foobar", 1); + grant(parent, READ, registered, "refs/*"); + grant(parent, PUSH, registered, "refs/for/refs/*"); + grant(local, READ, registered, "refs/heads/foobar"); ProjectControl u = user(); - assertTrue("can upload", u.canPushToAtLeastOneRef()); + assertTrue("can upload", u.canPushToAtLeastOneRef() == Capable.OK); assertTrue("can upload refs/heads/master", // u.controlForRef("refs/heads/master").canUpload()); @@ -131,17 +150,29 @@ public class RefControlTest extends TestCase { u.controlForRef("refs/heads/foobar").canUpload()); } + public void testInheritDuplicateSections() { + grant(parent, READ, admin, "refs/*"); + grant(local, READ, devs, "refs/heads/*"); + local.getProject().setParentName(parent.getProject().getName()); + assertTrue("a can read", user("a", admin).isVisible()); + + local = new ProjectConfig(new Project.NameKey("local")); + local.createInMemory(); + grant(local, READ, devs, "refs/*"); + assertTrue("d can read", user("d", devs).isVisible()); + } + public void testInheritRead_OverrideWithDeny() { - grant(parent, READ, registered, "refs/*", 1); - grant(local, READ, registered, "refs/*", 0); + grant(parent, READ, registered, "refs/*"); + grant(local, READ, registered, "refs/*").setDeny(); ProjectControl u = user(); assertFalse("can't read", u.isVisible()); } public void testInheritRead_AppendWithDenyOfRef() { - grant(parent, READ, registered, "refs/*", 1); - grant(local, READ, registered, "refs/heads/*", 0); + grant(parent, READ, registered, "refs/*"); + grant(local, READ, registered, "refs/heads/*").setDeny(); ProjectControl u = user(); assertTrue("can read", u.isVisible()); @@ -151,9 +182,9 @@ public class RefControlTest extends TestCase { } public void testInheritRead_OverridesAndDeniesOfRef() { - grant(parent, READ, registered, "refs/*", 1); - grant(local, READ, registered, "refs/*", 0); - grant(local, READ, registered, "refs/heads/*", -1, 1); + grant(parent, READ, registered, "refs/*"); + grant(local, READ, registered, "refs/*").setDeny(); + grant(local, READ, registered, "refs/heads/*"); ProjectControl u = user(); assertTrue("can read", u.isVisible()); @@ -163,9 +194,9 @@ public class RefControlTest extends TestCase { } public void testInheritSubmit_OverridesAndDeniesOfRef() { - grant(parent, SUBMIT, registered, "refs/*", 1); - grant(local, SUBMIT, registered, "refs/*", 0); - grant(local, SUBMIT, registered, "refs/heads/*", -1, 1); + grant(parent, SUBMIT, registered, "refs/*"); + grant(local, SUBMIT, registered, "refs/*").setDeny(); + grant(local, SUBMIT, registered, "refs/heads/*"); ProjectControl u = user(); assertFalse("can't submit", u.controlForRef("refs/foobar").canSubmit()); @@ -174,70 +205,140 @@ public class RefControlTest extends TestCase { } public void testCannotUploadToAnyRef() { - grant(parent, READ, registered, "refs/*", 1); - grant(local, READ, devs, "refs/heads/*", 1, 2); + grant(parent, READ, registered, "refs/*"); + grant(local, READ, devs, "refs/heads/*"); + grant(local, PUSH, devs, "refs/for/refs/heads/*"); ProjectControl u = user(); - assertFalse("cannot upload", u.canPushToAtLeastOneRef()); + assertFalse("cannot upload", u.canPushToAtLeastOneRef() == Capable.OK); assertFalse("cannot upload refs/heads/master", // u.controlForRef("refs/heads/master").canUpload()); } + public void testUsernamePatternNonRegex() { + grant(local, READ, devs, "refs/sb/${username}/heads/*"); + + ProjectControl u = user("u", devs), d = user("d", devs); + assertFalse("u can't read", u.controlForRef("refs/sb/d/heads/foobar").isVisible()); + assertTrue("d can read", d.controlForRef("refs/sb/d/heads/foobar").isVisible()); + } + + public void testUsernamePatternWithRegex() { + grant(local, READ, devs, "^refs/sb/${username}/heads/.*"); + + ProjectControl u = user("d.v", devs), d = user("dev", devs); + assertFalse("u can't read", u.controlForRef("refs/sb/dev/heads/foobar").isVisible()); + assertTrue("d can read", d.controlForRef("refs/sb/dev/heads/foobar").isVisible()); + } + + public void testSortWithRegex() { + grant(local, READ, devs, "^refs/heads/.*"); + grant(parent, READ, anonymous, "^refs/heads/.*-QA-.*"); + + ProjectControl u = user(devs), d = user(devs); + assertTrue("u can read", u.controlForRef("refs/heads/foo-QA-bar").isVisible()); + assertTrue("d can read", d.controlForRef("refs/heads/foo-QA-bar").isVisible()); + } + + public void testBlockRule_ParentBlocksChild() { + grant(local, PUSH, devs, "refs/tags/*"); + grant(parent, PUSH, anonymous, "refs/tags/*").setBlock(); + + ProjectControl u = user(devs); + assertFalse("u can't force update tag", u.controlForRef("refs/tags/V10").canForceUpdate()); + } + + public void testBlockLabelRange_ParentBlocksChild() { + grant(local, LABEL + "Code-Review", -2, +2, devs, "refs/heads/*"); + grant(parent, LABEL + "Code-Review", -2, +2, devs, "refs/heads/*").setBlock(); + + ProjectControl u = user(devs); + PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review"); + assertTrue("u can vote -1", range.contains(-1)); + assertTrue("u can vote +1", range.contains(1)); + assertFalse("u can't vote -2", range.contains(-2)); + assertFalse("u can't vote 2", range.contains(2)); + } // ----------------------------------------------------------------------- - private final Project.NameKey local = new Project.NameKey("test"); - private final Project.NameKey parent = new Project.NameKey("parent"); - private final AccountGroup.Id admin = new AccountGroup.Id(1); - private final AccountGroup.Id anonymous = new AccountGroup.Id(2); - private final AccountGroup.Id registered = new AccountGroup.Id(3); - private final AccountGroup.Id owners = new AccountGroup.Id(4); + private final Map<Project.NameKey, ProjectState> all; + private final AllProjectsName allProjectsName = new AllProjectsName("parent"); + private final ProjectCache projectCache; + + private ProjectConfig local; + private ProjectConfig parent; + private PermissionCollection.Factory sectionSorter; - private final AccountGroup.Id devs = new AccountGroup.Id(5); - private final AccountGroup.Id fixers = new AccountGroup.Id(6); + private final AccountGroup.UUID admin = new AccountGroup.UUID("test.admin"); + private final AccountGroup.UUID anonymous = AccountGroup.ANONYMOUS_USERS; + private final AccountGroup.UUID registered = AccountGroup.REGISTERED_USERS; - private final SystemConfig systemConfig; - private final AuthConfig authConfig; - private final AnonymousUser anonymousUser; + private final AccountGroup.UUID devs = new AccountGroup.UUID("test.devs"); + private final AccountGroup.UUID fixers = new AccountGroup.UUID("test.fixers"); + + private final CapabilityControl.Factory capabilityControlFactory; public RefControlTest() { - systemConfig = SystemConfig.create(); - systemConfig.adminGroupId = admin; - systemConfig.anonymousGroupId = anonymous; - systemConfig.registeredGroupId = registered; - systemConfig.ownerGroupId = owners; - systemConfig.batchUsersGroupId = anonymous; - try { - byte[] bin = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8"); - systemConfig.registerEmailPrivateKey = Base64.encodeBase64String(bin); - } catch (UnsupportedEncodingException err) { - throw new RuntimeException("Cannot encode key", err); - } + all = new HashMap<Project.NameKey, ProjectState>(); + projectCache = new ProjectCache() { + @Override + public ProjectState getAllProjects() { + return get(allProjectsName); + } + + @Override + public ProjectState get(Project.NameKey projectName) { + return all.get(projectName); + } + + @Override + public void evict(Project p) { + } + + @Override + public Iterable<Project.NameKey> all() { + return Collections.emptySet(); + } - Injector injector = Guice.createInjector(new AbstractModule() { + @Override + public Iterable<Project.NameKey> byName(String prefix) { + return Collections.emptySet(); + } + + @Override + public void onCreateProject(Project.NameKey newProjectName) { + } + }; + + Injector injector = Guice.createInjector(new FactoryModule() { @Override protected void configure() { - bind(Config.class) // - .annotatedWith(GerritServerConfig.class) // + bind(Config.class) + .annotatedWith(GerritServerConfig.class) .toInstance(new Config()); - bind(SystemConfig.class).toInstance(systemConfig); - bind(AuthConfig.class); - bind(AnonymousUser.class); + factory(CapabilityControl.Factory.class); + bind(ProjectCache.class).toInstance(projectCache); } }); - authConfig = injector.getInstance(AuthConfig.class); - anonymousUser = injector.getInstance(AnonymousUser.class); + capabilityControlFactory = injector.getInstance(CapabilityControl.Factory.class); } - private List<RefRight> localRights; - private List<RefRight> inheritedRights; - @Override - protected void setUp() throws Exception { + public void setUp() throws Exception { super.setUp(); - localRights = new ArrayList<RefRight>(); - inheritedRights = new ArrayList<RefRight>(); + + parent = new ProjectConfig(new Project.NameKey("parent")); + parent.createInMemory(); + + local = new ProjectConfig(new Project.NameKey("local")); + local.createInMemory(); + + sectionSorter = + new PermissionCollection.Factory( + new SectionSortCache( + new ConcurrentHashMapCache<SectionSortCache.EntryKey, SectionSortCache.EntryVal>())); } private static void assertOwner(String ref, ProjectControl u) { @@ -248,68 +349,96 @@ public class RefControlTest extends TestCase { assertFalse("NOT OWN " + ref, u.controlForRef(ref).isOwner()); } - private void grant(Project.NameKey project, ApprovalCategory.Id categoryId, - AccountGroup.Id group, String ref, int maxValue) { - grant(project, categoryId, group, ref, maxValue, maxValue); + private PermissionRule grant(ProjectConfig project, String permissionName, + AccountGroup.UUID group, String ref) { + return grant(project, permissionName, newRule(project, group), ref); } - private void grant(Project.NameKey project, ApprovalCategory.Id categoryId, AccountGroup.Id group, - String ref, int minValue, int maxValue) { - RefRight right = - new RefRight(new RefRight.Key(project, new RefPattern(ref), - categoryId, group)); - right.setMinValue((short) minValue); - right.setMaxValue((short) maxValue); - - if (project == parent) { - inheritedRights.add(right); - } else if (project == local) { - localRights.add(right); - } else { - fail("Unknown project key: " + project); - } + private PermissionRule grant(ProjectConfig project, String permissionName, + int min, int max, AccountGroup.UUID group, String ref) { + PermissionRule rule = newRule(project, group); + rule.setMin(min); + rule.setMax(max); + return grant(project, permissionName, rule, ref); } - private ProjectControl user(AccountGroup.Id... memberOf) { - RefControl.Factory refControlFactory = new RefControl.Factory() { - @Override - public RefControl create(final ProjectControl projectControl, final String ref) { - return new RefControl(systemConfig, projectControl, ref); - } - }; - return new ProjectControl(systemConfig, - Collections.<AccountGroup.Id> emptySet(), - Collections.<AccountGroup.Id> emptySet(), refControlFactory, - new MockUser(memberOf), newProjectState()); + + private PermissionRule grant(ProjectConfig project, String permissionName, + PermissionRule rule, String ref) { + project.getAccessSection(ref, true) // + .getPermission(permissionName, true) // + .add(rule); + return rule; + } + + private void doNotInherit(ProjectConfig project, String permissionName, + String ref) { + project.getAccessSection(ref, true) // + .getPermission(permissionName, true) // + .setExclusiveGroup(true); + } + + private PermissionRule newRule(ProjectConfig project, AccountGroup.UUID groupUUID) { + GroupReference group = new GroupReference(groupUUID, groupUUID.get()); + group = project.resolve(group); + + return new PermissionRule(group); + } + + private ProjectControl user(AccountGroup.UUID... memberOf) { + return user(null, memberOf); + } + + private ProjectControl user(String name, AccountGroup.UUID... memberOf) { + SchemaFactory<ReviewDb> schema = null; + GroupCache groupCache = null; + String canonicalWebUrl = "http://localhost"; + + return new ProjectControl(Collections.<AccountGroup.UUID> emptySet(), + Collections.<AccountGroup.UUID> emptySet(), schema, groupCache, + sectionSorter, + canonicalWebUrl, new MockUser(name, memberOf), + newProjectState()); } private ProjectState newProjectState() { - ProjectCache projectCache = null; - Project.NameKey wildProject = new Project.NameKey("-- All Projects --"); + PrologEnvironment.Factory envFactory = null; + GitRepositoryManager mgr = null; ProjectControl.AssistedFactory projectControlFactory = null; - ProjectState ps = - new ProjectState(anonymousUser, projectCache, wildProject, - projectControlFactory, new Project(parent), localRights); - ps.setInheritedRights(inheritedRights); - return ps; + RulesCache rulesCache = null; + all.put(local.getProject().getNameKey(), new ProjectState( + projectCache, allProjectsName, projectControlFactory, + envFactory, mgr, rulesCache, local)); + all.put(parent.getProject().getNameKey(), new ProjectState( + projectCache, allProjectsName, projectControlFactory, + envFactory, mgr, rulesCache, parent)); + return all.get(local.getProject().getNameKey()); } private class MockUser extends CurrentUser { - private final Set<AccountGroup.Id> groups; - - MockUser(AccountGroup.Id[] groupId) { - super(AccessPath.UNKNOWN, RefControlTest.this.authConfig); - groups = new HashSet<AccountGroup.Id>(Arrays.asList(groupId)); - groups.add(registered); - groups.add(anonymous); + private final String username; + private final GroupMembership groups; + + MockUser(String name, AccountGroup.UUID[] groupId) { + super(RefControlTest.this.capabilityControlFactory, AccessPath.UNKNOWN); + username = name; + ArrayList<AccountGroup.UUID> groupIds = Lists.newArrayList(groupId); + groupIds.add(registered); + groupIds.add(anonymous); + groups = new ListGroupMembership(groupIds); } @Override - public Set<AccountGroup.Id> getEffectiveGroups() { + public GroupMembership getEffectiveGroups() { return groups; } @Override + public String getUserName() { + return username; + } + + @Override public Set<Change.Id> getStarredChanges() { return Collections.emptySet(); } |