Update Groups.proto to match shared spec.

This commit is contained in:
Greyson Parrelli
2026-01-13 14:01:35 -05:00
parent 2e4665e5c4
commit bd38c4f5d2
75 changed files with 779 additions and 757 deletions

View File

@@ -1,11 +1,11 @@
package org.whispersystems.signalservice.api.groupsv2
import org.signal.storageservice.protos.groups.AccessControl
import org.signal.storageservice.protos.groups.Member
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange
import org.signal.storageservice.protos.groups.local.DecryptedMember
import org.signal.storageservice.protos.groups.local.DecryptedRequestingMember
import org.signal.storageservice.protos.groups.local.EnabledState
import org.signal.storageservice.storage.protos.groups.AccessControl
import org.signal.storageservice.storage.protos.groups.Member
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember
import org.signal.storageservice.storage.protos.groups.local.EnabledState
internal class DecryptedGroupChangeActionsBuilderChangeSetModifier(private val result: DecryptedGroupChange.Builder) : ChangeSetModifier {
override fun removeAddMembers(i: Int) {

View File

@@ -1,7 +1,7 @@
package org.whispersystems.signalservice.api.groupsv2
import org.signal.storageservice.protos.groups.local.DecryptedGroup
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange
/**
* A changelog from the server representing a specific group state revision. The

View File

@@ -7,9 +7,9 @@ package org.whispersystems.signalservice.api.groupsv2
import org.signal.core.models.ServiceId
import org.signal.core.models.ServiceId.ACI
import org.signal.storageservice.protos.groups.local.DecryptedMember
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember
import org.signal.storageservice.protos.groups.local.DecryptedRequestingMember
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember
import java.util.Optional
fun Collection<DecryptedMember>.toAciListWithUnknowns(): List<ACI> {

View File

@@ -6,7 +6,7 @@
package org.whispersystems.signalservice.api.groupsv2
import org.signal.libsignal.zkgroup.groupsend.GroupSendEndorsementsResponse
import org.signal.storageservice.protos.groups.local.DecryptedGroup
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup
/**
* Decrypted response from server operations that includes our global group state and

View File

@@ -1,18 +1,18 @@
package org.whispersystems.signalservice.api.groupsv2;
import org.signal.libsignal.protocol.logging.Log;
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.DecryptedBannedMember;
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.EnabledState;
import org.signal.storageservice.storage.protos.groups.AccessControl;
import org.signal.storageservice.storage.protos.groups.Member;
import org.signal.storageservice.storage.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberRole;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMemberRemoval;
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember;
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
import org.signal.core.models.ServiceId;
import org.signal.core.models.ServiceId.ACI;
import org.whispersystems.signalservice.api.push.ServiceIds;
@@ -299,11 +299,11 @@ public final class DecryptedGroupUtil {
applyModifyMemberProfileKeyActions(builder, change.modifiedProfileKeys);
applyAddPendingMemberActions(builder, change.newPendingMembers);
applyAddMemberPendingProfileKeyActions(builder, change.newPendingMembers);
applyDeletePendingMemberActions(builder, change.deletePendingMembers);
applyDeleteMemberPendingProfileKeyActions(builder, change.deletePendingMembers);
applyPromotePendingMemberActions(builder, change.promotePendingMembers);
applyPromoteMemberPendingProfileKeyActions(builder, change.promotePendingMembers);
applyModifyTitleAction(builder, change);
@@ -325,7 +325,7 @@ public final class DecryptedGroupUtil {
applyDeleteRequestingMembers(builder, change.deleteRequestingMembers);
applyPromoteRequestingMemberActions(builder, change.promoteRequestingMembers);
applyPromoteMemberPendingAdminApprovalActions(builder, change.promoteRequestingMembers);
applyInviteLinkPassword(builder, change);
@@ -409,7 +409,7 @@ public final class DecryptedGroupUtil {
builder.members(members);
}
private static void applyAddPendingMemberActions(DecryptedGroup.Builder builder, List<DecryptedPendingMember> newPendingMembersList) throws NotAbleToApplyGroupV2ChangeException {
private static void applyAddMemberPendingProfileKeyActions(DecryptedGroup.Builder builder, List<DecryptedPendingMember> newPendingMembersList) throws NotAbleToApplyGroupV2ChangeException {
Set<ByteString> fullMemberSet = getMemberAciSet(builder.members);
Set<ByteString> pendingMemberCipherTexts = getPendingMemberCipherTextSet(builder.pendingMembers);
List<DecryptedPendingMember> pendingMembers = new ArrayList<>(builder.pendingMembers);
@@ -427,7 +427,7 @@ public final class DecryptedGroupUtil {
builder.pendingMembers(pendingMembers);
}
private static void applyDeletePendingMemberActions(DecryptedGroup.Builder builder, List<DecryptedPendingMemberRemoval> deletePendingMembersList) {
private static void applyDeleteMemberPendingProfileKeyActions(DecryptedGroup.Builder builder, List<DecryptedPendingMemberRemoval> deletePendingMembersList) {
List<DecryptedPendingMember> pendingMembers = new ArrayList<>(builder.pendingMembers);
for (DecryptedPendingMemberRemoval removedMember : deletePendingMembersList) {
@@ -444,7 +444,7 @@ public final class DecryptedGroupUtil {
builder.pendingMembers(pendingMembers);
}
private static void applyPromotePendingMemberActions(DecryptedGroup.Builder builder, List<DecryptedMember> promotePendingMembersList) throws NotAbleToApplyGroupV2ChangeException {
private static void applyPromoteMemberPendingProfileKeyActions(DecryptedGroup.Builder builder, List<DecryptedMember> promotePendingMembersList) throws NotAbleToApplyGroupV2ChangeException {
List<DecryptedMember> members = new ArrayList<>(builder.members);
List<DecryptedPendingMember> pendingMembers = new ArrayList<>(builder.pendingMembers);
@@ -541,7 +541,7 @@ public final class DecryptedGroupUtil {
builder.requestingMembers(requestingMembers);
}
private static void applyPromoteRequestingMemberActions(DecryptedGroup.Builder builder, List<DecryptedApproveMember> promoteRequestingMembers) throws NotAbleToApplyGroupV2ChangeException {
private static void applyPromoteMemberPendingAdminApprovalActions(DecryptedGroup.Builder builder, List<DecryptedApproveMember> promoteRequestingMembers) throws NotAbleToApplyGroupV2ChangeException {
List<DecryptedMember> members = new ArrayList<>(builder.members);
List<DecryptedRequestingMember> requestingMembers = new ArrayList<>(builder.requestingMembers);

View File

@@ -1,8 +1,8 @@
package org.whispersystems.signalservice.api.groupsv2
import org.signal.storageservice.protos.groups.GroupChange
import org.signal.storageservice.protos.groups.GroupChange.Actions.AddMemberAction
import org.signal.storageservice.protos.groups.GroupChange.Actions.AddRequestingMemberAction
import org.signal.storageservice.storage.protos.groups.GroupChange
import org.signal.storageservice.storage.protos.groups.GroupChange.Actions.AddMemberAction
import org.signal.storageservice.storage.protos.groups.GroupChange.Actions.AddMemberPendingAdminApprovalAction
internal class GroupChangeActionsBuilderChangeSetModifier(private val result: GroupChange.Actions.Builder) : ChangeSetModifier {
override fun removeAddMembers(i: Int) {
@@ -12,7 +12,7 @@ internal class GroupChangeActionsBuilderChangeSetModifier(private val result: Gr
override fun moveAddToPromote(i: Int) {
val addMemberAction: AddMemberAction = result.addMembers[i]
result.addMembers = result.addMembers.removeIndex(i)
result.promotePendingMembers += GroupChange.Actions.PromotePendingMemberAction.Builder().presentation(addMemberAction.added!!.presentation).build()
result.promoteMembersPendingProfileKey += GroupChange.Actions.PromoteMemberPendingProfileKeyAction.Builder().presentation(addMemberAction.added!!.presentation).build()
}
override fun removeDeleteMembers(i: Int) {
@@ -28,15 +28,15 @@ internal class GroupChangeActionsBuilderChangeSetModifier(private val result: Gr
}
override fun removeAddPendingMembers(i: Int) {
result.addPendingMembers = result.addPendingMembers.removeIndex(i)
result.addMembersPendingProfileKey = result.addMembersPendingProfileKey.removeIndex(i)
}
override fun removeDeletePendingMembers(i: Int) {
result.deletePendingMembers = result.deletePendingMembers.removeIndex(i)
result.deleteMembersPendingProfileKey = result.deleteMembersPendingProfileKey.removeIndex(i)
}
override fun removePromotePendingMembers(i: Int) {
result.promotePendingMembers = result.promotePendingMembers.removeIndex(i)
result.promoteMembersPendingProfileKey = result.promoteMembersPendingProfileKey.removeIndex(i)
}
override fun clearModifyTitle() {
@@ -48,7 +48,7 @@ internal class GroupChangeActionsBuilderChangeSetModifier(private val result: Gr
}
override fun clearModifyDisappearingMessagesTimer() {
result.modifyDisappearingMessagesTimer = null
result.modifyDisappearingMessageTimer= null
}
override fun clearModifyAttributesAccess() {
@@ -64,21 +64,21 @@ internal class GroupChangeActionsBuilderChangeSetModifier(private val result: Gr
}
override fun removeAddRequestingMembers(i: Int) {
result.addRequestingMembers = result.addRequestingMembers.removeIndex(i)
result.addMembersPendingAdminApproval = result.addMembersPendingAdminApproval.removeIndex(i)
}
override fun moveAddRequestingMembersToPromote(i: Int) {
val addMemberAction: AddRequestingMemberAction = result.addRequestingMembers[i]
result.addRequestingMembers = result.addRequestingMembers.removeIndex(i)
result.promotePendingMembers += GroupChange.Actions.PromotePendingMemberAction.Builder().presentation(addMemberAction.added!!.presentation).build()
val addMemberAction: AddMemberPendingAdminApprovalAction = result.addMembersPendingAdminApproval[i]
result.addMembersPendingAdminApproval = result.addMembersPendingAdminApproval.removeIndex(i)
result.promoteMembersPendingProfileKey += GroupChange.Actions.PromoteMemberPendingProfileKeyAction.Builder().presentation(addMemberAction.added!!.presentation).build()
}
override fun removeDeleteRequestingMembers(i: Int) {
result.deleteRequestingMembers = result.deleteRequestingMembers.removeIndex(i)
result.deleteMembersPendingAdminApproval = result.deleteMembersPendingAdminApproval.removeIndex(i)
}
override fun removePromoteRequestingMembers(i: Int) {
result.promoteRequestingMembers = result.promoteRequestingMembers.removeIndex(i)
result.promoteMembersPendingAdminApproval = result.promoteMembersPendingAdminApproval.removeIndex(i)
}
override fun clearModifyDescription() {
@@ -86,19 +86,19 @@ internal class GroupChangeActionsBuilderChangeSetModifier(private val result: Gr
}
override fun clearModifyAnnouncementsOnly() {
result.modifyAnnouncementsOnly = null
result.modify_announcements_only = null
}
override fun removeAddBannedMembers(i: Int) {
result.addBannedMembers = result.addBannedMembers.removeIndex(i)
result.add_members_banned = result.add_members_banned.removeIndex(i)
}
override fun removeDeleteBannedMembers(i: Int) {
result.deleteBannedMembers = result.deleteBannedMembers.removeIndex(i)
result.delete_members_banned = result.delete_members_banned.removeIndex(i)
}
override fun removePromotePendingPniAciMembers(i: Int) {
result.promotePendingPniAciMembers = result.promotePendingPniAciMembers.removeIndex(i)
result.promote_members_pending_pni_aci_profile_key = result.promote_members_pending_pni_aci_profile_key.removeIndex(i)
}
private fun <T> List<T>.removeIndex(i: Int): List<T> {

View File

@@ -1,15 +1,15 @@
package org.whispersystems.signalservice.api.groupsv2;
import org.signal.storageservice.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.protos.groups.local.DecryptedBannedMember;
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.storage.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberRole;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMemberRemoval;
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
import java.util.ArrayList;
import java.util.Collection;

View File

@@ -1,15 +1,15 @@
package org.whispersystems.signalservice.api.groupsv2;
import org.signal.storageservice.protos.groups.GroupChange;
import org.signal.storageservice.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.protos.groups.local.DecryptedBannedMember;
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.storage.protos.groups.GroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberRole;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMemberRemoval;
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember;
import java.util.HashMap;
import java.util.List;
@@ -29,24 +29,24 @@ public final class GroupChangeUtil {
change.deleteMembers.size() == 0 && // field 4
change.modifyMemberRoles.size() == 0 && // field 5
change.modifyMemberProfileKeys.size() == 0 && // field 6
change.addPendingMembers.size() == 0 && // field 7
change.deletePendingMembers.size() == 0 && // field 8
change.promotePendingMembers.size() == 0 && // field 9
change.addMembersPendingProfileKey.size() == 0 && // field 7
change.deleteMembersPendingProfileKey.size() == 0 && // field 8
change.promoteMembersPendingProfileKey.size() == 0 && // field 9
change.modifyTitle == null && // field 10
change.modifyAvatar == null && // field 11
change.modifyDisappearingMessagesTimer == null && // field 12
change.modifyDisappearingMessageTimer == null && // field 12
change.modifyAttributesAccess == null && // field 13
change.modifyMemberAccess == null && // field 14
change.modifyAddFromInviteLinkAccess == null && // field 15
change.addRequestingMembers.size() == 0 && // field 16
change.deleteRequestingMembers.size() == 0 && // field 17
change.promoteRequestingMembers.size() == 0 && // field 18
change.addMembersPendingAdminApproval.size() == 0 && // field 16
change.deleteMembersPendingAdminApproval.size() == 0 && // field 17
change.promoteMembersPendingAdminApproval.size() == 0 && // field 18
change.modifyInviteLinkPassword == null && // field 19
change.modifyDescription == null && // field 20
change.modifyAnnouncementsOnly == null && // field 21
change.addBannedMembers.size() == 0 && // field 22
change.deleteBannedMembers.size() == 0 && // field 23
change.promotePendingPniAciMembers.size() == 0; // field 24
change.modify_announcements_only == null && // field 21
change.add_members_banned.size() == 0 && // field 22
change.delete_members_banned.size() == 0 && // field 23
change.promote_members_pending_pni_aci_profile_key.size() == 0; // field 24
}
/**
@@ -58,7 +58,7 @@ public final class GroupChangeUtil {
* Membership additions and removals also respect last writer wins and are removed if they have
* already been applied. e.g. you add someone but they are already added.
* <p>
* Membership additions will be altered to {@link GroupChange.Actions.PromotePendingMemberAction}
* Membership additions will be altered to {@link GroupChange.Actions.PromoteMemberPendingProfileKeyAction}
* if someone has invited them since.
*
* @param groupState Latest group state in plaintext.

View File

@@ -10,18 +10,18 @@ import org.signal.libsignal.zkgroup.calllinks.CallLinkAuthCredentialResponse;
import org.signal.libsignal.zkgroup.groups.ClientZkGroupCipher;
import org.signal.libsignal.zkgroup.groups.GroupSecretParams;
import org.signal.libsignal.zkgroup.groupsend.GroupSendEndorsementsResponse;
import org.signal.storageservice.protos.groups.AvatarUploadAttributes;
import org.signal.storageservice.protos.groups.Group;
import org.signal.storageservice.protos.groups.GroupAttributeBlob;
import org.signal.storageservice.protos.groups.GroupChange;
import org.signal.storageservice.protos.groups.GroupChangeResponse;
import org.signal.storageservice.protos.groups.GroupChanges;
import org.signal.storageservice.protos.groups.GroupExternalCredential;
import org.signal.storageservice.protos.groups.GroupJoinInfo;
import org.signal.storageservice.protos.groups.GroupResponse;
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.protos.groups.local.DecryptedGroupJoinInfo;
import org.signal.storageservice.storage.protos.groups.AvatarUploadAttributes;
import org.signal.storageservice.storage.protos.groups.Group;
import org.signal.storageservice.storage.protos.groups.GroupAttributeBlob;
import org.signal.storageservice.storage.protos.groups.GroupChange;
import org.signal.storageservice.storage.protos.groups.GroupChangeResponse;
import org.signal.storageservice.storage.protos.groups.GroupChanges;
import org.signal.storageservice.storage.protos.groups.ExternalGroupCredential;
import org.signal.storageservice.storage.protos.groups.GroupJoinInfo;
import org.signal.storageservice.storage.protos.groups.GroupResponse;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupJoinInfo;
import org.whispersystems.signalservice.api.NetworkResult;
import org.signal.core.models.ServiceId.ACI;
import org.signal.core.models.ServiceId.PNI;
@@ -88,14 +88,14 @@ public class GroupsV2Api {
String cdnKey = uploadAvatar(newGroup.getAvatar().get(), newGroup.getGroupSecretParams(), authorization);
group = group.newBuilder()
.avatar(cdnKey)
.avatarUrl(cdnKey)
.build();
}
GroupResponse response = socket.putNewGroupsV2Group(group, authorization);
return groupsOperations.forGroup(newGroup.getGroupSecretParams())
.decryptGroup(Objects.requireNonNull(response.group), response.groupSendEndorsementsResponse.toByteArray());
.decryptGroup(Objects.requireNonNull(response.group), response.group_send_endorsements_response.toByteArray());
}
public NetworkResult<DecryptedGroupResponse> getGroupAsResult(GroupSecretParams groupSecretParams, GroupsV2AuthorizationString authorization) {
@@ -109,7 +109,7 @@ public class GroupsV2Api {
GroupResponse response = socket.getGroupsV2Group(authorization);
return groupsOperations.forGroup(groupSecretParams)
.decryptGroup(Objects.requireNonNull(response.group), response.groupSendEndorsementsResponse.toByteArray());
.decryptGroup(Objects.requireNonNull(response.group), response.group_send_endorsements_response.toByteArray());
}
public GroupHistoryPage getGroupHistoryPage(GroupSecretParams groupSecretParams,
@@ -130,7 +130,7 @@ public class GroupsV2Api {
result.add(new DecryptedGroupChangeLog(decryptedGroup, decryptedChange));
}
byte[] groupSendEndorsementsResponseBytes = group.getGroupChanges().groupSendEndorsementsResponse.toByteArray();
byte[] groupSendEndorsementsResponseBytes = group.getGroupChanges().group_send_endorsements_response.toByteArray();
GroupSendEndorsementsResponse groupSendEndorsementsResponse = groupSendEndorsementsResponseBytes.length > 0 ? new GroupSendEndorsementsResponse(groupSendEndorsementsResponseBytes) : null;
return new GroupHistoryPage(result, groupSendEndorsementsResponse, GroupHistoryPage.PagingData.forGroupHistory(group));
@@ -182,10 +182,10 @@ public class GroupsV2Api {
return socket.patchGroupsV2Group(groupChange, authorization.toString(), groupLinkPassword);
}
public GroupExternalCredential getGroupExternalCredential(GroupsV2AuthorizationString authorization)
public ExternalGroupCredential getExternalGroupCredential(GroupsV2AuthorizationString authorization)
throws IOException
{
return socket.getGroupExternalCredential(authorization);
return socket.getExternalGroupCredential(authorization);
}
private static CredentialResponseMaps parseCredentialResponse(CredentialResponse credentialResponse)

View File

@@ -16,28 +16,28 @@ import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations;
import org.signal.libsignal.zkgroup.profiles.ExpiringProfileKeyCredential;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.signal.libsignal.zkgroup.profiles.ProfileKeyCredentialPresentation;
import org.signal.storageservice.protos.groups.AccessControl;
import org.signal.storageservice.protos.groups.BannedMember;
import org.signal.storageservice.protos.groups.Group;
import org.signal.storageservice.protos.groups.GroupAttributeBlob;
import org.signal.storageservice.protos.groups.GroupChange;
import org.signal.storageservice.protos.groups.GroupJoinInfo;
import org.signal.storageservice.protos.groups.Member;
import org.signal.storageservice.protos.groups.PendingMember;
import org.signal.storageservice.protos.groups.RequestingMember;
import org.signal.storageservice.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.protos.groups.local.DecryptedGroupJoinInfo;
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.storageservice.protos.groups.local.EnabledState;
import org.signal.storageservice.storage.protos.groups.AccessControl;
import org.signal.storageservice.storage.protos.groups.MemberBanned;
import org.signal.storageservice.storage.protos.groups.Group;
import org.signal.storageservice.storage.protos.groups.GroupAttributeBlob;
import org.signal.storageservice.storage.protos.groups.GroupChange;
import org.signal.storageservice.storage.protos.groups.GroupJoinInfo;
import org.signal.storageservice.storage.protos.groups.Member;
import org.signal.storageservice.storage.protos.groups.MemberPendingProfileKey;
import org.signal.storageservice.storage.protos.groups.MemberPendingAdminApproval;
import org.signal.storageservice.storage.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupJoinInfo;
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberRole;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMemberRemoval;
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
import org.signal.core.models.ServiceId;
import org.signal.core.models.ServiceId.ACI;
import org.signal.core.models.ServiceId.PNI;
@@ -110,7 +110,7 @@ public final class GroupsV2Operations {
final GroupOperations groupOperations = forGroup(groupSecretParams);
Group.Builder group = new Group.Builder()
.revision(0)
.version(0)
.publicKey(ByteString.of(groupSecretParams.getPublicParams().serialize()))
.title(groupOperations.encryptTitle(title))
.disappearingMessagesTimer(groupOperations.encryptTimer(disappearingMessageTimerSeconds))
@@ -120,7 +120,7 @@ public final class GroupsV2Operations {
.build());
List<Member> groupMembers = new ArrayList<>();
List<PendingMember> groupPendingMembers = new ArrayList<>();
List<MemberPendingProfileKey> groupPendingMembers = new ArrayList<>();
groupMembers.add(groupOperations.member(self.requireExpiringProfileKeyCredential(), Member.Role.ADMINISTRATOR).build());
@@ -135,7 +135,7 @@ public final class GroupsV2Operations {
}
group.members(groupMembers)
.pendingMembers(groupPendingMembers);
.membersPendingProfileKey(groupPendingMembers);
return new NewGroup(groupSecretParams, group.build(), avatar);
}
@@ -186,7 +186,7 @@ public final class GroupsV2Operations {
: createUnbanServiceIdsChange(membersToUnban);
List<GroupChange.Actions.AddMemberAction> addGroupMembers = new ArrayList<>(actions.addMembers);
List<GroupChange.Actions.AddPendingMemberAction> addGroupPendingMembers = new ArrayList<>(actions.addPendingMembers);
List<GroupChange.Actions.AddMemberPendingProfileKeyAction> addGroupPendingMembers = new ArrayList<>(actions.addMembersPendingProfileKey);
for (GroupCandidate credential : membersToAdd) {
Member.Role newMemberRole = Member.Role.DEFAULT;
ExpiringProfileKeyCredential expiringProfileKeyCredential = credential.getExpiringProfileKeyCredential().orElse(null);
@@ -194,7 +194,7 @@ public final class GroupsV2Operations {
if (expiringProfileKeyCredential != null) {
addGroupMembers.add(new GroupChange.Actions.AddMemberAction.Builder().added(groupOperations.member(expiringProfileKeyCredential, newMemberRole).build()).build());
} else {
addGroupPendingMembers.add(new GroupChange.Actions.AddPendingMemberAction.Builder().added(groupOperations.invitee(credential.getServiceId(), newMemberRole)
addGroupPendingMembers.add(new GroupChange.Actions.AddMemberPendingProfileKeyAction.Builder().added(groupOperations.invitee(credential.getServiceId(), newMemberRole)
.addedByUserId(encryptServiceId(selfAci))
.build())
.build());
@@ -202,14 +202,14 @@ public final class GroupsV2Operations {
}
return actions.addMembers(addGroupMembers)
.addPendingMembers(addGroupPendingMembers);
.addMembersPendingProfileKey(addGroupPendingMembers);
}
public GroupChange.Actions.Builder createGroupJoinRequest(ExpiringProfileKeyCredential expiringProfileKeyCredential) {
GroupOperations groupOperations = forGroup(groupSecretParams);
GroupChange.Actions.Builder actions = new GroupChange.Actions.Builder();
actions.addRequestingMembers = Collections.singletonList(new GroupChange.Actions.AddRequestingMemberAction.Builder().added(groupOperations.requestingMember(expiringProfileKeyCredential).build()).build());
actions.addMembersPendingAdminApproval = Collections.singletonList(new GroupChange.Actions.AddMemberPendingAdminApprovalAction.Builder().added(groupOperations.requestingMember(expiringProfileKeyCredential).build()).build());
return actions;
}
@@ -227,20 +227,20 @@ public final class GroupsV2Operations {
GroupChange.Actions.Builder actions = alsoBan ? createBanServiceIdsChange(requestsToRemove, false, bannedMembers)
: new GroupChange.Actions.Builder();
List<GroupChange.Actions.DeleteRequestingMemberAction> deleteRequestingMemberActions = new ArrayList<>(actions.deleteRequestingMembers);
List<GroupChange.Actions.DeleteMemberPendingAdminApprovalAction> DeleteMemberPendingAdminApprovalActions = new ArrayList<>(actions.deleteMembersPendingAdminApproval);
for (ServiceId serviceId : requestsToRemove) {
if (serviceId instanceof ACI) {
deleteRequestingMemberActions.add(new GroupChange.Actions.DeleteRequestingMemberAction.Builder().deletedUserId(encryptServiceId(serviceId)).build());
DeleteMemberPendingAdminApprovalActions.add(new GroupChange.Actions.DeleteMemberPendingAdminApprovalAction.Builder().deletedUserId(encryptServiceId(serviceId)).build());
}
}
return actions.deleteRequestingMembers(deleteRequestingMemberActions);
return actions.deleteMembersPendingAdminApproval(DeleteMemberPendingAdminApprovalActions);
}
public GroupChange.Actions.Builder createApproveGroupJoinRequest(Set<UUID> requestsToApprove) {
GroupChange.Actions.Builder actions = new GroupChange.Actions.Builder();
actions.promoteRequestingMembers = requestsToApprove.stream()
.map(uuid -> new GroupChange.Actions.PromoteRequestingMemberAction.Builder().role(Member.Role.DEFAULT)
actions.promoteMembersPendingAdminApproval = requestsToApprove.stream()
.map(uuid -> new GroupChange.Actions.PromoteMemberPendingAdminApprovalAction.Builder().role(Member.Role.DEFAULT)
.userId(encryptServiceId(ACI.from(uuid)))
.build())
.collect(Collectors.toList());
@@ -271,7 +271,7 @@ public final class GroupsV2Operations {
public GroupChange.Actions.Builder createModifyGroupTimerChange(int timerDurationSeconds) {
return new GroupChange.Actions.Builder()
.modifyDisappearingMessagesTimer(new GroupChange.Actions.ModifyDisappearingMessagesTimerAction.Builder().timer(encryptTimer(timerDurationSeconds)).build());
.modifyDisappearingMessageTimer(new GroupChange.Actions.ModifyDisappearingMessageTimerAction.Builder().timer(encryptTimer(timerDurationSeconds)).build());
}
public GroupChange.Actions.Builder createUpdateProfileKeyCredentialChange(ExpiringProfileKeyCredential expiringProfileKeyCredential) {
@@ -287,8 +287,8 @@ public final class GroupsV2Operations {
public GroupChange.Actions.Builder createAcceptInviteChange(ExpiringProfileKeyCredential credential) {
ProfileKeyCredentialPresentation presentation = clientZkProfileOperations.createProfileKeyCredentialPresentation(random, groupSecretParams, credential);
return new GroupChange.Actions.Builder().promotePendingMembers(Collections.singletonList(
new GroupChange.Actions.PromotePendingMemberAction.Builder()
return new GroupChange.Actions.Builder().promoteMembersPendingProfileKey(Collections.singletonList(
new GroupChange.Actions.PromoteMemberPendingProfileKeyAction.Builder()
.presentation(ByteString.of(presentation.serialize()))
.build()
));
@@ -297,16 +297,16 @@ public final class GroupsV2Operations {
public GroupChange.Actions.Builder createAcceptPniInviteChange(ExpiringProfileKeyCredential credential) {
ByteString presentation = ByteString.of(clientZkProfileOperations.createProfileKeyCredentialPresentation(random, groupSecretParams, credential).serialize());
return new GroupChange.Actions.Builder().promotePendingPniAciMembers(Collections.singletonList(
new GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction.Builder().presentation(presentation).build()
return new GroupChange.Actions.Builder().promote_members_pending_pni_aci_profile_key(Collections.singletonList(
new GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyAction.Builder().presentation(presentation).build()
));
}
public GroupChange.Actions.Builder createRemoveInvitationChange(final Set<UuidCiphertext> uuidCipherTextsFromInvitesToRemove) {
GroupChange.Actions.Builder builder = new GroupChange.Actions.Builder();
builder.deletePendingMembers = uuidCipherTextsFromInvitesToRemove.stream()
.map(uuidCipherText -> new GroupChange.Actions.DeletePendingMemberAction.Builder().deletedUserId(ByteString.of(uuidCipherText.serialize()))
builder.deleteMembersPendingProfileKey = uuidCipherTextsFromInvitesToRemove.stream()
.map(uuidCipherText -> new GroupChange.Actions.DeleteMemberPendingProfileKeyAction.Builder().deletedUserId(ByteString.of(uuidCipherText.serialize()))
.build())
.collect(Collectors.toList());
@@ -342,8 +342,8 @@ public final class GroupsV2Operations {
}
public GroupChange.Actions.Builder createAnnouncementGroupChange(boolean isAnnouncementGroup) {
return new GroupChange.Actions.Builder().modifyAnnouncementsOnly(
new GroupChange.Actions.ModifyAnnouncementsOnlyAction.Builder().announcementsOnly(isAnnouncementGroup).build()
return new GroupChange.Actions.Builder().modify_announcements_only(
new GroupChange.Actions.ModifyAnnouncementsOnlyAction.Builder().announcements_only(isAnnouncementGroup).build()
);
}
@@ -360,18 +360,18 @@ public final class GroupsV2Operations {
.map(m -> m.serviceIdBytes)
.collect(Collectors.toList());
List<GroupChange.Actions.DeleteBannedMemberAction> deleteBannedMemberActions = new ArrayList<>(builder.deleteBannedMembers);
List<GroupChange.Actions.DeleteMemberBannedAction> deleteBannedMemberActions = new ArrayList<>(builder.delete_members_banned);
for (ByteString serviceIdBinary : unban) {
deleteBannedMemberActions.add(new GroupChange.Actions.DeleteBannedMemberAction.Builder().deletedUserId(encryptServiceId(ServiceId.parseOrThrow(serviceIdBinary.toByteArray()))).build());
deleteBannedMemberActions.add(new GroupChange.Actions.DeleteMemberBannedAction.Builder().deletedUserId(encryptServiceId(ServiceId.parseOrThrow(serviceIdBinary.toByteArray()))).build());
}
builder.deleteBannedMembers(deleteBannedMemberActions);
builder.delete_members_banned(deleteBannedMemberActions);
}
List<GroupChange.Actions.AddBannedMemberAction> addBannedMemberActions = new ArrayList<>(builder.addBannedMembers);
List<GroupChange.Actions.AddMemberBannedAction> AddMemberBannedActions = new ArrayList<>(builder.add_members_banned);
for (ServiceId banServiceId : banServiceIds) {
addBannedMemberActions.add(new GroupChange.Actions.AddBannedMemberAction.Builder().added(new BannedMember.Builder().userId(encryptServiceId(banServiceId)).build()).build());
AddMemberBannedActions.add(new GroupChange.Actions.AddMemberBannedAction.Builder().added(new MemberBanned.Builder().userId(encryptServiceId(banServiceId)).build()).build());
}
builder.addBannedMembers(addBannedMemberActions);
builder.add_members_banned(AddMemberBannedActions);
return builder;
}
@@ -379,8 +379,8 @@ public final class GroupsV2Operations {
public GroupChange.Actions.Builder createUnbanServiceIdsChange(Set<ServiceId> serviceIds) {
GroupChange.Actions.Builder builder = new GroupChange.Actions.Builder();
builder.deleteBannedMembers = serviceIds.stream()
.map(serviceId -> new GroupChange.Actions.DeleteBannedMemberAction.Builder().deletedUserId(encryptServiceId(serviceId)).build())
builder.delete_members_banned = serviceIds.stream()
.map(serviceId -> new GroupChange.Actions.DeleteMemberBannedAction.Builder().deletedUserId(encryptServiceId(serviceId)).build())
.collect(Collectors.toList());
return builder;
@@ -415,20 +415,20 @@ public final class GroupsV2Operations {
.presentation(ByteString.of(presentation.serialize()));
}
private RequestingMember.Builder requestingMember(ExpiringProfileKeyCredential credential) {
private MemberPendingAdminApproval.Builder requestingMember(ExpiringProfileKeyCredential credential) {
ProfileKeyCredentialPresentation presentation = clientZkProfileOperations.createProfileKeyCredentialPresentation(new SecureRandom(), groupSecretParams, credential);
return new RequestingMember.Builder().presentation(ByteString.of(presentation.serialize()));
return new MemberPendingAdminApproval.Builder().presentation(ByteString.of(presentation.serialize()));
}
public PendingMember.Builder invitee(ServiceId serviceId, Member.Role role) {
public MemberPendingProfileKey.Builder invitee(ServiceId serviceId, Member.Role role) {
UuidCiphertext uuidCiphertext = clientZkGroupCipher.encrypt(serviceId.getLibSignalServiceId());
Member member = new Member.Builder().role(role)
.userId(ByteString.of(uuidCiphertext.serialize()))
.build();
return new PendingMember.Builder().member(member);
return new MemberPendingProfileKey.Builder().member(member);
}
public @Nonnull DecryptedGroupResponse decryptGroup(@Nonnull Group group, @Nonnull byte[] groupSendEndorsementsBytes)
@@ -443,13 +443,13 @@ public final class GroupsV2Operations {
public DecryptedGroup decryptGroup(Group group)
throws VerificationFailedException, InvalidGroupStateException
{
List<Member> membersList = group.members;
List<PendingMember> pendingMembersList = group.pendingMembers;
List<RequestingMember> requestingMembersList = group.requestingMembers;
List<DecryptedMember> decryptedMembers = new ArrayList<>(membersList.size());
List<DecryptedPendingMember> decryptedPendingMembers = new ArrayList<>(pendingMembersList.size());
List<DecryptedRequestingMember> decryptedRequestingMembers = new ArrayList<>(requestingMembersList.size());
List<DecryptedBannedMember> decryptedBannedMembers = new ArrayList<>(group.bannedMembers.size());
List<Member> membersList = group.members;
List<MemberPendingProfileKey> pendingMembersList = group.membersPendingProfileKey;
List<MemberPendingAdminApproval> requestingMembersList = group.membersPendingAdminApproval;
List<DecryptedMember> decryptedMembers = new ArrayList<>(membersList.size());
List<DecryptedPendingMember> decryptedPendingMembers = new ArrayList<>(pendingMembersList.size());
List<DecryptedRequestingMember> decryptedRequestingMembers = new ArrayList<>(requestingMembersList.size());
List<DecryptedBannedMember> decryptedBannedMembers = new ArrayList<>(group.members_banned.size());
for (Member member : membersList) {
try {
@@ -459,25 +459,25 @@ public final class GroupsV2Operations {
}
}
for (PendingMember member : pendingMembersList) {
for (MemberPendingProfileKey member : pendingMembersList) {
decryptedPendingMembers.add(decryptMember(member));
}
for (RequestingMember member : requestingMembersList) {
for (MemberPendingAdminApproval member : requestingMembersList) {
decryptedRequestingMembers.add(decryptRequestingMember(member));
}
for (BannedMember member : group.bannedMembers) {
for (MemberBanned member : group.members_banned) {
decryptedBannedMembers.add(new DecryptedBannedMember.Builder().serviceIdBytes(decryptServiceIdToBinary(member.userId)).timestamp(member.timestamp).build());
}
return new DecryptedGroup.Builder()
.title(decryptTitle(group.title))
.description(decryptDescription(group.description))
.isAnnouncementGroup(group.announcementsOnly ? EnabledState.ENABLED : EnabledState.DISABLED)
.avatar(group.avatar)
.isAnnouncementGroup(group.announcements_only ? EnabledState.ENABLED : EnabledState.DISABLED)
.avatar(group.avatarUrl)
.accessControl(group.accessControl)
.revision(group.revision)
.revision(group.version)
.members(decryptedMembers)
.pendingMembers(decryptedPendingMembers)
.requestingMembers(decryptedRequestingMembers)
@@ -506,7 +506,7 @@ public final class GroupsV2Operations {
if (verification.verify()) {
GroupIdentifier groupId = verification.groupId();
if (groupId == null || !Arrays.equals(groupId.serialize(), actions.groupId.toByteArray())) {
if (groupId == null || !Arrays.equals(groupId.serialize(), actions.group_id.toByteArray())) {
throw new VerificationFailedException("Invalid group id");
}
}
@@ -530,18 +530,18 @@ public final class GroupsV2Operations {
if (source != null) {
editorServiceId = source;
} else {
editorServiceId = decryptServiceId(actions.sourceServiceId);
editorServiceId = decryptServiceId(actions.sourceUserId);
}
builder.editorServiceIdBytes(editorServiceId.toByteString());
// Field 2
builder.revision(actions.revision);
builder.revision(actions.version);
// Field 3
List<DecryptedMember> newMembers = new ArrayList<>(actions.addMembers.size());
for (GroupChange.Actions.AddMemberAction addMemberAction : actions.addMembers) {
try {
newMembers.add(decryptMember(addMemberAction.added).joinedAtRevision(actions.revision).build());
newMembers.add(decryptMember(addMemberAction.added).joinedAtRevision(actions.version).build());
} catch (InvalidInputException e) {
throw new InvalidGroupStateException(e);
}
@@ -593,9 +593,9 @@ public final class GroupsV2Operations {
builder.modifiedProfileKeys(modifiedProfileKeys);
// Field 7
List<DecryptedPendingMember> newPendingMembers = new ArrayList<>(actions.addPendingMembers.size());
for (GroupChange.Actions.AddPendingMemberAction addPendingMemberAction : actions.addPendingMembers) {
PendingMember added = addPendingMemberAction.added;
List<DecryptedPendingMember> newPendingMembers = new ArrayList<>(actions.addMembersPendingProfileKey.size());
for (GroupChange.Actions.AddMemberPendingProfileKeyAction AddMemberPendingProfileKeyAction : actions.addMembersPendingProfileKey) {
MemberPendingProfileKey added = AddMemberPendingProfileKeyAction.added;
Member member = added.member;
ByteString serviceIdCipherText = member.userId;
ServiceId serviceId = decryptServiceIdOrUnknown(serviceIdCipherText);
@@ -611,9 +611,9 @@ public final class GroupsV2Operations {
builder.newPendingMembers(newPendingMembers);
// Field 8
List<DecryptedPendingMemberRemoval> deletePendingMembers = new ArrayList<>(actions.deletePendingMembers.size());
for (GroupChange.Actions.DeletePendingMemberAction deletePendingMemberAction : actions.deletePendingMembers) {
ByteString serviceIdCipherText = deletePendingMemberAction.deletedUserId;
List<DecryptedPendingMemberRemoval> deletePendingMembers = new ArrayList<>(actions.deleteMembersPendingProfileKey.size());
for (GroupChange.Actions.DeleteMemberPendingProfileKeyAction DeleteMemberPendingProfileKeyAction : actions.deleteMembersPendingProfileKey) {
ByteString serviceIdCipherText = DeleteMemberPendingProfileKeyAction.deletedUserId;
ServiceId serviceId = decryptServiceIdOrUnknown(serviceIdCipherText);
deletePendingMembers.add(new DecryptedPendingMemberRemoval.Builder()
@@ -624,19 +624,19 @@ public final class GroupsV2Operations {
builder.deletePendingMembers(deletePendingMembers);
// Field 9
List<DecryptedMember> promotePendingMembers = new ArrayList<>(actions.promotePendingMembers.size());
for (GroupChange.Actions.PromotePendingMemberAction promotePendingMemberAction : actions.promotePendingMembers) {
List<DecryptedMember> promotePendingMembers = new ArrayList<>(actions.promoteMembersPendingProfileKey.size());
for (GroupChange.Actions.PromoteMemberPendingProfileKeyAction PromoteMemberPendingProfileKeyAction : actions.promoteMembersPendingProfileKey) {
try {
ACI aci;
ProfileKey profileKey;
if (promotePendingMemberAction.user_id.size() == 0 || promotePendingMemberAction.profile_key.size() == 0) {
ProfileKeyCredentialPresentation presentation = new ProfileKeyCredentialPresentation(promotePendingMemberAction.presentation.toByteArray());
if (PromoteMemberPendingProfileKeyAction.user_id.size() == 0 || PromoteMemberPendingProfileKeyAction.profile_key.size() == 0) {
ProfileKeyCredentialPresentation presentation = new ProfileKeyCredentialPresentation(PromoteMemberPendingProfileKeyAction.presentation.toByteArray());
aci = decryptAci(ByteString.of(presentation.getUuidCiphertext().serialize()));
profileKey = decryptProfileKey(ByteString.of(presentation.getProfileKeyCiphertext().serialize()), aci);
} else {
aci = decryptAci(promotePendingMemberAction.user_id);
profileKey = decryptProfileKey(promotePendingMemberAction.profile_key, aci);
aci = decryptAci(PromoteMemberPendingProfileKeyAction.user_id);
profileKey = decryptProfileKey(PromoteMemberPendingProfileKeyAction.profile_key, aci);
}
promotePendingMembers.add(new DecryptedMember.Builder()
@@ -662,8 +662,8 @@ public final class GroupsV2Operations {
}
// Field 12
if (actions.modifyDisappearingMessagesTimer != null) {
int duration = decryptDisappearingMessagesTimer(actions.modifyDisappearingMessagesTimer.timer);
if (actions.modifyDisappearingMessageTimer != null) {
int duration = decryptDisappearingMessagesTimer(actions.modifyDisappearingMessageTimer.timer);
builder.newTimer(new DecryptedTimer.Builder().duration(duration).build());
}
@@ -683,22 +683,22 @@ public final class GroupsV2Operations {
}
// Field 16
List<DecryptedRequestingMember> newRequestingMembers = new ArrayList<>(actions.addRequestingMembers.size());
for (GroupChange.Actions.AddRequestingMemberAction request : actions.addRequestingMembers) {
List<DecryptedRequestingMember> newRequestingMembers = new ArrayList<>(actions.addMembersPendingAdminApproval.size());
for (GroupChange.Actions.AddMemberPendingAdminApprovalAction request : actions.addMembersPendingAdminApproval) {
newRequestingMembers.add(decryptRequestingMember(request.added));
}
builder.newRequestingMembers(newRequestingMembers);
// Field 17
List<ByteString> deleteRequestingMembers = new ArrayList<>(actions.deleteRequestingMembers.size());
for (GroupChange.Actions.DeleteRequestingMemberAction delete : actions.deleteRequestingMembers) {
List<ByteString> deleteRequestingMembers = new ArrayList<>(actions.deleteMembersPendingAdminApproval.size());
for (GroupChange.Actions.DeleteMemberPendingAdminApprovalAction delete : actions.deleteMembersPendingAdminApproval) {
deleteRequestingMembers.add(decryptServiceIdToBinary(delete.deletedUserId));
}
builder.deleteRequestingMembers(deleteRequestingMembers);
// Field 18
List<DecryptedApproveMember> promoteRequestingMembers = new ArrayList<>(actions.promoteRequestingMembers.size());
for (GroupChange.Actions.PromoteRequestingMemberAction promote : actions.promoteRequestingMembers) {
List<DecryptedApproveMember> promoteRequestingMembers = new ArrayList<>(actions.promoteMembersPendingAdminApproval.size());
for (GroupChange.Actions.PromoteMemberPendingAdminApprovalAction promote : actions.promoteMembersPendingAdminApproval) {
promoteRequestingMembers.add(new DecryptedApproveMember.Builder().role(promote.role).aciBytes(decryptAciToBinary(promote.userId)).build());
}
builder.promoteRequestingMembers(promoteRequestingMembers);
@@ -714,30 +714,30 @@ public final class GroupsV2Operations {
}
// Field 21
if (actions.modifyAnnouncementsOnly != null) {
builder.newIsAnnouncementGroup(actions.modifyAnnouncementsOnly.announcementsOnly ? EnabledState.ENABLED : EnabledState.DISABLED);
if (actions.modify_announcements_only != null) {
builder.newIsAnnouncementGroup(actions.modify_announcements_only.announcements_only ? EnabledState.ENABLED : EnabledState.DISABLED);
}
// Field 22
List<DecryptedBannedMember> newBannedMembers = new ArrayList<>(actions.addBannedMembers.size());
for (GroupChange.Actions.AddBannedMemberAction action : actions.addBannedMembers) {
List<DecryptedBannedMember> newBannedMembers = new ArrayList<>(actions.add_members_banned.size());
for (GroupChange.Actions.AddMemberBannedAction action : actions.add_members_banned) {
newBannedMembers.add(new DecryptedBannedMember.Builder().serviceIdBytes(decryptServiceIdToBinary(action.added.userId)).timestamp(action.added.timestamp).build());
}
builder.newBannedMembers(newBannedMembers);
// Field 23
List<DecryptedBannedMember> deleteBannedMembers = new ArrayList<>(actions.deleteBannedMembers.size());
for (GroupChange.Actions.DeleteBannedMemberAction action : actions.deleteBannedMembers) {
List<DecryptedBannedMember> deleteBannedMembers = new ArrayList<>(actions.delete_members_banned.size());
for (GroupChange.Actions.DeleteMemberBannedAction action : actions.delete_members_banned) {
deleteBannedMembers.add(new DecryptedBannedMember.Builder().serviceIdBytes(decryptServiceIdToBinary(action.deletedUserId)).build());
}
builder.deleteBannedMembers(deleteBannedMembers);
// Field 24
List<DecryptedMember> promotePendingPniAciMembers = new ArrayList<>(actions.promotePendingPniAciMembers.size());
for (GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction promotePendingPniAciMemberAction : actions.promotePendingPniAciMembers) {
ACI aci = decryptAci(promotePendingPniAciMemberAction.userId);
List<DecryptedMember> promotePendingPniAciMembers = new ArrayList<>(actions.promote_members_pending_pni_aci_profile_key.size());
for (GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyAction promotePendingPniAciMemberAction : actions.promote_members_pending_pni_aci_profile_key) {
ACI aci = decryptAci(promotePendingPniAciMemberAction.user_id);
ServiceId pni = decryptServiceId(promotePendingPniAciMemberAction.pni);
ProfileKey profileKey = decryptProfileKey(promotePendingPniAciMemberAction.profileKey, aci);
ProfileKey profileKey = decryptProfileKey(promotePendingPniAciMemberAction.profile_key, aci);
if (!(pni instanceof PNI)) {
throw new InvalidGroupStateException();
@@ -748,7 +748,7 @@ public final class GroupsV2Operations {
.aciBytes(aci.toByteString())
.role(Member.Role.DEFAULT)
.profileKey(ByteString.of(profileKey.serialize()))
.joinedAtRevision(actions.revision)
.joinedAtRevision(actions.version)
.pniBytes(pni.toByteString())
.build());
}
@@ -766,7 +766,7 @@ public final class GroupsV2Operations {
Log.w(TAG, "Unable to replace PNI editor with ACI for add member update");
builder.editorServiceIdBytes(ByteString.EMPTY);
}
} else if (actions.deletePendingMembers.isEmpty() && actions.promotePendingPniAciMembers.isEmpty()) {
} else if (actions.deleteMembersPendingProfileKey.isEmpty() && actions.promote_members_pending_pni_aci_profile_key.isEmpty()) {
Log.w(TAG, "Received group change with PNI editor for a non-PNI editor eligible update, clearing editor");
builder.editorServiceIdBytes(ByteString.EMPTY);
}
@@ -781,7 +781,7 @@ public final class GroupsV2Operations {
.avatar(joinInfo.avatar)
.memberCount(joinInfo.memberCount)
.addFromInviteLink(joinInfo.addFromInviteLink)
.revision(joinInfo.revision)
.revision(joinInfo.version)
.pendingAdminApproval(joinInfo.pendingAdminApproval)
.description(decryptDescription(joinInfo.description))
.build();
@@ -795,7 +795,7 @@ public final class GroupsV2Operations {
return new DecryptedMember.Builder()
.aciBytes(aci.toByteString())
.joinedAtRevision(member.joinedAtRevision)
.joinedAtRevision(member.joinedAtVersion)
.profileKey(decryptProfileKeyToByteString(member.profileKey, aci))
.role(member.role);
} else {
@@ -811,13 +811,13 @@ public final class GroupsV2Operations {
return new DecryptedMember.Builder()
.aciBytes(aci.toByteString())
.joinedAtRevision(member.joinedAtRevision)
.joinedAtRevision(member.joinedAtVersion)
.profileKey(ByteString.of(profileKey.serialize()))
.role(member.role);
}
}
private DecryptedPendingMember decryptMember(PendingMember member)
private DecryptedPendingMember decryptMember(MemberPendingProfileKey member)
throws InvalidGroupStateException, VerificationFailedException
{
ByteString userIdCipherText = member.member.userId;
@@ -839,7 +839,7 @@ public final class GroupsV2Operations {
.build();
}
private DecryptedRequestingMember decryptRequestingMember(RequestingMember member)
private DecryptedRequestingMember decryptRequestingMember(MemberPendingAdminApproval member)
throws InvalidGroupStateException, VerificationFailedException
{
if (member.presentation.size() == 0) {
@@ -956,7 +956,7 @@ public final class GroupsV2Operations {
ByteString encryptDescription(String description) {
try {
GroupAttributeBlob blob = new GroupAttributeBlob.Builder().description(description).build();
GroupAttributeBlob blob = new GroupAttributeBlob.Builder().descriptionText(description).build();
return ByteString.of(clientZkGroupCipher.encryptBlob(blob.encode()));
} catch (VerificationFailedException e) {
@@ -965,7 +965,7 @@ public final class GroupsV2Operations {
}
private String decryptDescription(ByteString cipherText) {
String description = decryptBlob(cipherText).description;
String description = decryptBlob(cipherText).descriptionText;
return description != null ? description.trim() : "";
}

View File

@@ -14,15 +14,15 @@ import org.signal.core.util.Base64;
import org.signal.core.util.Hex;
import org.signal.libsignal.protocol.InvalidKeyException;
import org.signal.libsignal.protocol.logging.Log;
import org.signal.storageservice.protos.groups.AvatarUploadAttributes;
import org.signal.storageservice.protos.groups.Group;
import org.signal.storageservice.protos.groups.GroupChange;
import org.signal.storageservice.protos.groups.GroupChangeResponse;
import org.signal.storageservice.protos.groups.GroupChanges;
import org.signal.storageservice.protos.groups.GroupExternalCredential;
import org.signal.storageservice.protos.groups.GroupJoinInfo;
import org.signal.storageservice.protos.groups.GroupResponse;
import org.signal.storageservice.protos.groups.Member;
import org.signal.storageservice.storage.protos.groups.AvatarUploadAttributes;
import org.signal.storageservice.storage.protos.groups.Group;
import org.signal.storageservice.storage.protos.groups.GroupChange;
import org.signal.storageservice.storage.protos.groups.GroupChangeResponse;
import org.signal.storageservice.storage.protos.groups.GroupChanges;
import org.signal.storageservice.storage.protos.groups.ExternalGroupCredential;
import org.signal.storageservice.storage.protos.groups.GroupJoinInfo;
import org.signal.storageservice.storage.protos.groups.GroupResponse;
import org.signal.storageservice.storage.protos.groups.Member;
import org.whispersystems.signalservice.api.NetworkResult;
import org.whispersystems.signalservice.api.account.AccountAttributes;
import org.whispersystems.signalservice.api.account.PreKeyCollection;
@@ -2066,7 +2066,7 @@ public class PushServiceSocket {
null,
GROUPS_V2_GET_CURRENT_HANDLER))
{
return Member.ADAPTER.decode(readBodyBytes(response)).joinedAtRevision;
return Member.ADAPTER.decode(readBodyBytes(response)).joinedAtVersion;
}
}
@@ -2084,7 +2084,7 @@ public class PushServiceSocket {
}
}
public GroupExternalCredential getGroupExternalCredential(GroupsV2AuthorizationString authorization)
public ExternalGroupCredential getExternalGroupCredential(GroupsV2AuthorizationString authorization)
throws NonSuccessfulResponseCodeException, PushNetworkException, IOException, MalformedResponseException
{
try (Response response = makeStorageRequest(authorization.toString(),
@@ -2093,7 +2093,7 @@ public class PushServiceSocket {
null,
NO_HANDLER))
{
return GroupExternalCredential.ADAPTER.decode(readBodyBytes(response));
return ExternalGroupCredential.ADAPTER.decode(readBodyBytes(response));
}
}

View File

@@ -5,7 +5,9 @@
*/
syntax = "proto3";
option java_package = "org.signal.storageservice.protos.groups.local";
package signal;
option java_package = "org.signal.storageservice.storage.protos.groups.local";
option java_multiple_files = true;
import "Groups.proto";

View File

@@ -1,92 +1,135 @@
/**
* Copyright (C) 2019 Open Whisper Systems
*
* Licensed according to the LICENSE file in this repository.
/*
* Copyright 2020 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
syntax = "proto3";
option java_package = "org.signal.storageservice.protos.groups";
package signal;
option java_package = "org.signal.storageservice.storage.protos.groups";
option java_outer_classname = "GroupProtos";
option java_multiple_files = true;
message AvatarUploadAttributes {
string key = 1;
string key = 1;
string credential = 2;
string acl = 3;
string algorithm = 4;
string date = 5;
string policy = 6;
string signature = 7;
string acl = 3;
string algorithm = 4;
string date = 5;
string policy = 6;
string signature = 7;
}
// Stored data
message Member {
enum Role {
UNKNOWN = 0;
DEFAULT = 1;
UNKNOWN = 0;
DEFAULT = 1;
ADMINISTRATOR = 2;
}
bytes userId = 1;
Role role = 2;
bytes profileKey = 3;
bytes presentation = 4; // Only set when sending to server
uint32 joinedAtRevision = 5;
bytes userId = 1;
Role role = 2;
bytes profileKey = 3;
bytes presentation = 4;
uint32 joinedAtVersion = 5;
}
message PendingMember {
Member member = 1;
bytes addedByUserId = 2;
uint64 timestamp = 3;
message MemberPendingProfileKey {
Member member = 1;
bytes addedByUserId = 2;
uint64 timestamp = 3; // ms since epoch
}
message RequestingMember {
bytes userId = 1;
bytes profileKey = 2;
bytes presentation = 3; // Only set when sending to server
uint64 timestamp = 4;
message MemberPendingAdminApproval {
bytes userId = 1;
bytes profileKey = 2;
bytes presentation = 3;
uint64 timestamp = 4; // ms since epoch
}
message BannedMember {
bytes userId = 1;
uint64 timestamp = 2;
message MemberBanned {
bytes userId = 1;
uint64 timestamp = 2; // ms since epoch
}
message AccessControl {
enum AccessRequired {
UNKNOWN = 0;
ANY = 1;
MEMBER = 2;
UNKNOWN = 0;
ANY = 1;
MEMBER = 2;
ADMINISTRATOR = 3;
UNSATISFIABLE = 4;
}
AccessRequired attributes = 1;
AccessRequired members = 2;
AccessRequired attributes = 1;
AccessRequired members = 2;
AccessRequired addFromInviteLink = 3;
}
message Group {
bytes publicKey = 1;
bytes title = 2;
string avatar = 3;
bytes disappearingMessagesTimer = 4;
AccessControl accessControl = 5;
uint32 revision = 6;
repeated Member members = 7;
repeated PendingMember pendingMembers = 8;
repeated RequestingMember requestingMembers = 9;
bytes inviteLinkPassword = 10;
bytes description = 11;
bool announcementsOnly = 12;
repeated BannedMember bannedMembers = 13;
bytes publicKey = 1;
bytes title = 2;
bytes description = 11;
// The URL for this group's avatar. The content at this URL can be
// decrypted/deserialized into a `GroupAttributeBlob`.
string avatarUrl = 3;
bytes disappearingMessagesTimer = 4;
AccessControl accessControl = 5;
uint32 version = 6;
repeated Member members = 7;
repeated MemberPendingProfileKey membersPendingProfileKey = 8;
repeated MemberPendingAdminApproval membersPendingAdminApproval = 9;
bytes inviteLinkPassword = 10;
bool announcements_only = 12;
repeated MemberBanned members_banned = 13;
// next: 14
}
message GroupAttributeBlob {
oneof content {
string title = 1;
bytes avatar = 2;
uint32 disappearingMessagesDuration = 3;
string descriptionText = 4;
}
}
message GroupInviteLink {
message GroupInviteLinkContentsV1 {
bytes groupMasterKey = 1;
bytes inviteLinkPassword = 2;
}
oneof contents {
GroupInviteLinkContentsV1 contentsV1 = 1;
}
}
message GroupJoinInfo {
bytes publicKey = 1;
bytes title = 2;
bytes description = 8;
string avatar = 3;
uint32 memberCount = 4;
AccessControl.AccessRequired addFromInviteLink = 5;
uint32 version = 6;
bool pendingAdminApproval = 7;
// bool pendingAdminApprovalFull = 9;
// next: 10
}
// Deltas
message GroupChange {
message Actions {
message AddMemberAction {
Member added = 1;
bool joinFromInviteLink = 2;
Member added = 1;
bool joinFromInviteLink = 2;
}
message DeleteMemberAction {
@@ -94,55 +137,55 @@ message GroupChange {
}
message ModifyMemberRoleAction {
bytes userId = 1;
Member.Role role = 2;
bytes userId = 1;
Member.Role role = 2;
}
message ModifyMemberProfileKeyAction {
bytes presentation = 1; // Only set when sending to server
bytes user_id = 2; // Only set when receiving from server
bytes profile_key = 3; // Only set when receiving from server
bytes presentation = 1;
bytes user_id = 2;
bytes profile_key = 3;
}
message AddPendingMemberAction {
PendingMember added = 1;
message AddMemberPendingProfileKeyAction {
MemberPendingProfileKey added = 1;
}
message DeletePendingMemberAction {
message DeleteMemberPendingProfileKeyAction {
bytes deletedUserId = 1;
}
message PromotePendingMemberAction {
bytes presentation = 1; // Only set when sending to server
bytes user_id = 2; // Only set when receiving from server
bytes profile_key = 3; // Only set when receiving from server
message PromoteMemberPendingProfileKeyAction {
bytes presentation = 1;
bytes user_id = 2;
bytes profile_key = 3;
}
message PromotePendingPniAciMemberProfileKeyAction {
bytes presentation = 1; // Only set when sending to server
bytes userId = 2; // Only set when receiving from server
bytes pni = 3; // Only set when receiving from server
bytes profileKey = 4; // Only set when receiving from server
message PromoteMemberPendingPniAciProfileKeyAction {
bytes presentation = 1;
bytes user_id = 2;
bytes pni = 3;
bytes profile_key = 4;
}
message AddRequestingMemberAction {
RequestingMember added = 1;
message AddMemberPendingAdminApprovalAction {
MemberPendingAdminApproval added = 1;
}
message DeleteRequestingMemberAction {
message DeleteMemberPendingAdminApprovalAction {
bytes deletedUserId = 1;
}
message PromoteRequestingMemberAction {
bytes userId = 1;
Member.Role role = 2;
message PromoteMemberPendingAdminApprovalAction {
bytes userId = 1;
Member.Role role = 2;
}
message AddBannedMemberAction {
BannedMember added = 1;
message AddMemberBannedAction {
MemberBanned added = 1;
}
message DeleteBannedMemberAction {
message DeleteMemberBannedAction {
bytes deletedUserId = 1;
}
@@ -158,7 +201,7 @@ message GroupChange {
string avatar = 1;
}
message ModifyDisappearingMessagesTimerAction {
message ModifyDisappearingMessageTimerAction {
bytes timer = 1;
}
@@ -179,92 +222,69 @@ message GroupChange {
}
message ModifyAnnouncementsOnlyAction {
bool announcementsOnly = 1;
bool announcements_only = 1;
}
bytes sourceServiceId = 1;
bytes groupId = 25; // Only set when receiving from server
uint32 revision = 2;
repeated AddMemberAction addMembers = 3;
repeated DeleteMemberAction deleteMembers = 4;
repeated ModifyMemberRoleAction modifyMemberRoles = 5;
repeated ModifyMemberProfileKeyAction modifyMemberProfileKeys = 6;
repeated AddPendingMemberAction addPendingMembers = 7;
repeated DeletePendingMemberAction deletePendingMembers = 8;
repeated PromotePendingMemberAction promotePendingMembers = 9;
ModifyTitleAction modifyTitle = 10;
ModifyAvatarAction modifyAvatar = 11;
ModifyDisappearingMessagesTimerAction modifyDisappearingMessagesTimer = 12;
ModifyAttributesAccessControlAction modifyAttributesAccess = 13;
ModifyMembersAccessControlAction modifyMemberAccess = 14;
ModifyAddFromInviteLinkAccessControlAction modifyAddFromInviteLinkAccess = 15;
repeated AddRequestingMemberAction addRequestingMembers = 16;
repeated DeleteRequestingMemberAction deleteRequestingMembers = 17;
repeated PromoteRequestingMemberAction promoteRequestingMembers = 18;
ModifyInviteLinkPasswordAction modifyInviteLinkPassword = 19;
ModifyDescriptionAction modifyDescription = 20;
ModifyAnnouncementsOnlyAction modifyAnnouncementsOnly = 21;
repeated AddBannedMemberAction addBannedMembers = 22;
repeated DeleteBannedMemberAction deleteBannedMembers = 23;
repeated PromotePendingPniAciMemberProfileKeyAction promotePendingPniAciMembers = 24;
bytes sourceUserId = 1;
// clients should not provide this value; the server will provide it in the response buffer to ensure the signature is binding to a particular group
// if clients set it during a request the server will respond with 400.
bytes group_id = 25;
uint32 version = 2;
repeated AddMemberAction addMembers = 3;
repeated DeleteMemberAction deleteMembers = 4;
repeated ModifyMemberRoleAction modifyMemberRoles = 5;
repeated ModifyMemberProfileKeyAction modifyMemberProfileKeys = 6;
repeated AddMemberPendingProfileKeyAction addMembersPendingProfileKey = 7;
repeated DeleteMemberPendingProfileKeyAction deleteMembersPendingProfileKey = 8;
repeated PromoteMemberPendingProfileKeyAction promoteMembersPendingProfileKey = 9;
ModifyTitleAction modifyTitle = 10;
ModifyAvatarAction modifyAvatar = 11;
ModifyDisappearingMessageTimerAction modifyDisappearingMessageTimer = 12;
ModifyAttributesAccessControlAction modifyAttributesAccess = 13;
ModifyMembersAccessControlAction modifyMemberAccess = 14;
ModifyAddFromInviteLinkAccessControlAction modifyAddFromInviteLinkAccess = 15; // change epoch = 1
repeated AddMemberPendingAdminApprovalAction addMembersPendingAdminApproval = 16; // change epoch = 1
repeated DeleteMemberPendingAdminApprovalAction deleteMembersPendingAdminApproval = 17; // change epoch = 1
repeated PromoteMemberPendingAdminApprovalAction promoteMembersPendingAdminApproval = 18; // change epoch = 1
ModifyInviteLinkPasswordAction modifyInviteLinkPassword = 19; // change epoch = 1
ModifyDescriptionAction modifyDescription = 20; // change epoch = 2
ModifyAnnouncementsOnlyAction modify_announcements_only = 21; // change epoch = 3
repeated AddMemberBannedAction add_members_banned = 22; // change epoch = 4
repeated DeleteMemberBannedAction delete_members_banned = 23; // change epoch = 4
repeated PromoteMemberPendingPniAciProfileKeyAction promote_members_pending_pni_aci_profile_key = 24; // change epoch = 5
// next: 26
}
bytes actions = 1;
bytes serverSignature = 2;
uint32 changeEpoch = 3;
bytes actions = 1;
bytes serverSignature = 2;
uint32 changeEpoch = 3;
}
// External credentials
message ExternalGroupCredential {
string token = 1;
}
// API responses
message GroupResponse {
Group group = 1;
bytes groupSendEndorsementsResponse = 2;
Group group = 1;
bytes group_send_endorsements_response = 2;
}
message GroupChanges {
message GroupChangeState {
GroupChange groupChange = 1;
Group groupState = 2;
Group groupState = 2;
}
repeated GroupChangeState groupChanges = 1;
bytes groupSendEndorsementsResponse = 2;
repeated GroupChangeState groupChanges = 1;
bytes group_send_endorsements_response = 2;
}
message GroupChangeResponse {
GroupChange groupChange = 1;
bytes groupSendEndorsementsResponse = 2;
}
message GroupAttributeBlob {
oneof content {
string title = 1;
bytes avatar = 2;
uint32 disappearingMessagesDuration = 3;
string description = 4;
}
}
message GroupInviteLink {
message GroupInviteLinkContentsV1 {
bytes groupMasterKey = 1;
bytes inviteLinkPassword = 2;
}
oneof contents {
GroupInviteLinkContentsV1 v1Contents = 1;
}
}
message GroupJoinInfo {
bytes publicKey = 1;
bytes title = 2;
string avatar = 3;
uint32 memberCount = 4;
AccessControl.AccessRequired addFromInviteLink = 5;
uint32 revision = 6;
bool pendingAdminApproval = 7;
bytes description = 8;
}
message GroupExternalCredential {
string token = 1;
}
GroupChange group_change = 1;
bytes group_send_endorsements_response = 2;
}

View File

@@ -7,9 +7,9 @@ import assertk.assertions.isNull
import okio.ByteString
import org.junit.Test
import org.signal.core.models.ServiceId
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember
import org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMemberRemoval
import org.whispersystems.signalservice.internal.util.Util
import java.util.UUID

View File

@@ -2,20 +2,20 @@ package org.whispersystems.signalservice.api.groupsv2;
import org.junit.Test;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
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.DecryptedBannedMember;
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.storageservice.protos.groups.local.EnabledState;
import org.signal.storageservice.storage.protos.groups.AccessControl;
import org.signal.storageservice.storage.protos.groups.Member;
import org.signal.storageservice.storage.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberRole;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMemberRemoval;
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
import org.signal.core.util.UuidUtil;
import org.whispersystems.signalservice.internal.util.Util;

View File

@@ -1,14 +1,14 @@
package org.whispersystems.signalservice.api.groupsv2;
import org.junit.Test;
import org.signal.storageservice.protos.groups.AccessControl;
import org.signal.storageservice.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
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.storageservice.protos.groups.local.EnabledState;
import org.signal.storageservice.storage.protos.groups.AccessControl;
import org.signal.storageservice.storage.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
import org.signal.core.util.UuidUtil;
import java.util.List;

View File

@@ -2,12 +2,12 @@ package org.whispersystems.signalservice.api.groupsv2;
import org.junit.Test;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.signal.storageservice.protos.groups.AccessControl;
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.protos.groups.local.DecryptedString;
import org.signal.storageservice.protos.groups.local.DecryptedTimer;
import org.signal.storageservice.protos.groups.local.EnabledState;
import org.signal.storageservice.storage.protos.groups.AccessControl;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
import org.signal.core.util.UuidUtil;
import org.whispersystems.signalservice.internal.util.Util;

View File

@@ -1,7 +1,7 @@
package org.whispersystems.signalservice.api.groupsv2;
import org.junit.Test;
import org.signal.storageservice.protos.groups.GroupChange;
import org.signal.storageservice.storage.protos.groups.GroupChange;
import java.util.List;
@@ -69,7 +69,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
@Test
public void not_empty_with_add_pending_members_field_7() {
GroupChange.Actions actions = new GroupChange.Actions.Builder()
.addPendingMembers(List.of(new GroupChange.Actions.AddPendingMemberAction()))
.addMembersPendingProfileKey(List.of(new GroupChange.Actions.AddMemberPendingProfileKeyAction()))
.build();
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
@@ -78,7 +78,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
@Test
public void not_empty_with_delete_pending_members_field_8() {
GroupChange.Actions actions = new GroupChange.Actions.Builder()
.deletePendingMembers(List.of(new GroupChange.Actions.DeletePendingMemberAction()))
.deleteMembersPendingProfileKey(List.of(new GroupChange.Actions.DeleteMemberPendingProfileKeyAction()))
.build();
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
@@ -87,7 +87,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
@Test
public void not_empty_with_promote_delete_pending_members_field_9() {
GroupChange.Actions actions = new GroupChange.Actions.Builder()
.promotePendingMembers(List.of(new GroupChange.Actions.PromotePendingMemberAction()))
.promoteMembersPendingProfileKey(List.of(new GroupChange.Actions.PromoteMemberPendingProfileKeyAction()))
.build();
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
@@ -114,7 +114,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
@Test
public void not_empty_with_modify_disappearing_message_timer_field_12() {
GroupChange.Actions actions = new GroupChange.Actions.Builder()
.modifyDisappearingMessagesTimer(new GroupChange.Actions.ModifyDisappearingMessagesTimerAction())
.modifyDisappearingMessageTimer(new GroupChange.Actions.ModifyDisappearingMessageTimerAction())
.build();
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
@@ -150,7 +150,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
@Test
public void not_empty_with_add_requesting_members_field_16() {
GroupChange.Actions actions = new GroupChange.Actions.Builder()
.addRequestingMembers(List.of(new GroupChange.Actions.AddRequestingMemberAction()))
.addMembersPendingAdminApproval(List.of(new GroupChange.Actions.AddMemberPendingAdminApprovalAction()))
.build();
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
@@ -159,7 +159,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
@Test
public void not_empty_with_delete_requesting_members_field_17() {
GroupChange.Actions actions = new GroupChange.Actions.Builder()
.deleteRequestingMembers(List.of(new GroupChange.Actions.DeleteRequestingMemberAction()))
.deleteMembersPendingAdminApproval(List.of(new GroupChange.Actions.DeleteMemberPendingAdminApprovalAction()))
.build();
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
@@ -168,7 +168,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
@Test
public void not_empty_with_promote_requesting_members_field_18() {
GroupChange.Actions actions = new GroupChange.Actions.Builder()
.promoteRequestingMembers(List.of(new GroupChange.Actions.PromoteRequestingMemberAction()))
.promoteMembersPendingAdminApproval(List.of(new GroupChange.Actions.PromoteMemberPendingAdminApprovalAction()))
.build();
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
@@ -195,7 +195,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
@Test
public void not_empty_with_modify_description_field_21() {
GroupChange.Actions actions = new GroupChange.Actions.Builder()
.modifyAnnouncementsOnly(new GroupChange.Actions.ModifyAnnouncementsOnlyAction())
.modify_announcements_only(new GroupChange.Actions.ModifyAnnouncementsOnlyAction())
.build();
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
@@ -204,7 +204,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
@Test
public void not_empty_with_add_banned_member_field_22() {
GroupChange.Actions actions = new GroupChange.Actions.Builder()
.addBannedMembers(List.of(new GroupChange.Actions.AddBannedMemberAction()))
.add_members_banned(List.of(new GroupChange.Actions.AddMemberBannedAction()))
.build();
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
@@ -213,7 +213,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
@Test
public void not_empty_with_delete_banned_member_field_23() {
GroupChange.Actions actions = new GroupChange.Actions.Builder()
.deleteBannedMembers(List.of(new GroupChange.Actions.DeleteBannedMemberAction()))
.delete_members_banned(List.of(new GroupChange.Actions.DeleteMemberBannedAction()))
.build();
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
@@ -222,7 +222,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
@Test
public void not_empty_with_promote_pending_pni_aci_members_field_24() {
GroupChange.Actions actions = new GroupChange.Actions.Builder()
.promotePendingPniAciMembers(List.of(new GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction()))
.promote_members_pending_pni_aci_profile_key(List.of(new GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyAction()))
.build();
assertFalse(GroupChangeUtil.changeIsEmpty(actions));

View File

@@ -2,17 +2,17 @@ package org.whispersystems.signalservice.api.groupsv2;
import org.junit.Test;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.signal.storageservice.protos.groups.AccessControl;
import org.signal.storageservice.protos.groups.BannedMember;
import org.signal.storageservice.protos.groups.GroupChange;
import org.signal.storageservice.protos.groups.Member;
import org.signal.storageservice.protos.groups.PendingMember;
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.DecryptedString;
import org.signal.storageservice.protos.groups.local.DecryptedTimer;
import org.signal.storageservice.protos.groups.local.EnabledState;
import org.signal.storageservice.storage.protos.groups.AccessControl;
import org.signal.storageservice.storage.protos.groups.MemberBanned;
import org.signal.storageservice.storage.protos.groups.GroupChange;
import org.signal.storageservice.storage.protos.groups.Member;
import org.signal.storageservice.storage.protos.groups.MemberPendingProfileKey;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
import org.signal.core.util.UuidUtil;
import org.whispersystems.signalservice.internal.util.Util;
@@ -250,15 +250,15 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.addPendingMembers(List.of(new GroupChange.Actions.AddPendingMemberAction.Builder().added(new PendingMember.Builder().member(encryptedMember(member1, randomProfileKey())).build()).build(),
new GroupChange.Actions.AddPendingMemberAction.Builder().added(new PendingMember.Builder().member(encryptedMember(member2, profileKey2)).build()).build(),
new GroupChange.Actions.AddPendingMemberAction.Builder().added(new PendingMember.Builder().member(encryptedMember(member3, randomProfileKey())).build()).build()))
.addMembersPendingProfileKey(List.of(new GroupChange.Actions.AddMemberPendingProfileKeyAction.Builder().added(new MemberPendingProfileKey.Builder().member(encryptedMember(member1, randomProfileKey())).build()).build(),
new GroupChange.Actions.AddMemberPendingProfileKeyAction.Builder().added(new MemberPendingProfileKey.Builder().member(encryptedMember(member2, profileKey2)).build()).build(),
new GroupChange.Actions.AddMemberPendingProfileKeyAction.Builder().added(new MemberPendingProfileKey.Builder().member(encryptedMember(member3, randomProfileKey())).build()).build()))
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
GroupChange.Actions expected = new GroupChange.Actions.Builder()
.addPendingMembers(List.of(new GroupChange.Actions.AddPendingMemberAction.Builder().added(new PendingMember.Builder().member(encryptedMember(member2, profileKey2)).build()).build()))
.addMembersPendingProfileKey(List.of(new GroupChange.Actions.AddMemberPendingProfileKeyAction.Builder().added(new MemberPendingProfileKey.Builder().member(encryptedMember(member2, profileKey2)).build()).build()))
.build();
assertEquals(expected, resolvedActions);
@@ -280,15 +280,15 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.deletePendingMembers(List.of(new GroupChange.Actions.DeletePendingMemberAction.Builder().deletedUserId(encrypt(member1)).build(),
new GroupChange.Actions.DeletePendingMemberAction.Builder().deletedUserId(encrypt(member2)).build(),
new GroupChange.Actions.DeletePendingMemberAction.Builder().deletedUserId(encrypt(member3)).build()))
.deleteMembersPendingProfileKey(List.of(new GroupChange.Actions.DeleteMemberPendingProfileKeyAction.Builder().deletedUserId(encrypt(member1)).build(),
new GroupChange.Actions.DeleteMemberPendingProfileKeyAction.Builder().deletedUserId(encrypt(member2)).build(),
new GroupChange.Actions.DeleteMemberPendingProfileKeyAction.Builder().deletedUserId(encrypt(member3)).build()))
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
GroupChange.Actions expected = new GroupChange.Actions.Builder()
.deletePendingMembers(List.of(new GroupChange.Actions.DeletePendingMemberAction.Builder().deletedUserId(encrypt(member2)).build()))
.deleteMembersPendingProfileKey(List.of(new GroupChange.Actions.DeleteMemberPendingProfileKeyAction.Builder().deletedUserId(encrypt(member2)).build()))
.build();
assertEquals(expected, resolvedActions);
@@ -311,16 +311,16 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.promotePendingMembers(List.of(new GroupChange.Actions.PromotePendingMemberAction.Builder().presentation(presentation(member1, randomProfileKey())).build(),
new GroupChange.Actions.PromotePendingMemberAction.Builder().presentation(presentation(member2, profileKey2)).build(),
new GroupChange.Actions.PromotePendingMemberAction.Builder().presentation(presentation(member3, randomProfileKey())).build()))
.promoteMembersPendingProfileKey(List.of(new GroupChange.Actions.PromoteMemberPendingProfileKeyAction.Builder().presentation(presentation(member1, randomProfileKey())).build(),
new GroupChange.Actions.PromoteMemberPendingProfileKeyAction.Builder().presentation(presentation(member2, profileKey2)).build(),
new GroupChange.Actions.PromoteMemberPendingProfileKeyAction.Builder().presentation(presentation(member3, randomProfileKey())).build()))
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
GroupChange.Actions expected = new GroupChange.Actions.Builder()
.promotePendingMembers(List.of(new GroupChange.Actions.PromotePendingMemberAction.Builder().presentation(presentation(member2, profileKey2)).build()))
.promoteMembersPendingProfileKey(List.of(new GroupChange.Actions.PromoteMemberPendingProfileKeyAction.Builder().presentation(presentation(member2, profileKey2)).build()))
.build();
assertEquals(expected, resolvedActions);
@@ -346,7 +346,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
GroupChange.Actions expected = new GroupChange.Actions.Builder()
.promotePendingMembers(List.of(new GroupChange.Actions.PromotePendingMemberAction.Builder().presentation(presentation(member1, profileKey1)).build()))
.promoteMembersPendingProfileKey(List.of(new GroupChange.Actions.PromoteMemberPendingProfileKeyAction.Builder().presentation(presentation(member1, profileKey1)).build()))
.build();
assertEquals(expected, resolvedActions);
@@ -439,7 +439,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.modifyDisappearingMessagesTimer(new GroupChange.Actions.ModifyDisappearingMessagesTimerAction.Builder().timer(ByteString.EMPTY).build())
.modifyDisappearingMessageTimer(new GroupChange.Actions.ModifyDisappearingMessageTimerAction.Builder().timer(ByteString.EMPTY).build())
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
@@ -458,7 +458,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.modifyDisappearingMessagesTimer(new GroupChange.Actions.ModifyDisappearingMessagesTimerAction.Builder().timer(ByteString.EMPTY).build())
.modifyDisappearingMessageTimer(new GroupChange.Actions.ModifyDisappearingMessageTimerAction.Builder().timer(ByteString.EMPTY).build())
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
@@ -567,15 +567,15 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.addRequestingMembers(List.of(new GroupChange.Actions.AddRequestingMemberAction.Builder().added(encryptedRequestingMember(member1, randomProfileKey())).build(),
new GroupChange.Actions.AddRequestingMemberAction.Builder().added(encryptedRequestingMember(member2, profileKey2)).build(),
new GroupChange.Actions.AddRequestingMemberAction.Builder().added(encryptedRequestingMember(member3, randomProfileKey())).build()))
.addMembersPendingAdminApproval(List.of(new GroupChange.Actions.AddMemberPendingAdminApprovalAction.Builder().added(encryptedRequestingMember(member1, randomProfileKey())).build(),
new GroupChange.Actions.AddMemberPendingAdminApprovalAction.Builder().added(encryptedRequestingMember(member2, profileKey2)).build(),
new GroupChange.Actions.AddMemberPendingAdminApprovalAction.Builder().added(encryptedRequestingMember(member3, randomProfileKey())).build()))
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
GroupChange.Actions expected = new GroupChange.Actions.Builder()
.addRequestingMembers(List.of(new GroupChange.Actions.AddRequestingMemberAction.Builder().added(encryptedRequestingMember(member2, profileKey2)).build()))
.addMembersPendingAdminApproval(List.of(new GroupChange.Actions.AddMemberPendingAdminApprovalAction.Builder().added(encryptedRequestingMember(member2, profileKey2)).build()))
.build();
assertEquals(expected, resolvedActions);
@@ -599,17 +599,17 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.addRequestingMembers(List.of(new GroupChange.Actions.AddRequestingMemberAction.Builder().added(encryptedRequestingMember(member1, profileKey1)).build(),
new GroupChange.Actions.AddRequestingMemberAction.Builder().added(encryptedRequestingMember(member2, profileKey2)).build(),
new GroupChange.Actions.AddRequestingMemberAction.Builder().added(encryptedRequestingMember(member3, profileKey3)).build()))
.addMembersPendingAdminApproval(List.of(new GroupChange.Actions.AddMemberPendingAdminApprovalAction.Builder().added(encryptedRequestingMember(member1, profileKey1)).build(),
new GroupChange.Actions.AddMemberPendingAdminApprovalAction.Builder().added(encryptedRequestingMember(member2, profileKey2)).build(),
new GroupChange.Actions.AddMemberPendingAdminApprovalAction.Builder().added(encryptedRequestingMember(member3, profileKey3)).build()))
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
GroupChange.Actions expected = new GroupChange.Actions.Builder()
.promotePendingMembers(List.of(new GroupChange.Actions.PromotePendingMemberAction.Builder().presentation(presentation(member3, profileKey3)).build(),
new GroupChange.Actions.PromotePendingMemberAction.Builder().presentation(presentation(member1, profileKey1)).build()))
.addRequestingMembers(List.of(new GroupChange.Actions.AddRequestingMemberAction.Builder().added(encryptedRequestingMember(member2, profileKey2)).build()))
.promoteMembersPendingProfileKey(List.of(new GroupChange.Actions.PromoteMemberPendingProfileKeyAction.Builder().presentation(presentation(member3, profileKey3)).build(),
new GroupChange.Actions.PromoteMemberPendingProfileKeyAction.Builder().presentation(presentation(member1, profileKey1)).build()))
.addMembersPendingAdminApproval(List.of(new GroupChange.Actions.AddMemberPendingAdminApprovalAction.Builder().added(encryptedRequestingMember(member2, profileKey2)).build()))
.build();
assertEquals(expected, resolvedActions);
@@ -630,15 +630,15 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.deleteRequestingMembers(List.of(new GroupChange.Actions.DeleteRequestingMemberAction.Builder().deletedUserId(encrypt(member1)).build(),
new GroupChange.Actions.DeleteRequestingMemberAction.Builder().deletedUserId(encrypt(member2)).build(),
new GroupChange.Actions.DeleteRequestingMemberAction.Builder().deletedUserId(encrypt(member3)).build()))
.deleteMembersPendingAdminApproval(List.of(new GroupChange.Actions.DeleteMemberPendingAdminApprovalAction.Builder().deletedUserId(encrypt(member1)).build(),
new GroupChange.Actions.DeleteMemberPendingAdminApprovalAction.Builder().deletedUserId(encrypt(member2)).build(),
new GroupChange.Actions.DeleteMemberPendingAdminApprovalAction.Builder().deletedUserId(encrypt(member3)).build()))
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
GroupChange.Actions expected = new GroupChange.Actions.Builder()
.deleteRequestingMembers(List.of(new GroupChange.Actions.DeleteRequestingMemberAction.Builder().deletedUserId(encrypt(member2)).build()))
.deleteMembersPendingAdminApproval(List.of(new GroupChange.Actions.DeleteMemberPendingAdminApprovalAction.Builder().deletedUserId(encrypt(member2)).build()))
.build();
assertEquals(expected, resolvedActions);
@@ -660,15 +660,15 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.promoteRequestingMembers(List.of(new GroupChange.Actions.PromoteRequestingMemberAction.Builder().role(Member.Role.DEFAULT).userId(UuidUtil.toByteString(member1)).build(),
new GroupChange.Actions.PromoteRequestingMemberAction.Builder().role(Member.Role.DEFAULT).userId(UuidUtil.toByteString(member2)).build(),
new GroupChange.Actions.PromoteRequestingMemberAction.Builder().role(Member.Role.DEFAULT).userId(UuidUtil.toByteString(member3)).build()))
.promoteMembersPendingAdminApproval(List.of(new GroupChange.Actions.PromoteMemberPendingAdminApprovalAction.Builder().role(Member.Role.DEFAULT).userId(UuidUtil.toByteString(member1)).build(),
new GroupChange.Actions.PromoteMemberPendingAdminApprovalAction.Builder().role(Member.Role.DEFAULT).userId(UuidUtil.toByteString(member2)).build(),
new GroupChange.Actions.PromoteMemberPendingAdminApprovalAction.Builder().role(Member.Role.DEFAULT).userId(UuidUtil.toByteString(member3)).build()))
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
GroupChange.Actions expected = new GroupChange.Actions.Builder()
.promoteRequestingMembers(List.of(new GroupChange.Actions.PromoteRequestingMemberAction.Builder().role(Member.Role.DEFAULT).userId(UuidUtil.toByteString(member2)).build()))
.promoteMembersPendingAdminApproval(List.of(new GroupChange.Actions.PromoteMemberPendingAdminApprovalAction.Builder().role(Member.Role.DEFAULT).userId(UuidUtil.toByteString(member2)).build()))
.build();
assertEquals(expected, resolvedActions);
@@ -741,7 +741,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
.newIsAnnouncementGroup(EnabledState.ENABLED)
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.modifyAnnouncementsOnly(new GroupChange.Actions.ModifyAnnouncementsOnlyAction.Builder().announcementsOnly(true).build())
.modify_announcements_only(new GroupChange.Actions.ModifyAnnouncementsOnlyAction.Builder().announcements_only(true).build())
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
@@ -758,7 +758,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
.newIsAnnouncementGroup(EnabledState.ENABLED)
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.modifyAnnouncementsOnly(new GroupChange.Actions.ModifyAnnouncementsOnlyAction.Builder().announcementsOnly(true).build())
.modify_announcements_only(new GroupChange.Actions.ModifyAnnouncementsOnlyAction.Builder().announcements_only(true).build())
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
@@ -783,16 +783,16 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.addBannedMembers(List.of(new GroupChange.Actions.AddBannedMemberAction.Builder().added(new BannedMember.Builder().userId(encrypt(member1)).build()).build(),
new GroupChange.Actions.AddBannedMemberAction.Builder().added(new BannedMember.Builder().userId(encrypt(member2)).build()).build(),
new GroupChange.Actions.AddBannedMemberAction.Builder().added(new BannedMember.Builder().userId(encrypt(member3)).build()).build()))
.add_members_banned(List.of(new GroupChange.Actions.AddMemberBannedAction.Builder().added(new MemberBanned.Builder().userId(encrypt(member1)).build()).build(),
new GroupChange.Actions.AddMemberBannedAction.Builder().added(new MemberBanned.Builder().userId(encrypt(member2)).build()).build(),
new GroupChange.Actions.AddMemberBannedAction.Builder().added(new MemberBanned.Builder().userId(encrypt(member3)).build()).build()))
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
GroupChange.Actions expected = new GroupChange.Actions.Builder()
.addBannedMembers(List.of(new GroupChange.Actions.AddBannedMemberAction.Builder().added(new BannedMember.Builder().userId(encrypt(member1)).build()).build(),
new GroupChange.Actions.AddBannedMemberAction.Builder().added(new BannedMember.Builder().userId(encrypt(member2)).build()).build()))
.add_members_banned(List.of(new GroupChange.Actions.AddMemberBannedAction.Builder().added(new MemberBanned.Builder().userId(encrypt(member1)).build()).build(),
new GroupChange.Actions.AddMemberBannedAction.Builder().added(new MemberBanned.Builder().userId(encrypt(member2)).build()).build()))
.build();
assertEquals(expected, resolvedActions);
@@ -814,15 +814,15 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.deleteBannedMembers(List.of(new GroupChange.Actions.DeleteBannedMemberAction.Builder().deletedUserId(encrypt(member1)).build(),
new GroupChange.Actions.DeleteBannedMemberAction.Builder().deletedUserId(encrypt(member2)).build(),
new GroupChange.Actions.DeleteBannedMemberAction.Builder().deletedUserId(encrypt(member3)).build()))
.delete_members_banned(List.of(new GroupChange.Actions.DeleteMemberBannedAction.Builder().deletedUserId(encrypt(member1)).build(),
new GroupChange.Actions.DeleteMemberBannedAction.Builder().deletedUserId(encrypt(member2)).build(),
new GroupChange.Actions.DeleteMemberBannedAction.Builder().deletedUserId(encrypt(member3)).build()))
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
GroupChange.Actions expected = new GroupChange.Actions.Builder()
.deleteBannedMembers(List.of(new GroupChange.Actions.DeleteBannedMemberAction.Builder().deletedUserId(encrypt(member2)).build()))
.delete_members_banned(List.of(new GroupChange.Actions.DeleteMemberBannedAction.Builder().deletedUserId(encrypt(member2)).build()))
.build();
assertEquals(expected, resolvedActions);
@@ -843,14 +843,14 @@ public final class GroupChangeUtil_resolveConflict_Test {
.build();
GroupChange.Actions change = new GroupChange.Actions.Builder()
.promotePendingPniAciMembers(List.of(new GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction.Builder().presentation(presentation(member1.pniBytes, member1.profileKey)).build(),
new GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction.Builder().presentation(presentation(member2.pniBytes, member2.profileKey)).build()))
.promote_members_pending_pni_aci_profile_key(List.of(new GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyAction.Builder().presentation(presentation(member1.pniBytes, member1.profileKey)).build(),
new GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyAction.Builder().presentation(presentation(member2.pniBytes, member2.profileKey)).build()))
.build();
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
GroupChange.Actions expected = new GroupChange.Actions.Builder()
.promotePendingPniAciMembers(List.of(new GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction.Builder().presentation(presentation(member2.pniBytes, member2.profileKey)).build()))
.promote_members_pending_pni_aci_profile_key(List.of(new GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyAction.Builder().presentation(presentation(member2.pniBytes, member2.profileKey)).build()))
.build();
assertEquals(expected, resolvedActions);
}

View File

@@ -2,13 +2,13 @@ package org.whispersystems.signalservice.api.groupsv2;
import org.junit.Test;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.signal.storageservice.protos.groups.AccessControl;
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.DecryptedString;
import org.signal.storageservice.protos.groups.local.DecryptedTimer;
import org.signal.storageservice.protos.groups.local.EnabledState;
import org.signal.storageservice.storage.protos.groups.AccessControl;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
import org.signal.core.util.UuidUtil;
import org.whispersystems.signalservice.internal.util.Util;

View File

@@ -42,7 +42,7 @@ class GroupsV2Operations_ban_Test {
emptyList()
)
assertThat(banUuidsChange.addBannedMembers)
assertThat(banUuidsChange.add_members_banned)
.single()
.transform { it.added?.userId }
.isEqualTo(groupOperations.encryptServiceId(ban))
@@ -62,7 +62,7 @@ class GroupsV2Operations_ban_Test {
alreadyBanned
)
assertThat(banUuidsChange.addBannedMembers)
assertThat(banUuidsChange.add_members_banned)
.single()
.transform { it.added?.userId }
.isEqualTo(groupOperations.encryptServiceId(toBan))
@@ -89,12 +89,12 @@ class GroupsV2Operations_ban_Test {
)
val oldest = alreadyBanned.minBy { it.timestamp }
assertThat(banUuidsChange.deleteBannedMembers)
assertThat(banUuidsChange.delete_members_banned)
.single()
.transform { it.deletedUserId }
.isEqualTo(groupOperations.encryptServiceId(ServiceId.parseOrThrow(oldest.serviceIdBytes)))
assertThat(banUuidsChange.addBannedMembers)
assertThat(banUuidsChange.add_members_banned)
.single()
.transform { it.added?.userId }
.isEqualTo(groupOperations.encryptServiceId(toBan))
@@ -125,7 +125,7 @@ class GroupsV2Operations_ban_Test {
.subList(0, 2)
.map { groupOperations.encryptServiceId(ServiceId.parseOrThrow(it.serviceIdBytes)) }
.toTypedArray()
assertThat(banUuidsChange.deleteBannedMembers)
assertThat(banUuidsChange.delete_members_banned)
.transform { members ->
members.map { member ->
member.deletedUserId
@@ -136,7 +136,7 @@ class GroupsV2Operations_ban_Test {
val newBans = (0..1).map { i ->
groupOperations.encryptServiceId(toBan[i])
}.toTypedArray()
assertThat(banUuidsChange.addBannedMembers)
assertThat(banUuidsChange.add_members_banned)
.transform { members ->
members.map { member ->
member.added?.userId

View File

@@ -16,20 +16,20 @@ import org.signal.libsignal.zkgroup.profiles.ProfileKeyCommitment;
import org.signal.libsignal.zkgroup.profiles.ProfileKeyCredentialPresentation;
import org.signal.libsignal.zkgroup.profiles.ProfileKeyCredentialRequest;
import org.signal.libsignal.zkgroup.profiles.ProfileKeyCredentialRequestContext;
import org.signal.storageservice.protos.groups.AccessControl;
import org.signal.storageservice.protos.groups.GroupChange;
import org.signal.storageservice.protos.groups.Member;
import org.signal.storageservice.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.protos.groups.local.DecryptedBannedMember;
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.storageservice.protos.groups.local.EnabledState;
import org.signal.storageservice.storage.protos.groups.AccessControl;
import org.signal.storageservice.storage.protos.groups.GroupChange;
import org.signal.storageservice.storage.protos.groups.Member;
import org.signal.storageservice.storage.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberRole;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMemberRemoval;
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
import org.signal.core.models.ServiceId.ACI;
import org.signal.core.models.ServiceId.PNI;
import org.signal.core.util.UuidUtil;
@@ -90,7 +90,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
@Test
public void can_pass_revision_through_encrypt_and_decrypt_methods() {
assertDecryption(new GroupChange.Actions.Builder()
.revision(1),
.version(1),
new DecryptedGroupChange.Builder()
.revision(1));
}
@@ -103,7 +103,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
GroupCandidate groupCandidate = groupCandidate(newMember, profileKey);
assertDecryption(groupOperations.createModifyGroupMembershipChange(Collections.singleton(groupCandidate), Collections.emptySet(), self)
.revision(10),
.version(10),
new DecryptedGroupChange.Builder()
.revision(10)
.newMembers(List.of(new DecryptedMember.Builder()
@@ -121,7 +121,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
GroupCandidate groupCandidate = groupCandidate(newMember, profileKey);
assertDecryption(groupOperations.createGroupJoinDirect(groupCandidate.getExpiringProfileKeyCredential().get())
.revision(10),
.version(10),
new DecryptedGroupChange.Builder()
.revision(10)
.newMembers(List.of(new DecryptedMember.Builder()
@@ -140,7 +140,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
GroupCandidate groupCandidate = groupCandidate(newMember, profileKey);
assertDecryption(groupOperations.createModifyGroupMembershipChange(Collections.singleton(groupCandidate), Collections.emptySet(), self)
.revision(10),
.version(10),
new DecryptedGroupChange.Builder()
.revision(10)
.newMembers(List.of(new DecryptedMember.Builder()
@@ -167,7 +167,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
ACI oldMember = ACI.from(UUID.randomUUID());
assertDecryption(groupOperations.createRemoveMembersChange(Collections.singleton(oldMember), false, Collections.emptyList())
.revision(10),
.version(10),
new DecryptedGroupChange.Builder()
.revision(10)
.deleteMembers(List.of(oldMember.toByteString())));
@@ -213,7 +213,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
GroupCandidate groupCandidate = groupCandidate(self, profileKey);
assertDecryption(groupOperations.createUpdateProfileKeyCredentialChange(groupCandidate.getExpiringProfileKeyCredential().get())
.revision(10),
.version(10),
new DecryptedGroupChange.Builder()
.revision(10)
.modifiedProfileKeys(List.of(new DecryptedMember.Builder()
@@ -231,7 +231,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
GroupCandidate groupCandidate = new GroupCandidate(newMember, Optional.empty());
assertDecryption(groupOperations.createModifyGroupMembershipChange(Collections.singleton(groupCandidate), Collections.emptySet(), self)
.revision(13),
.version(13),
new DecryptedGroupChange.Builder()
.revision(13)
.newPendingMembers(List.of(new DecryptedPendingMember.Builder()
@@ -260,7 +260,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
byte[] uuidCiphertext = Util.getSecretBytes(60);
assertDecryption(new GroupChange.Actions.Builder()
.deletePendingMembers(List.of(new GroupChange.Actions.DeletePendingMemberAction.Builder()
.deleteMembersPendingProfileKey(List.of(new GroupChange.Actions.DeleteMemberPendingProfileKeyAction.Builder()
.deletedUserId(ByteString.of(uuidCiphertext)).build())),
new DecryptedGroupChange.Builder()
.deletePendingMembers(List.of(new DecryptedPendingMemberRemoval.Builder()
@@ -342,7 +342,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
GroupCandidate groupCandidate = groupCandidate(newRequestingMember, profileKey);
assertDecryption(groupOperations.createGroupJoinRequest(groupCandidate.getExpiringProfileKeyCredential().get())
.revision(10),
.version(10),
new DecryptedGroupChange.Builder()
.revision(10)
.newRequestingMembers(List.of(new DecryptedRequestingMember.Builder()
@@ -356,7 +356,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
ACI newRequestingMember = ACI.from(UUID.randomUUID());
assertDecryption(groupOperations.createRefuseGroupJoinRequest(Collections.singleton(newRequestingMember), true, Collections.emptyList())
.revision(10),
.version(10),
new DecryptedGroupChange.Builder()
.revision(10)
.deleteRequestingMembers(List.of(newRequestingMember.toByteString()))
@@ -368,7 +368,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
UUID newRequestingMember = UUID.randomUUID();
assertDecryption(groupOperations.createApproveGroupJoinRequest(Collections.singleton(newRequestingMember))
.revision(15),
.version(15),
new DecryptedGroupChange.Builder()
.revision(15)
.promoteRequestingMembers(List.of(new DecryptedApproveMember.Builder()
@@ -399,8 +399,8 @@ public final class GroupsV2Operations_decrypt_change_Test {
@Test
public void can_pass_through_new_announcment_only_field21() {
assertDecryption(new GroupChange.Actions.Builder()
.modifyAnnouncementsOnly(new GroupChange.Actions.ModifyAnnouncementsOnlyAction.Builder()
.announcementsOnly(true)
.modify_announcements_only(new GroupChange.Actions.ModifyAnnouncementsOnlyAction.Builder()
.announcements_only(true)
.build()),
new DecryptedGroupChange.Builder()
.newIsAnnouncementGroup(EnabledState.ENABLED));
@@ -411,7 +411,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
ACI ban = ACI.from(UUID.randomUUID());
assertDecryption(groupOperations.createBanServiceIdsChange(Collections.singleton(ban), false, Collections.emptyList())
.revision(13),
.version(13),
new DecryptedGroupChange.Builder()
.revision(13)
.newBannedMembers(List.of(new DecryptedBannedMember.Builder()
@@ -424,7 +424,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
ACI ban = ACI.from(UUID.randomUUID());
assertDecryption(groupOperations.createUnbanServiceIdsChange(Collections.singleton(ban))
.revision(13),
.version(13),
new DecryptedGroupChange.Builder()
.revision(13)
.deleteBannedMembers(List.of(new DecryptedBannedMember.Builder()
@@ -438,12 +438,12 @@ public final class GroupsV2Operations_decrypt_change_Test {
ProfileKey profileKey = newProfileKey();
GroupChange.Actions.Builder builder = new GroupChange.Actions.Builder()
.sourceServiceId(groupOperations.encryptServiceId(memberPni))
.revision(5)
.promotePendingPniAciMembers(List.of(new GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction.Builder()
.userId(groupOperations.encryptServiceId(memberAci))
.sourceUserId(groupOperations.encryptServiceId(memberPni))
.version(5)
.promote_members_pending_pni_aci_profile_key(List.of(new GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyAction.Builder()
.user_id(groupOperations.encryptServiceId(memberAci))
.pni(groupOperations.encryptServiceId(memberPni))
.profileKey(encryptProfileKey(memberAci, profileKey))
.profile_key(encryptProfileKey(memberAci, profileKey))
.build()));
assertDecryptionWithEditorSet(builder,
@@ -498,7 +498,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
DecryptedGroupChange.Builder expectedDecrypted)
{
ACI editor = ACI.from(UUID.randomUUID());
assertDecryptionWithEditorSet(inputChange.sourceServiceId(groupOperations.encryptServiceId(editor)), expectedDecrypted.editorServiceIdBytes(editor.toByteString()));
assertDecryptionWithEditorSet(inputChange.sourceUserId(groupOperations.encryptServiceId(editor)), expectedDecrypted.editorServiceIdBytes(editor.toByteString()));
}
void assertDecryptionWithEditorSet(GroupChange.Actions.Builder inputChange,

View File

@@ -5,9 +5,9 @@ import org.junit.Test;
import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
import org.signal.libsignal.zkgroup.groups.GroupSecretParams;
import org.signal.storageservice.protos.groups.AccessControl;
import org.signal.storageservice.protos.groups.GroupJoinInfo;
import org.signal.storageservice.protos.groups.local.DecryptedGroupJoinInfo;
import org.signal.storageservice.storage.protos.groups.AccessControl;
import org.signal.storageservice.storage.protos.groups.GroupJoinInfo;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupJoinInfo;
import org.whispersystems.signalservice.internal.util.Util;
import org.whispersystems.signalservice.testutil.LibSignalLibraryUtil;
@@ -102,7 +102,7 @@ public final class GroupsV2Operations_decrypt_groupJoinInfo_Test {
@Test
public void revision_passed_though_6() {
GroupJoinInfo groupJoinInfo = new GroupJoinInfo.Builder()
.revision(11)
.version(11)
.build();
DecryptedGroupJoinInfo decryptedGroupJoinInfo = groupOperations.decryptGroupJoinInfo(groupJoinInfo);

View File

@@ -8,18 +8,18 @@ import org.signal.libsignal.zkgroup.groups.ClientZkGroupCipher;
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
import org.signal.libsignal.zkgroup.groups.GroupSecretParams;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.signal.storageservice.protos.groups.AccessControl;
import org.signal.storageservice.protos.groups.BannedMember;
import org.signal.storageservice.protos.groups.Group;
import org.signal.storageservice.protos.groups.Member;
import org.signal.storageservice.protos.groups.PendingMember;
import org.signal.storageservice.protos.groups.RequestingMember;
import org.signal.storageservice.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.protos.groups.local.DecryptedMember;
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.protos.groups.local.DecryptedRequestingMember;
import org.signal.storageservice.protos.groups.local.EnabledState;
import org.signal.storageservice.storage.protos.groups.AccessControl;
import org.signal.storageservice.storage.protos.groups.MemberBanned;
import org.signal.storageservice.storage.protos.groups.Group;
import org.signal.storageservice.storage.protos.groups.Member;
import org.signal.storageservice.storage.protos.groups.MemberPendingProfileKey;
import org.signal.storageservice.storage.protos.groups.MemberPendingAdminApproval;
import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember;
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
import org.signal.core.models.ServiceId.ACI;
import org.whispersystems.signalservice.internal.util.Util;
import org.whispersystems.signalservice.testutil.LibSignalLibraryUtil;
@@ -75,7 +75,7 @@ public final class GroupsV2Operations_decrypt_group_Test {
@Test
public void avatar_field_passed_through_3() throws VerificationFailedException, InvalidGroupStateException {
Group group = new Group.Builder()
.avatar("AvatarCdnKey")
.avatarUrl("AvatarCdnKey")
.build();
DecryptedGroup decryptedGroup = groupOperations.decryptGroup(group);
@@ -113,7 +113,7 @@ public final class GroupsV2Operations_decrypt_group_Test {
@Test
public void set_revision_field_6() throws VerificationFailedException, InvalidGroupStateException {
Group group = new Group.Builder()
.revision(99)
.version(99)
.build();
DecryptedGroup decryptedGroup = groupOperations.decryptGroup(group);
@@ -132,13 +132,13 @@ public final class GroupsV2Operations_decrypt_group_Test {
.members(List.of(new Member.Builder()
.role(Member.Role.ADMINISTRATOR)
.userId(groupOperations.encryptServiceId(admin1))
.joinedAtRevision(4)
.joinedAtVersion(4)
.profileKey(encryptProfileKey(admin1, adminProfileKey))
.build(),
new Member.Builder()
.role(Member.Role.DEFAULT)
.userId(groupOperations.encryptServiceId(member1))
.joinedAtRevision(7)
.joinedAtVersion(7)
.profileKey(encryptProfileKey(member1, memberProfileKey))
.build()))
.build();
@@ -171,7 +171,7 @@ public final class GroupsV2Operations_decrypt_group_Test {
ACI inviter2 = ACI.from(UUID.randomUUID());
Group group = new Group.Builder()
.pendingMembers(List.of(new PendingMember.Builder()
.membersPendingProfileKey(List.of(new MemberPendingProfileKey.Builder()
.addedByUserId(groupOperations.encryptServiceId(inviter1))
.timestamp(100)
.member(new Member.Builder()
@@ -179,7 +179,7 @@ public final class GroupsV2Operations_decrypt_group_Test {
.userId(groupOperations.encryptServiceId(admin1))
.build())
.build(),
new PendingMember.Builder()
new MemberPendingProfileKey.Builder()
.addedByUserId(groupOperations.encryptServiceId(inviter1))
.timestamp(200)
.member(new Member.Builder()
@@ -187,7 +187,7 @@ public final class GroupsV2Operations_decrypt_group_Test {
.userId(groupOperations.encryptServiceId(member1))
.build())
.build(),
new PendingMember.Builder()
new MemberPendingProfileKey.Builder()
.addedByUserId(groupOperations.encryptServiceId(inviter2))
.timestamp(1500)
.member(new Member.Builder()
@@ -232,12 +232,12 @@ public final class GroupsV2Operations_decrypt_group_Test {
ProfileKey memberProfileKey = newProfileKey();
Group group = new Group.Builder()
.requestingMembers(List.of(new RequestingMember.Builder()
.membersPendingAdminApproval(List.of(new MemberPendingAdminApproval.Builder()
.userId(groupOperations.encryptServiceId(admin1))
.profileKey(encryptProfileKey(admin1, adminProfileKey))
.timestamp(5000)
.build(),
new RequestingMember.Builder()
new MemberPendingAdminApproval.Builder()
.userId(groupOperations.encryptServiceId(member1))
.profileKey(encryptProfileKey(member1, memberProfileKey))
.timestamp(15000)
@@ -288,7 +288,7 @@ public final class GroupsV2Operations_decrypt_group_Test {
@Test
public void decrypt_announcements_field_12() throws VerificationFailedException, InvalidGroupStateException {
Group group = new Group.Builder()
.announcementsOnly(true)
.announcements_only(true)
.build();
DecryptedGroup decryptedGroup = groupOperations.decryptGroup(group);
@@ -301,7 +301,7 @@ public final class GroupsV2Operations_decrypt_group_Test {
ACI member1 = ACI.from(UUID.randomUUID());
Group group = new Group.Builder()
.bannedMembers(List.of(new BannedMember.Builder().userId(groupOperations.encryptServiceId(member1)).build()))
.members_banned(List.of(new MemberBanned.Builder().userId(groupOperations.encryptServiceId(member1)).build()))
.build();
DecryptedGroup decryptedGroup = groupOperations.decryptGroup(group);

View File

@@ -2,15 +2,15 @@ package org.whispersystems.signalservice.api.groupsv2;
import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.signal.storageservice.protos.groups.Member;
import org.signal.storageservice.protos.groups.RequestingMember;
import org.signal.storageservice.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.protos.groups.local.DecryptedBannedMember;
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.storage.protos.groups.Member;
import org.signal.storageservice.storage.protos.groups.MemberPendingAdminApproval;
import org.signal.storageservice.storage.protos.groups.local.DecryptedApproveMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberRole;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMemberRemoval;
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember;
import org.signal.core.util.UuidUtil;
import org.whispersystems.signalservice.internal.util.Util;
@@ -88,8 +88,8 @@ final class ProtoTestUtils {
.build();
}
static RequestingMember encryptedRequestingMember(UUID uuid, ProfileKey profileKey) {
return new RequestingMember.Builder()
static MemberPendingAdminApproval encryptedRequestingMember(UUID uuid, ProfileKey profileKey) {
return new MemberPendingAdminApproval.Builder()
.presentation(presentation(uuid, profileKey))
.build();
}