315 lines
13 KiB
Java
315 lines
13 KiB
Java
// Copyright (C) 2017 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package com.google.gerrit.server.group.db;
|
|
|
|
import static com.google.common.truth.Truth.assertThat;
|
|
|
|
import com.google.common.collect.ImmutableSet;
|
|
import com.google.common.collect.Sets;
|
|
import com.google.gerrit.reviewdb.client.Account;
|
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
|
import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
|
|
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
|
|
import com.google.gerrit.server.account.GroupUUID;
|
|
import com.google.gerrit.server.group.InternalGroup;
|
|
import java.sql.Timestamp;
|
|
import java.util.Set;
|
|
import org.eclipse.jgit.lib.PersonIdent;
|
|
import org.junit.Before;
|
|
import org.junit.Test;
|
|
|
|
/** Unit tests for {@link AuditLogReader}. */
|
|
public final class AuditLogReaderTest extends AbstractGroupTest {
|
|
|
|
private AuditLogReader auditLogReader;
|
|
|
|
@Before
|
|
public void setUp() throws Exception {
|
|
auditLogReader = new AuditLogReader(SERVER_ID, allUsersName);
|
|
}
|
|
|
|
@Test
|
|
public void createGroupAsUserIdent() throws Exception {
|
|
InternalGroup group = createGroupAsUser(1, "test-group");
|
|
AccountGroup.UUID uuid = group.getGroupUUID();
|
|
|
|
AccountGroupMemberAudit expAudit =
|
|
createExpMemberAudit(group.getId(), userId, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid)).containsExactly(expAudit);
|
|
}
|
|
|
|
@Test
|
|
public void createGroupAsServerIdent() throws Exception {
|
|
InternalGroup group = createGroup(1, "test-group", serverIdent, null);
|
|
assertThat(auditLogReader.getMembersAudit(allUsersRepo, group.getGroupUUID())).isEmpty();
|
|
}
|
|
|
|
@Test
|
|
public void addAndRemoveMember() throws Exception {
|
|
InternalGroup group = createGroupAsUser(1, "test-group");
|
|
AccountGroup.UUID uuid = group.getGroupUUID();
|
|
|
|
AccountGroupMemberAudit expAudit1 =
|
|
createExpMemberAudit(group.getId(), userId, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid)).containsExactly(expAudit1);
|
|
|
|
// User adds account 100002 to the group.
|
|
Account.Id id = new Account.Id(100002);
|
|
addMembers(uuid, ImmutableSet.of(id));
|
|
|
|
AccountGroupMemberAudit expAudit2 =
|
|
createExpMemberAudit(group.getId(), id, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid))
|
|
.containsExactly(expAudit1, expAudit2)
|
|
.inOrder();
|
|
|
|
// User removes account 100002 from the group.
|
|
removeMembers(uuid, ImmutableSet.of(id));
|
|
|
|
expAudit2.removed(userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid))
|
|
.containsExactly(expAudit1, expAudit2)
|
|
.inOrder();
|
|
}
|
|
|
|
@Test
|
|
public void addMultiMembers() throws Exception {
|
|
InternalGroup group = createGroupAsUser(1, "test-group");
|
|
AccountGroup.Id groupId = group.getId();
|
|
AccountGroup.UUID uuid = group.getGroupUUID();
|
|
|
|
AccountGroupMemberAudit expAudit1 =
|
|
createExpMemberAudit(groupId, userId, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid)).containsExactly(expAudit1);
|
|
|
|
Account.Id id1 = new Account.Id(100002);
|
|
Account.Id id2 = new Account.Id(100003);
|
|
addMembers(uuid, ImmutableSet.of(id1, id2));
|
|
|
|
AccountGroupMemberAudit expAudit2 =
|
|
createExpMemberAudit(groupId, id1, userId, getTipTimestamp(uuid));
|
|
AccountGroupMemberAudit expAudit3 =
|
|
createExpMemberAudit(groupId, id2, userId, getTipTimestamp(uuid));
|
|
|
|
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid))
|
|
.containsExactly(expAudit1, expAudit2, expAudit3)
|
|
.inOrder();
|
|
}
|
|
|
|
@Test
|
|
public void addAndRemoveSubgroups() throws Exception {
|
|
InternalGroup group = createGroupAsUser(1, "test-group");
|
|
AccountGroup.UUID uuid = group.getGroupUUID();
|
|
|
|
InternalGroup subgroup = createGroupAsUser(2, "test-group-2");
|
|
AccountGroup.UUID subgroupUuid = subgroup.getGroupUUID();
|
|
|
|
addSubgroups(uuid, ImmutableSet.of(subgroupUuid));
|
|
|
|
AccountGroupByIdAud expAudit =
|
|
createExpGroupAudit(group.getId(), subgroupUuid, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid)).containsExactly(expAudit);
|
|
|
|
removeSubgroups(uuid, ImmutableSet.of(subgroupUuid));
|
|
|
|
expAudit.removed(userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid)).containsExactly(expAudit);
|
|
}
|
|
|
|
@Test
|
|
public void addMultiSubgroups() throws Exception {
|
|
InternalGroup group = createGroupAsUser(1, "test-group");
|
|
AccountGroup.UUID uuid = group.getGroupUUID();
|
|
|
|
InternalGroup subgroup1 = createGroupAsUser(2, "test-group-2");
|
|
InternalGroup subgroup2 = createGroupAsUser(3, "test-group-3");
|
|
AccountGroup.UUID subgroupUuid1 = subgroup1.getGroupUUID();
|
|
AccountGroup.UUID subgroupUuid2 = subgroup2.getGroupUUID();
|
|
|
|
addSubgroups(uuid, ImmutableSet.of(subgroupUuid1, subgroupUuid2));
|
|
|
|
AccountGroupByIdAud expAudit1 =
|
|
createExpGroupAudit(group.getId(), subgroupUuid1, userId, getTipTimestamp(uuid));
|
|
AccountGroupByIdAud expAudit2 =
|
|
createExpGroupAudit(group.getId(), subgroupUuid2, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid))
|
|
.containsExactly(expAudit1, expAudit2)
|
|
.inOrder();
|
|
}
|
|
|
|
@Test
|
|
public void addAndRemoveMembersAndSubgroups() throws Exception {
|
|
InternalGroup group = createGroupAsUser(1, "test-group");
|
|
AccountGroup.Id groupId = group.getId();
|
|
AccountGroup.UUID uuid = group.getGroupUUID();
|
|
AccountGroupMemberAudit expMemberAudit =
|
|
createExpMemberAudit(groupId, userId, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid)).containsExactly(expMemberAudit);
|
|
|
|
Account.Id id1 = new Account.Id(100002);
|
|
Account.Id id2 = new Account.Id(100003);
|
|
Account.Id id3 = new Account.Id(100004);
|
|
InternalGroup subgroup1 = createGroupAsUser(2, "test-group-2");
|
|
InternalGroup subgroup2 = createGroupAsUser(3, "test-group-3");
|
|
InternalGroup subgroup3 = createGroupAsUser(4, "test-group-4");
|
|
AccountGroup.UUID subgroupUuid1 = subgroup1.getGroupUUID();
|
|
AccountGroup.UUID subgroupUuid2 = subgroup2.getGroupUUID();
|
|
AccountGroup.UUID subgroupUuid3 = subgroup3.getGroupUUID();
|
|
|
|
// Add two accounts.
|
|
addMembers(uuid, ImmutableSet.of(id1, id2));
|
|
AccountGroupMemberAudit expMemberAudit1 =
|
|
createExpMemberAudit(groupId, id1, userId, getTipTimestamp(uuid));
|
|
AccountGroupMemberAudit expMemberAudit2 =
|
|
createExpMemberAudit(groupId, id2, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid))
|
|
.containsExactly(expMemberAudit, expMemberAudit1, expMemberAudit2)
|
|
.inOrder();
|
|
|
|
// Add one subgroup.
|
|
addSubgroups(uuid, ImmutableSet.of(subgroupUuid1));
|
|
AccountGroupByIdAud expGroupAudit1 =
|
|
createExpGroupAudit(group.getId(), subgroupUuid1, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid))
|
|
.containsExactly(expGroupAudit1);
|
|
|
|
// Remove one account.
|
|
removeMembers(uuid, ImmutableSet.of(id2));
|
|
expMemberAudit2.removed(userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid))
|
|
.containsExactly(expMemberAudit, expMemberAudit1, expMemberAudit2)
|
|
.inOrder();
|
|
|
|
// Add two subgroups.
|
|
addSubgroups(uuid, ImmutableSet.of(subgroupUuid2, subgroupUuid3));
|
|
AccountGroupByIdAud expGroupAudit2 =
|
|
createExpGroupAudit(group.getId(), subgroupUuid2, userId, getTipTimestamp(uuid));
|
|
AccountGroupByIdAud expGroupAudit3 =
|
|
createExpGroupAudit(group.getId(), subgroupUuid3, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid))
|
|
.containsExactly(expGroupAudit1, expGroupAudit2, expGroupAudit3)
|
|
.inOrder();
|
|
|
|
// Add two account, including a removed account.
|
|
addMembers(uuid, ImmutableSet.of(id2, id3));
|
|
AccountGroupMemberAudit expMemberAudit4 =
|
|
createExpMemberAudit(groupId, id2, userId, getTipTimestamp(uuid));
|
|
AccountGroupMemberAudit expMemberAudit3 =
|
|
createExpMemberAudit(groupId, id3, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid))
|
|
.containsExactly(
|
|
expMemberAudit, expMemberAudit1, expMemberAudit2, expMemberAudit4, expMemberAudit3)
|
|
.inOrder();
|
|
|
|
// Remove two subgroups.
|
|
removeSubgroups(uuid, ImmutableSet.of(subgroupUuid1, subgroupUuid3));
|
|
expGroupAudit1.removed(userId, getTipTimestamp(uuid));
|
|
expGroupAudit3.removed(userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid))
|
|
.containsExactly(expGroupAudit1, expGroupAudit2, expGroupAudit3)
|
|
.inOrder();
|
|
|
|
// Add back one removed subgroup.
|
|
addSubgroups(uuid, ImmutableSet.of(subgroupUuid1));
|
|
AccountGroupByIdAud expGroupAudit4 =
|
|
createExpGroupAudit(group.getId(), subgroupUuid1, userId, getTipTimestamp(uuid));
|
|
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid))
|
|
.containsExactly(expGroupAudit1, expGroupAudit2, expGroupAudit3, expGroupAudit4)
|
|
.inOrder();
|
|
}
|
|
|
|
private InternalGroup createGroupAsUser(int next, String groupName) throws Exception {
|
|
return createGroup(next, groupName, userIdent, userId);
|
|
}
|
|
|
|
private InternalGroup createGroup(
|
|
int next, String groupName, PersonIdent authorIdent, Account.Id authorId) throws Exception {
|
|
InternalGroupCreation groupCreation =
|
|
InternalGroupCreation.builder()
|
|
.setGroupUUID(GroupUUID.make(groupName, serverIdent))
|
|
.setNameKey(new AccountGroup.NameKey(groupName))
|
|
.setId(new AccountGroup.Id(next))
|
|
.build();
|
|
InternalGroupUpdate groupUpdate =
|
|
authorIdent.equals(serverIdent)
|
|
? InternalGroupUpdate.builder().setDescription("Groups").build()
|
|
: InternalGroupUpdate.builder()
|
|
.setDescription("Groups")
|
|
.setMemberModification(members -> ImmutableSet.of(authorId))
|
|
.build();
|
|
|
|
GroupConfig groupConfig =
|
|
GroupConfig.createForNewGroup(allUsersName, allUsersRepo, groupCreation);
|
|
groupConfig.setGroupUpdate(groupUpdate, getAuditLogFormatter());
|
|
|
|
groupConfig.commit(createMetaDataUpdate(authorIdent));
|
|
return groupConfig
|
|
.getLoadedGroup()
|
|
.orElseThrow(() -> new IllegalStateException("create group failed"));
|
|
}
|
|
|
|
private void updateGroup(AccountGroup.UUID uuid, InternalGroupUpdate groupUpdate)
|
|
throws Exception {
|
|
GroupConfig groupConfig = GroupConfig.loadForGroup(allUsersName, allUsersRepo, uuid);
|
|
groupConfig.setGroupUpdate(groupUpdate, getAuditLogFormatter());
|
|
groupConfig.commit(createMetaDataUpdate(userIdent));
|
|
}
|
|
|
|
private void addMembers(AccountGroup.UUID groupUuid, Set<Account.Id> ids) throws Exception {
|
|
InternalGroupUpdate update =
|
|
InternalGroupUpdate.builder()
|
|
.setMemberModification(memberIds -> Sets.union(memberIds, ids))
|
|
.build();
|
|
updateGroup(groupUuid, update);
|
|
}
|
|
|
|
private void removeMembers(AccountGroup.UUID groupUuid, Set<Account.Id> ids) throws Exception {
|
|
InternalGroupUpdate update =
|
|
InternalGroupUpdate.builder()
|
|
.setMemberModification(memberIds -> Sets.difference(memberIds, ids))
|
|
.build();
|
|
updateGroup(groupUuid, update);
|
|
}
|
|
|
|
private void addSubgroups(AccountGroup.UUID groupUuid, Set<AccountGroup.UUID> uuids)
|
|
throws Exception {
|
|
InternalGroupUpdate update =
|
|
InternalGroupUpdate.builder()
|
|
.setSubgroupModification(memberIds -> Sets.union(memberIds, uuids))
|
|
.build();
|
|
updateGroup(groupUuid, update);
|
|
}
|
|
|
|
private void removeSubgroups(AccountGroup.UUID groupUuid, Set<AccountGroup.UUID> uuids)
|
|
throws Exception {
|
|
InternalGroupUpdate update =
|
|
InternalGroupUpdate.builder()
|
|
.setSubgroupModification(memberIds -> Sets.difference(memberIds, uuids))
|
|
.build();
|
|
updateGroup(groupUuid, update);
|
|
}
|
|
|
|
private static AccountGroupMemberAudit createExpMemberAudit(
|
|
AccountGroup.Id groupId, Account.Id id, Account.Id addedBy, Timestamp addedOn) {
|
|
return new AccountGroupMemberAudit(
|
|
new AccountGroupMemberAudit.Key(id, groupId, addedOn), addedBy);
|
|
}
|
|
|
|
private static AccountGroupByIdAud createExpGroupAudit(
|
|
AccountGroup.Id groupId, AccountGroup.UUID uuid, Account.Id addedBy, Timestamp addedOn) {
|
|
return new AccountGroupByIdAud(new AccountGroupByIdAud.Key(groupId, uuid, addedOn), addedBy);
|
|
}
|
|
}
|