mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-27 20:24:32 +01:00
Introduce new add member labels permission.
This commit is contained in:
@@ -51,7 +51,7 @@ public final class DecryptedGroupUtil_apply_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("DecryptedGroupUtil and its tests need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
||||
26, maxFieldFound);
|
||||
27, maxFieldFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1052,4 +1052,36 @@ public final class DecryptedGroupUtil_apply_Test {
|
||||
.modifyMemberLabels(List.of(modifyLabelAction))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply_sets_member_label_access() throws NotAbleToApplyGroupV2ChangeException {
|
||||
DecryptedGroup group = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.accessControl(
|
||||
new AccessControl.Builder()
|
||||
.attributes(AccessControl.AccessRequired.ADMINISTRATOR)
|
||||
.members(AccessControl.AccessRequired.ADMINISTRATOR)
|
||||
.memberLabel(AccessControl.AccessRequired.ADMINISTRATOR)
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange groupChange = new DecryptedGroupChange.Builder()
|
||||
.revision(11)
|
||||
.newMemberLabelAccess(AccessControl.AccessRequired.MEMBER)
|
||||
.build();
|
||||
|
||||
DecryptedGroup expectedResult = new DecryptedGroup.Builder()
|
||||
.revision(11)
|
||||
.accessControl(
|
||||
new AccessControl.Builder()
|
||||
.attributes(AccessControl.AccessRequired.ADMINISTRATOR)
|
||||
.members(AccessControl.AccessRequired.ADMINISTRATOR)
|
||||
.memberLabel(AccessControl.AccessRequired.MEMBER)
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
|
||||
assertEquals(expectedResult, DecryptedGroupUtil.apply(group, groupChange));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public final class DecryptedGroupUtil_empty_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("GroupChangeField and getChangedFields() need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
||||
26, maxFieldFound);
|
||||
27, maxFieldFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -285,6 +285,16 @@ public final class DecryptedGroupUtil_empty_Test {
|
||||
assertTrue(DecryptedGroupExtensions.isSilent(change));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void not_empty_with_modify_member_label_access_field_27() {
|
||||
DecryptedGroupChange change = new DecryptedGroupChange.Builder()
|
||||
.newMemberLabelAccess(AccessControl.AccessRequired.ADMINISTRATOR)
|
||||
.build();
|
||||
|
||||
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
|
||||
assertFalse(DecryptedGroupExtensions.isSilent(change));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void silent_with_profile_keys_and_banned_members() {
|
||||
DecryptedGroupChange change = new DecryptedGroupChange.Builder()
|
||||
|
||||
@@ -462,4 +462,29 @@ public final class GroupChangeReconstructTest {
|
||||
assertEquals("", change.modifyMemberLabels.get(0).labelEmoji);
|
||||
assertEquals("", change.modifyMemberLabels.get(0).labelString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void new_member_label_access() {
|
||||
DecryptedGroup from = new DecryptedGroup.Builder()
|
||||
.accessControl(
|
||||
new AccessControl.Builder()
|
||||
.memberLabel(AccessControl.AccessRequired.ADMINISTRATOR)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
DecryptedGroup to = new DecryptedGroup.Builder()
|
||||
.accessControl(
|
||||
new AccessControl.Builder()
|
||||
.memberLabel(AccessControl.AccessRequired.MEMBER)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange decryptedGroupChange = GroupChangeReconstruct.reconstructGroupChange(from, to);
|
||||
|
||||
assertEquals(
|
||||
new DecryptedGroupChange.Builder()
|
||||
.newMemberLabelAccess(AccessControl.AccessRequired.MEMBER)
|
||||
.build(),
|
||||
decryptedGroupChange);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(GroupChange.Actions.class);
|
||||
|
||||
assertEquals("GroupChangeUtil and its tests need updating to account for new fields on " + GroupChange.Actions.class.getName(),
|
||||
26, maxFieldFound);
|
||||
27, maxFieldFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -236,4 +236,13 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
|
||||
|
||||
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void not_empty_with_modify_member_label_access_field_27() {
|
||||
GroupChange.Actions actions = new GroupChange.Actions.Builder()
|
||||
.modifyMemberLabelAccess(new GroupChange.Actions.ModifyMemberLabelAccessControlAction())
|
||||
.build();
|
||||
|
||||
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("GroupChangeUtil#resolveConflict and its tests need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
||||
26, maxFieldFound);
|
||||
27, maxFieldFound);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,10 +63,10 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
*/
|
||||
@Test
|
||||
public void ensure_resolveConflict_knows_about_all_fields_of_GroupChange() {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(GroupChange.Actions.class);
|
||||
|
||||
assertEquals("GroupChangeUtil#resolveConflict and its tests need updating to account for new fields on " + GroupChange.class.getName(),
|
||||
26, maxFieldFound);
|
||||
27, maxFieldFound);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -857,7 +857,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_26__modify_member_label__remove_if_label_already_matches() {
|
||||
public void field_26__member_label_change_removed_when_same_as_group_state() {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
|
||||
DecryptedMember existingMember = member(memberUuid)
|
||||
@@ -866,7 +866,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
.labelString("matching label")
|
||||
.build();
|
||||
|
||||
DecryptedGroup existingGroup = new DecryptedGroup.Builder()
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(existingMember))
|
||||
.build();
|
||||
@@ -881,21 +881,58 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
.modifyMemberLabels(List.of(modifyLabelAction))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange.Builder resolvedActions = GroupChangeUtil.resolveConflict(existingGroup, conflictingChange);
|
||||
assertTrue(resolvedActions.build().modifyMemberLabels.isEmpty());
|
||||
GroupChange.Actions change = new GroupChange.Actions.Builder()
|
||||
.modifyMemberLabels(List.of(new GroupChange.Actions.ModifyMemberLabelAction()))
|
||||
.build();
|
||||
|
||||
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, conflictingChange, change).build();
|
||||
assertTrue(GroupChangeUtil.changeIsEmpty(resolvedActions));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_26__modify_member_label__remove_if_member_not_in_group() {
|
||||
public void field_26__member_label_change_preserved_when_differs_from_group_state() {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
|
||||
DecryptedMember existingMember = member(memberUuid)
|
||||
.newBuilder()
|
||||
.labelEmoji("🔥")
|
||||
.labelString("Old Label")
|
||||
.build();
|
||||
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(existingMember))
|
||||
.build();
|
||||
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(UuidUtil.toByteString(memberUuid))
|
||||
.labelEmoji("🎉")
|
||||
.labelString("New Label")
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange conflictingChange = new DecryptedGroupChange.Builder()
|
||||
.modifyMemberLabels(List.of(modifyLabelAction))
|
||||
.build();
|
||||
|
||||
GroupChange.Actions change = new GroupChange.Actions.Builder()
|
||||
.modifyMemberLabels(List.of(new GroupChange.Actions.ModifyMemberLabelAction()))
|
||||
.build();
|
||||
|
||||
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, conflictingChange, change).build();
|
||||
assertEquals(change, resolvedActions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_26__member_label_change_removed_when_member_not_in_group() {
|
||||
UUID memberUuuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
UUID nonMemberUuid = UUID.fromString("d2d2d2d2-0000-4000-8000-000000000002");
|
||||
|
||||
DecryptedGroup existingGroup = new DecryptedGroup.Builder()
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(member(memberUuuid)))
|
||||
.build();
|
||||
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberLabel.Builder()
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(UuidUtil.toByteString(nonMemberUuid))
|
||||
.labelEmoji("🔥")
|
||||
.labelString("foo bar")
|
||||
@@ -905,7 +942,55 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
.modifyMemberLabels(List.of(modifyLabelAction))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange.Builder resolved = GroupChangeUtil.resolveConflict(existingGroup, conflictingChange);
|
||||
assertTrue(resolved.build().modifyMemberLabels.isEmpty());
|
||||
GroupChange.Actions change = new GroupChange.Actions.Builder()
|
||||
.modifyMemberLabels(List.of(new GroupChange.Actions.ModifyMemberLabelAction()))
|
||||
.build();
|
||||
|
||||
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, conflictingChange, change).build();
|
||||
assertTrue(GroupChangeUtil.changeIsEmpty(resolvedActions));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_27__member_label_access_change_preserved_when_differs_from_group_state() {
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.accessControl(new AccessControl.Builder().memberLabel(AccessControl.AccessRequired.ADMINISTRATOR).build())
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange decryptedChange = new DecryptedGroupChange.Builder()
|
||||
.newMemberLabelAccess(AccessControl.AccessRequired.MEMBER)
|
||||
.build();
|
||||
|
||||
GroupChange.Actions change = new GroupChange.Actions.Builder()
|
||||
.modifyMemberLabelAccess(
|
||||
new GroupChange.Actions.ModifyMemberLabelAccessControlAction.Builder()
|
||||
.memberLabelAccess(AccessControl.AccessRequired.MEMBER)
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
|
||||
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
|
||||
assertEquals(change, resolvedActions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_27__member_label_access_change_removed_when_same_as_group_state() {
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.accessControl(new AccessControl.Builder().memberLabel(AccessControl.AccessRequired.ADMINISTRATOR).build())
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange decryptedChange = new DecryptedGroupChange.Builder()
|
||||
.newMemberLabelAccess(AccessControl.AccessRequired.ADMINISTRATOR)
|
||||
.build();
|
||||
|
||||
GroupChange.Actions change = new GroupChange.Actions.Builder()
|
||||
.modifyMemberLabelAccess(
|
||||
new GroupChange.Actions.ModifyMemberLabelAccessControlAction.Builder()
|
||||
.memberLabelAccess(AccessControl.AccessRequired.ADMINISTRATOR)
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
|
||||
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
|
||||
assertTrue(GroupChangeUtil.changeIsEmpty(resolvedActions));
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import java.util.UUID;
|
||||
import okio.ByteString;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.admin;
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.approveMember;
|
||||
@@ -45,7 +46,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("GroupChangeUtil#resolveConflict and its tests need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
||||
26, maxFieldFound);
|
||||
27, maxFieldFound);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -676,7 +677,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_26__modify_member_label__remove_if_label_already_matches() {
|
||||
public void field_26__member_label_change_removed_when_same_as_group_state() {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
|
||||
DecryptedMember existingMember = member(memberUuid)
|
||||
@@ -691,7 +692,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
|
||||
.labelString("Already Set")
|
||||
.build();
|
||||
|
||||
DecryptedGroup existingGroup = new DecryptedGroup.Builder()
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(existingMember))
|
||||
.build();
|
||||
@@ -700,16 +701,16 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
|
||||
.modifyMemberLabels(List.of(modifyLabelAction))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange.Builder resolved = GroupChangeUtil.resolveConflict(existingGroup, conflictingChange);
|
||||
assertTrue(resolved.build().modifyMemberLabels.isEmpty());
|
||||
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, conflictingChange).build();
|
||||
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_26__modify_member_label__remove_if_member_not_in_group() {
|
||||
public void field_26__member_label_change_removed_when_member_not_in_group() {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
UUID notInGroupUuid = UUID.fromString("d2d2d2d2-0000-4000-8000-000000000002");
|
||||
|
||||
DecryptedGroup existingGroup = new DecryptedGroup.Builder()
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(member(memberUuid)))
|
||||
.build();
|
||||
@@ -724,7 +725,64 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
|
||||
.modifyMemberLabels(List.of(modifyLabelAction))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange.Builder resolved = GroupChangeUtil.resolveConflict(existingGroup, conflictingChange);
|
||||
assertTrue(resolved.build().modifyMemberLabels.isEmpty());
|
||||
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, conflictingChange).build();
|
||||
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_26__member_label_change_preserved_when_label_differs() {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
|
||||
DecryptedMember existingMember = member(memberUuid)
|
||||
.newBuilder()
|
||||
.labelEmoji("🔥")
|
||||
.labelString("Old Label")
|
||||
.build();
|
||||
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(existingMember))
|
||||
.build();
|
||||
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(UuidUtil.toByteString(memberUuid))
|
||||
.labelEmoji("🎉")
|
||||
.labelString("New Label")
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange conflictingChange = new DecryptedGroupChange.Builder()
|
||||
.modifyMemberLabels(List.of(modifyLabelAction))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, conflictingChange).build();
|
||||
assertFalse(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_27__member_label_access_change_preserved_when_differs_from_group_state() {
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.accessControl(new AccessControl.Builder().memberLabel(AccessControl.AccessRequired.ADMINISTRATOR).build())
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange decryptedChange = new DecryptedGroupChange.Builder()
|
||||
.newMemberLabelAccess(AccessControl.AccessRequired.MEMBER)
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
|
||||
assertEquals(decryptedChange, resolvedChanges);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_27__member_label_access_change_removed_when_same_as_group_state() {
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.accessControl(new AccessControl.Builder().memberLabel(AccessControl.AccessRequired.ADMINISTRATOR).build())
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange decryptedChange = new DecryptedGroupChange.Builder()
|
||||
.newMemberLabelAccess(AccessControl.AccessRequired.ADMINISTRATOR)
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
|
||||
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("GroupV2Operations#decryptChange and its tests need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
||||
26,
|
||||
27,
|
||||
maxFieldFound);
|
||||
}
|
||||
|
||||
@@ -476,6 +476,16 @@ public final class GroupsV2Operations_decrypt_change_Test {
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void can_pass_through_new_member_label_access_field_27() {
|
||||
GroupChange.Actions.Builder encryptedChange = groupOperations.createChangeMemberLabelRights(AccessControl.AccessRequired.ADMINISTRATOR);
|
||||
|
||||
DecryptedGroupChange.Builder expectedDecryptedChange = new DecryptedGroupChange.Builder()
|
||||
.newMemberLabelAccess(AccessControl.AccessRequired.ADMINISTRATOR);
|
||||
|
||||
assertDecryption(encryptedChange, expectedDecryptedChange);
|
||||
}
|
||||
|
||||
private static ProfileKey newProfileKey() {
|
||||
try {
|
||||
return new ProfileKey(Util.getSecretBytes(32));
|
||||
|
||||
Reference in New Issue
Block a user