767 lines
47 KiB
Java
767 lines
47 KiB
Java
package org.whispersystems.signalservice.api.groupsv2;
|
|
|
|
import com.google.protobuf.ByteString;
|
|
|
|
import org.junit.Test;
|
|
import org.signal.storageservice.protos.groups.AccessControl;
|
|
import org.signal.storageservice.protos.groups.Member;
|
|
import org.signal.storageservice.protos.groups.local.DecryptedApproveMember;
|
|
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
|
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
|
import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
|
import org.signal.storageservice.protos.groups.local.DecryptedModifyMemberRole;
|
|
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
|
import org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval;
|
|
import org.signal.storageservice.protos.groups.local.DecryptedRequestingMember;
|
|
import org.signal.storageservice.protos.groups.local.DecryptedString;
|
|
import org.signal.storageservice.protos.groups.local.DecryptedTimer;
|
|
import org.signal.zkgroup.profiles.ProfileKey;
|
|
import org.whispersystems.signalservice.api.util.UuidUtil;
|
|
import org.whispersystems.signalservice.internal.util.Util;
|
|
|
|
import java.util.UUID;
|
|
|
|
import static org.junit.Assert.assertEquals;
|
|
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.admin;
|
|
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.asAdmin;
|
|
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.asMember;
|
|
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.member;
|
|
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.newProfileKey;
|
|
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.pendingMember;
|
|
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.randomProfileKey;
|
|
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.requestingMember;
|
|
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.withProfileKey;
|
|
import static org.whispersystems.signalservice.api.groupsv2.ProtobufTestUtils.getMaxDeclaredFieldNumber;
|
|
|
|
public final class DecryptedGroupUtil_apply_Test {
|
|
|
|
/**
|
|
* Reflects over the generated protobuf class and ensures that no new fields have been added since we wrote this.
|
|
* <p>
|
|
* If we didn't, newly added fields would not be applied by {@link DecryptedGroupUtil#apply}.
|
|
*/
|
|
@Test
|
|
public void ensure_DecryptedGroupUtil_knows_about_all_fields_of_DecryptedGroupChange() {
|
|
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
|
|
|
assertEquals("DecryptedGroupUtil and its tests need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
|
19, maxFieldFound);
|
|
}
|
|
|
|
@Test
|
|
public void apply_revision() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(9)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(10)
|
|
.build());
|
|
|
|
assertEquals(10, newGroup.getRevision());
|
|
}
|
|
|
|
@Test
|
|
public void apply_new_member() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
DecryptedMember member2 = member(UUID.randomUUID());
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.addMembers(member1)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.addNewMembers(member2)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.addMembers(member1)
|
|
.addMembers(member2)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void apply_remove_member() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
DecryptedMember member2 = member(UUID.randomUUID());
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addMembers(member1)
|
|
.addMembers(member2)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addDeleteMembers(member1.getUuid())
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(14)
|
|
.addMembers(member2)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void apply_remove_members() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
DecryptedMember member2 = member(UUID.randomUUID());
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addMembers(member1)
|
|
.addMembers(member2)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addDeleteMembers(member1.getUuid())
|
|
.addDeleteMembers(member2.getUuid())
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(14)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void apply_remove_members_not_found() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
DecryptedMember member2 = member(UUID.randomUUID());
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addMembers(member1)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addDeleteMembers(member2.getUuid())
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.addMembers(member1)
|
|
.setRevision(14)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void apply_modify_member_role() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
DecryptedMember member2 = admin(UUID.randomUUID());
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addMembers(member1)
|
|
.addMembers(member2)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder().setUuid(member1.getUuid()).setRole(Member.Role.ADMINISTRATOR))
|
|
.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder().setUuid(member2.getUuid()).setRole(Member.Role.DEFAULT))
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(14)
|
|
.addMembers(asAdmin(member1))
|
|
.addMembers(asMember(member2))
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
|
|
public void not_able_to_apply_modify_member_role_for_non_member() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
DecryptedMember member2 = member(UUID.randomUUID());
|
|
|
|
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addMembers(member1)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder()
|
|
.setRole(Member.Role.ADMINISTRATOR)
|
|
.setUuid(member2.getUuid())
|
|
.build())
|
|
.build());
|
|
}
|
|
|
|
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
|
|
public void not_able_to_apply_modify_member_role_for_no_role() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
|
|
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addMembers(member1)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder()
|
|
.setUuid(member1.getUuid())
|
|
.build())
|
|
.build());
|
|
}
|
|
|
|
@Test
|
|
public void apply_modify_member_profile_keys() throws NotAbleToApplyGroupV2ChangeException {
|
|
ProfileKey profileKey1 = randomProfileKey();
|
|
ProfileKey profileKey2a = randomProfileKey();
|
|
ProfileKey profileKey2b = randomProfileKey();
|
|
DecryptedMember member1 = member(UUID.randomUUID(), profileKey1);
|
|
DecryptedMember member2a = member(UUID.randomUUID(), profileKey2a);
|
|
DecryptedMember member2b = withProfileKey(member2a, profileKey2b);
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addMembers(member1)
|
|
.addMembers(member2a)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addModifiedProfileKeys(member2b)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(14)
|
|
.addMembers(member1)
|
|
.addMembers(member2b)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
|
|
public void cant_apply_modify_member_profile_keys_if_member_not_in_group() throws NotAbleToApplyGroupV2ChangeException {
|
|
ProfileKey profileKey1 = randomProfileKey();
|
|
ProfileKey profileKey2a = randomProfileKey();
|
|
ProfileKey profileKey2b = randomProfileKey();
|
|
DecryptedMember member1 = member(UUID.randomUUID(), profileKey1);
|
|
DecryptedMember member2a = member(UUID.randomUUID(), profileKey2a);
|
|
DecryptedMember member2b = member(UUID.randomUUID(), profileKey2b);
|
|
|
|
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addMembers(member1)
|
|
.addMembers(member2a)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addModifiedProfileKeys(member2b)
|
|
.build());
|
|
}
|
|
|
|
@Test
|
|
public void apply_modify_admin_profile_keys() throws NotAbleToApplyGroupV2ChangeException {
|
|
UUID adminUuid = UUID.randomUUID();
|
|
ProfileKey profileKey1 = randomProfileKey();
|
|
ProfileKey profileKey2a = randomProfileKey();
|
|
ProfileKey profileKey2b = randomProfileKey();
|
|
DecryptedMember member1 = member(UUID.randomUUID(), profileKey1);
|
|
DecryptedMember admin2a = admin(adminUuid, profileKey2a);
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addMembers(member1)
|
|
.addMembers(admin2a)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addModifiedProfileKeys(DecryptedMember.newBuilder(DecryptedMember.newBuilder()
|
|
.setUuid(UuidUtil.toByteString(adminUuid))
|
|
.build())
|
|
.setProfileKey(ByteString.copyFrom(profileKey2b.serialize())))
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(14)
|
|
.addMembers(member1)
|
|
.addMembers(admin(adminUuid, profileKey2b))
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void apply_new_pending_member() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
DecryptedPendingMember pending = pendingMember(UUID.randomUUID());
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.addMembers(member1)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.addNewPendingMembers(pending)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.addMembers(member1)
|
|
.addPendingMembers(pending)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void apply_new_pending_member_already_pending() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
DecryptedPendingMember pending = pendingMember(UUID.randomUUID());
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.addMembers(member1)
|
|
.addPendingMembers(pending)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.addNewPendingMembers(pending)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.addMembers(member1)
|
|
.addPendingMembers(pending)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
|
|
public void apply_new_pending_member_already_in_group() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
UUID uuid2 = UUID.randomUUID();
|
|
DecryptedMember member2 = member(uuid2);
|
|
DecryptedPendingMember pending2 = pendingMember(uuid2);
|
|
|
|
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.addMembers(member1)
|
|
.addMembers(member2)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.addNewPendingMembers(pending2)
|
|
.build());
|
|
}
|
|
|
|
@Test
|
|
public void remove_pending_member() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
UUID pendingUuid = UUID.randomUUID();
|
|
DecryptedPendingMember pending = pendingMember(pendingUuid);
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.addMembers(member1)
|
|
.addPendingMembers(pending)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.addDeletePendingMembers(DecryptedPendingMemberRemoval.newBuilder()
|
|
.setUuidCipherText(ProtoTestUtils.encrypt(pendingUuid))
|
|
.build())
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.addMembers(member1)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void cannot_remove_pending_member_if_not_in_group() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
UUID pendingUuid = UUID.randomUUID();
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.addMembers(member1)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.addDeletePendingMembers(DecryptedPendingMemberRemoval.newBuilder()
|
|
.setUuidCipherText(ProtoTestUtils.encrypt(pendingUuid))
|
|
.build())
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.addMembers(member1)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void promote_pending_member() throws NotAbleToApplyGroupV2ChangeException {
|
|
ProfileKey profileKey2 = randomProfileKey();
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
UUID pending2Uuid = UUID.randomUUID();
|
|
DecryptedPendingMember pending2 = pendingMember(pending2Uuid);
|
|
DecryptedMember member2 = member(pending2Uuid, profileKey2);
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.addMembers(member1)
|
|
.addPendingMembers(pending2)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.addPromotePendingMembers(member2)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.addMembers(member1)
|
|
.addMembers(member2)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
|
|
public void cannot_promote_pending_member_if_not_in_group() throws NotAbleToApplyGroupV2ChangeException {
|
|
ProfileKey profileKey2 = randomProfileKey();
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
UUID pending2Uuid = UUID.randomUUID();
|
|
DecryptedMember member2 = withProfileKey(admin(pending2Uuid), profileKey2);
|
|
|
|
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.addMembers(member1)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.addPromotePendingMembers(member2)
|
|
.build());
|
|
}
|
|
|
|
@Test
|
|
public void skip_promote_pending_member_by_direct_add() throws NotAbleToApplyGroupV2ChangeException {
|
|
ProfileKey profileKey2 = randomProfileKey();
|
|
ProfileKey profileKey3 = randomProfileKey();
|
|
DecryptedMember member1 = member(UUID.randomUUID());
|
|
UUID pending2Uuid = UUID.randomUUID();
|
|
UUID pending3Uuid = UUID.randomUUID();
|
|
UUID pending4Uuid = UUID.randomUUID();
|
|
DecryptedPendingMember pending2 = pendingMember(pending2Uuid);
|
|
DecryptedPendingMember pending3 = pendingMember(pending3Uuid);
|
|
DecryptedPendingMember pending4 = pendingMember(pending4Uuid);
|
|
DecryptedMember member2 = member(pending2Uuid, profileKey2);
|
|
DecryptedMember member3 = member(pending3Uuid, profileKey3);
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.addMembers(member1)
|
|
.addPendingMembers(pending2)
|
|
.addPendingMembers(pending3)
|
|
.addPendingMembers(pending4)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.addNewMembers(member2)
|
|
.addNewMembers(member3)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.addMembers(member1)
|
|
.addMembers(member2)
|
|
.addMembers(member3)
|
|
.addPendingMembers(pending4)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void title() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.setTitle("Old title")
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.setNewTitle(DecryptedString.newBuilder().setValue("New title").build())
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.setTitle("New title")
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void avatar() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.setAvatar("https://cnd/oldavatar")
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.setNewAvatar(DecryptedString.newBuilder().setValue("https://cnd/newavatar").build())
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.setAvatar("https://cnd/newavatar")
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void timer() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.setDisappearingMessagesTimer(DecryptedTimer.newBuilder().setDuration(100))
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.setNewTimer(DecryptedTimer.newBuilder().setDuration(2000))
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.setDisappearingMessagesTimer(DecryptedTimer.newBuilder().setDuration(2000))
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void attribute_access() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.setAccessControl(AccessControl.newBuilder()
|
|
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
|
|
.setMembers(AccessControl.AccessRequired.MEMBER)
|
|
.build())
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.setNewAttributeAccess(AccessControl.AccessRequired.MEMBER)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.setAccessControl(AccessControl.newBuilder()
|
|
.setAttributes(AccessControl.AccessRequired.MEMBER)
|
|
.setMembers(AccessControl.AccessRequired.MEMBER)
|
|
.build())
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void membership_access() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.setAccessControl(AccessControl.newBuilder()
|
|
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
|
|
.setMembers(AccessControl.AccessRequired.MEMBER)
|
|
.build())
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.setNewMemberAccess(AccessControl.AccessRequired.ADMINISTRATOR)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.setAccessControl(AccessControl.newBuilder()
|
|
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
|
|
.setMembers(AccessControl.AccessRequired.ADMINISTRATOR)
|
|
.build())
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void change_both_access_levels() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.setAccessControl(AccessControl.newBuilder()
|
|
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
|
|
.setMembers(AccessControl.AccessRequired.MEMBER)
|
|
.build())
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.setNewAttributeAccess(AccessControl.AccessRequired.MEMBER)
|
|
.setNewMemberAccess(AccessControl.AccessRequired.ADMINISTRATOR)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.setAccessControl(AccessControl.newBuilder()
|
|
.setAttributes(AccessControl.AccessRequired.MEMBER)
|
|
.setMembers(AccessControl.AccessRequired.ADMINISTRATOR)
|
|
.build())
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void invite_link_access() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.setAccessControl(AccessControl.newBuilder()
|
|
.setAttributes(AccessControl.AccessRequired.MEMBER)
|
|
.setMembers(AccessControl.AccessRequired.MEMBER)
|
|
.setAddFromInviteLink(AccessControl.AccessRequired.UNSATISFIABLE)
|
|
.build())
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.setNewInviteLinkAccess(AccessControl.AccessRequired.ADMINISTRATOR)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.setAccessControl(AccessControl.newBuilder()
|
|
.setAttributes(AccessControl.AccessRequired.MEMBER)
|
|
.setMembers(AccessControl.AccessRequired.MEMBER)
|
|
.setAddFromInviteLink(AccessControl.AccessRequired.ADMINISTRATOR)
|
|
.build())
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void apply_new_requesting_member() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedRequestingMember member1 = requestingMember(UUID.randomUUID());
|
|
DecryptedRequestingMember member2 = requestingMember(UUID.randomUUID());
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.addRequestingMembers(member1)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.addNewRequestingMembers(member2)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.addRequestingMembers(member1)
|
|
.addRequestingMembers(member2)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void apply_remove_requesting_member() throws NotAbleToApplyGroupV2ChangeException {
|
|
DecryptedRequestingMember member1 = requestingMember(UUID.randomUUID());
|
|
DecryptedRequestingMember member2 = requestingMember(UUID.randomUUID());
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addRequestingMembers(member1)
|
|
.addRequestingMembers(member2)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addDeleteRequestingMembers(member1.getUuid())
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(14)
|
|
.addRequestingMembers(member2)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void promote_requesting_member() throws NotAbleToApplyGroupV2ChangeException {
|
|
UUID uuid1 = UUID.randomUUID();
|
|
UUID uuid2 = UUID.randomUUID();
|
|
UUID uuid3 = UUID.randomUUID();
|
|
ProfileKey profileKey1 = newProfileKey();
|
|
ProfileKey profileKey2 = newProfileKey();
|
|
ProfileKey profileKey3 = newProfileKey();
|
|
DecryptedRequestingMember member1 = requestingMember(uuid1, profileKey1);
|
|
DecryptedRequestingMember member2 = requestingMember(uuid2, profileKey2);
|
|
DecryptedRequestingMember member3 = requestingMember(uuid3, profileKey3);
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addRequestingMembers(member1)
|
|
.addRequestingMembers(member2)
|
|
.addRequestingMembers(member3)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addPromoteRequestingMembers(DecryptedApproveMember.newBuilder()
|
|
.setRole(Member.Role.DEFAULT)
|
|
.setUuid(member1.getUuid()))
|
|
.addPromoteRequestingMembers(DecryptedApproveMember.newBuilder()
|
|
.setRole(Member.Role.ADMINISTRATOR)
|
|
.setUuid(member2.getUuid()))
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(14)
|
|
.addMembers(member(uuid1, profileKey1))
|
|
.addMembers(admin(uuid2, profileKey2))
|
|
.addRequestingMembers(member3)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
|
|
public void cannot_apply_promote_requesting_member_without_a_role() throws NotAbleToApplyGroupV2ChangeException {
|
|
UUID uuid = UUID.randomUUID();
|
|
DecryptedRequestingMember member = requestingMember(uuid);
|
|
|
|
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(13)
|
|
.addRequestingMembers(member)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(14)
|
|
.addPromoteRequestingMembers(DecryptedApproveMember.newBuilder()
|
|
.setUuid(member.getUuid()))
|
|
.build());
|
|
}
|
|
|
|
@Test
|
|
public void invite_link_password() throws NotAbleToApplyGroupV2ChangeException {
|
|
ByteString password1 = ByteString.copyFrom(Util.getSecretBytes(16));
|
|
ByteString password2 = ByteString.copyFrom(Util.getSecretBytes(16));
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.setInviteLinkPassword(password1)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.setNewInviteLinkPassword(password2)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.setInviteLinkPassword(password2)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
@Test
|
|
public void invite_link_password_not_changed() throws NotAbleToApplyGroupV2ChangeException {
|
|
ByteString password = ByteString.copyFrom(Util.getSecretBytes(16));
|
|
|
|
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
|
|
.setRevision(10)
|
|
.setInviteLinkPassword(password)
|
|
.build(),
|
|
DecryptedGroupChange.newBuilder()
|
|
.setRevision(11)
|
|
.build());
|
|
|
|
assertEquals(DecryptedGroup.newBuilder()
|
|
.setRevision(11)
|
|
.setInviteLinkPassword(password)
|
|
.build(),
|
|
newGroup);
|
|
}
|
|
|
|
}
|