Prevent deletion (and creation) of refs/meta/group-names

This branch guarantees unique group names for groups in NoteDb. It must
not be possible to delete it.

Change-Id: Iceaa1820c81e58914c7fdaa6b22592161a07875f
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2017-11-20 10:54:22 +01:00
parent ddbfb0f10a
commit d7848539ca
2 changed files with 47 additions and 6 deletions

View File

@@ -149,7 +149,8 @@ public class RefOperationValidators {
} }
} }
if (refEvent.command.getRefName().startsWith(RefNames.REFS_GROUPS)) { if (refEvent.command.getRefName().startsWith(RefNames.REFS_GROUPS)
|| refEvent.command.getRefName().equals(RefNames.REFS_GROUPNAMES)) {
if (refEvent.command.getType().equals(ReceiveCommand.Type.CREATE)) { if (refEvent.command.getType().equals(ReceiveCommand.Type.CREATE)) {
throw new ValidationException("Not allowed to create group branch."); throw new ValidationException("Not allowed to create group branch.");
} else if (refEvent.command.getType().equals(ReceiveCommand.Type.DELETE)) { } else if (refEvent.command.getType().equals(ReceiveCommand.Type.DELETE)) {

View File

@@ -985,10 +985,36 @@ public class GroupsIT extends AbstractDaemonTest {
@Test @Test
@Sandboxed @Sandboxed
public void cannotCreateGroupBranch() throws Exception { public void cannotCreateGroupBranch() throws Exception {
grant(allUsers, RefNames.REFS_GROUPS + "*", Permission.CREATE); testCannotCreateGroupBranch(
grant(allUsers, RefNames.REFS_GROUPS + "*", Permission.PUSH); RefNames.REFS_GROUPS + "*", RefNames.refsGroups(new AccountGroup.UUID(name("foo"))));
}
@Test
@Sandboxed
public void cannotCreateGroupNamesBranch() throws Exception {
assume().that(groupsInNoteDb()).isTrue();
// Manually delete group names ref
try (Repository repo = repoManager.openRepository(allUsers);
RevWalk rw = new RevWalk(repo)) {
RevCommit commit = rw.parseCommit(repo.exactRef(RefNames.REFS_GROUPNAMES).getObjectId());
RefUpdate updateRef = repo.updateRef(RefNames.REFS_GROUPNAMES);
updateRef.setExpectedOldObjectId(commit.toObjectId());
updateRef.setNewObjectId(ObjectId.zeroId());
updateRef.setForceUpdate(true);
assertThat(updateRef.delete()).isEqualTo(RefUpdate.Result.FORCED);
}
// refs/meta/group-names is only visible with ACCESS_DATABASE
allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
testCannotCreateGroupBranch(RefNames.REFS_GROUPNAMES, RefNames.REFS_GROUPNAMES);
}
private void testCannotCreateGroupBranch(String refPattern, String groupRef) throws Exception {
grant(allUsers, refPattern, Permission.CREATE);
grant(allUsers, refPattern, Permission.PUSH);
String groupRef = RefNames.refsGroups(new AccountGroup.UUID(name("foo")));
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers); TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
PushOneCommit.Result r = pushFactory.create(db, admin.getIdent(), allUsersRepo).to(groupRef); PushOneCommit.Result r = pushFactory.create(db, admin.getIdent(), allUsersRepo).to(groupRef);
r.assertErrorStatus(); r.assertErrorStatus();
@@ -1003,9 +1029,23 @@ public class GroupsIT extends AbstractDaemonTest {
@Sandboxed @Sandboxed
public void cannotDeleteGroupBranch() throws Exception { public void cannotDeleteGroupBranch() throws Exception {
assume().that(groupsInNoteDb()).isTrue(); assume().that(groupsInNoteDb()).isTrue();
testCannotDeleteGroupBranch(RefNames.REFS_GROUPS + "*", RefNames.refsGroups(adminGroupUuid()));
}
@Test
@Sandboxed
public void cannotDeleteGroupNamesBranch() throws Exception {
assume().that(groupsInNoteDb()).isTrue();
// refs/meta/group-names is only visible with ACCESS_DATABASE
allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
testCannotDeleteGroupBranch(RefNames.REFS_GROUPNAMES, RefNames.REFS_GROUPNAMES);
}
private void testCannotDeleteGroupBranch(String refPattern, String groupRef) throws Exception {
grant(allUsers, refPattern, Permission.DELETE, true, REGISTERED_USERS);
grant(allUsers, RefNames.REFS_GROUPS + "*", Permission.DELETE, true, REGISTERED_USERS);
String groupRef = RefNames.refsGroups(adminGroupUuid());
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers); TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
PushResult r = deleteRef(allUsersRepo, groupRef); PushResult r = deleteRef(allUsersRepo, groupRef);
RemoteRefUpdate refUpdate = r.getRemoteUpdate(groupRef); RemoteRefUpdate refUpdate = r.getRemoteUpdate(groupRef);