mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 17:29:32 +01:00
Strongly type UUIDs as ACIs.
This commit is contained in:
@@ -60,6 +60,7 @@ import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||
import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException;
|
||||
import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ConflictException;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
@@ -92,7 +93,7 @@ final class GroupManagerV2 {
|
||||
private final GroupsV2Operations groupsV2Operations;
|
||||
private final GroupsV2Authorization authorization;
|
||||
private final GroupsV2StateProcessor groupsV2StateProcessor;
|
||||
private final UUID selfUuid;
|
||||
private final ACI selfAci;
|
||||
private final GroupCandidateHelper groupCandidateHelper;
|
||||
|
||||
GroupManagerV2(@NonNull Context context) {
|
||||
@@ -102,7 +103,7 @@ final class GroupManagerV2 {
|
||||
this.groupsV2Operations = ApplicationDependencies.getGroupsV2Operations();
|
||||
this.authorization = ApplicationDependencies.getGroupsV2Authorization();
|
||||
this.groupsV2StateProcessor = ApplicationDependencies.getGroupsV2StateProcessor();
|
||||
this.selfUuid = Recipient.self().getUuid().get();
|
||||
this.selfAci = Recipient.self().requireAci();
|
||||
this.groupCandidateHelper = new GroupCandidateHelper(context);
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ final class GroupManagerV2 {
|
||||
|
||||
return groupsV2Api.getGroupJoinInfo(groupSecretParams,
|
||||
Optional.fromNullable(password).transform(GroupLinkPassword::serialize),
|
||||
authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@@ -127,7 +128,7 @@ final class GroupManagerV2 {
|
||||
|
||||
GroupSecretParams groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupMasterKey);
|
||||
|
||||
return groupsV2Api.getGroupExternalCredential(authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
return groupsV2Api.getGroupExternalCredential(authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@@ -140,7 +141,7 @@ final class GroupManagerV2 {
|
||||
|
||||
Map<UUID, UuidCiphertext> uuidCipherTexts = new HashMap<>();
|
||||
for (Recipient recipient : recipients) {
|
||||
uuidCipherTexts.put(recipient.requireUuid(), clientZkGroupCipher.encryptUuid(recipient.requireUuid()));
|
||||
uuidCipherTexts.put(recipient.requireAci().uuid(), clientZkGroupCipher.encryptUuid(recipient.requireAci().uuid()));
|
||||
}
|
||||
|
||||
return uuidCipherTexts;
|
||||
@@ -195,7 +196,7 @@ final class GroupManagerV2 {
|
||||
return latest;
|
||||
}
|
||||
|
||||
Optional<DecryptedMember> selfInFullMemberList = DecryptedGroupUtil.findMemberByUuid(latest.getMembersList(), Recipient.self().requireUuid());
|
||||
Optional<DecryptedMember> selfInFullMemberList = DecryptedGroupUtil.findMemberByUuid(latest.getMembersList(), selfAci.uuid());
|
||||
|
||||
if (!selfInFullMemberList.isPresent()) {
|
||||
return latest;
|
||||
@@ -267,7 +268,7 @@ final class GroupManagerV2 {
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(groupRecipient.getId(), true);
|
||||
|
||||
DecryptedGroupChange groupChange = DecryptedGroupChange.newBuilder(GroupChangeReconstruct.reconstructGroupChange(DecryptedGroup.newBuilder().build(), decryptedGroup))
|
||||
.setEditor(UuidUtil.toByteString(selfUuid))
|
||||
.setEditor(selfAci.toByteString())
|
||||
.build();
|
||||
|
||||
RecipientAndThread recipientAndThread = sendGroupUpdate(masterKey, new GroupMutation(null, groupChange, decryptedGroup), null);
|
||||
@@ -312,7 +313,7 @@ final class GroupManagerV2 {
|
||||
groupCandidates = GroupCandidate.withoutProfileKeyCredentials(groupCandidates);
|
||||
}
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createModifyGroupMembershipChange(groupCandidates, selfUuid));
|
||||
return commitChangeWithConflictResolution(groupOperations.createModifyGroupMembershipChange(groupCandidates, selfAci.uuid()));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@@ -356,7 +357,7 @@ final class GroupManagerV2 {
|
||||
}
|
||||
|
||||
if (avatarChanged) {
|
||||
String cdnKey = avatarBytes != null ? groupsV2Api.uploadAvatar(avatarBytes, groupSecretParams, authorization.getAuthorizationForToday(selfUuid, groupSecretParams))
|
||||
String cdnKey = avatarBytes != null ? groupsV2Api.uploadAvatar(avatarBytes, groupSecretParams, authorization.getAuthorizationForToday(selfAci, groupSecretParams))
|
||||
: "";
|
||||
change.setModifyAvatar(GroupChange.Actions.ModifyAvatarAction.newBuilder()
|
||||
.setAvatar(cdnKey));
|
||||
@@ -387,7 +388,7 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
Set<UUID> uuids = Stream.of(recipientIds)
|
||||
.map(r -> Recipient.resolved(r).getUuid().get())
|
||||
.map(r -> Recipient.resolved(r).requireAci().uuid())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createApproveGroupJoinRequest(uuids));
|
||||
@@ -398,7 +399,7 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
Set<UUID> uuids = Stream.of(recipientIds)
|
||||
.map(r -> Recipient.resolved(r).getUuid().get())
|
||||
.map(r -> Recipient.resolved(r).requireAci().uuid())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createRefuseGroupJoinRequest(uuids));
|
||||
@@ -410,7 +411,7 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
return commitChangeWithConflictResolution(groupOperations.createChangeMemberRole(recipient.getUuid().get(), admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT));
|
||||
return commitChangeWithConflictResolution(groupOperations.createChangeMemberRole(recipient.requireAci().uuid(), admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@@ -420,7 +421,7 @@ final class GroupManagerV2 {
|
||||
Recipient self = Recipient.self();
|
||||
GroupDatabase.GroupRecord groupRecord = groupDatabase.getGroup(groupId).get();
|
||||
List<DecryptedPendingMember> pendingMembersList = groupRecord.requireV2GroupProperties().getDecryptedGroup().getPendingMembersList();
|
||||
Optional<DecryptedPendingMember> selfPendingMember = DecryptedGroupUtil.findPendingByUuid(pendingMembersList, selfUuid);
|
||||
Optional<DecryptedPendingMember> selfPendingMember = DecryptedGroupUtil.findPendingByUuid(pendingMembersList, selfAci.uuid());
|
||||
|
||||
if (selfPendingMember.isPresent()) {
|
||||
try {
|
||||
@@ -439,7 +440,7 @@ final class GroupManagerV2 {
|
||||
{
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createRemoveMembersChange(Collections.singleton(recipient.getUuid().get())));
|
||||
return commitChangeWithConflictResolution(groupOperations.createRemoveMembersChange(Collections.singleton(recipient.requireAci().uuid())));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@@ -447,9 +448,9 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, GroupNotAMemberException, GroupInsufficientRightsException, IOException
|
||||
{
|
||||
Recipient self = Recipient.self();
|
||||
List<UUID> newAdminRecipients = Stream.of(newAdmins).map(id -> Recipient.resolved(id).getUuid().get()).toList();
|
||||
List<UUID> newAdminRecipients = Stream.of(newAdmins).map(id -> Recipient.resolved(id).requireAci().uuid()).toList();
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createLeaveAndPromoteMembersToAdmin(self.getUuid().get(),
|
||||
return commitChangeWithConflictResolution(groupOperations.createLeaveAndPromoteMembersToAdmin(selfAci.uuid(),
|
||||
newAdminRecipients));
|
||||
}
|
||||
|
||||
@@ -459,7 +460,7 @@ final class GroupManagerV2 {
|
||||
{
|
||||
ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey();
|
||||
DecryptedGroup group = groupDatabase.requireGroup(groupId).requireV2GroupProperties().getDecryptedGroup();
|
||||
Optional<DecryptedMember> selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), selfUuid);
|
||||
Optional<DecryptedMember> selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), selfAci.uuid());
|
||||
|
||||
if (!selfInGroup.isPresent()) {
|
||||
Log.w(TAG, "Self not in group " + groupId);
|
||||
@@ -489,7 +490,7 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
DecryptedGroup group = groupDatabase.requireGroup(groupId).requireV2GroupProperties().getDecryptedGroup();
|
||||
Optional<DecryptedMember> selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), Recipient.self().getUuid().get());
|
||||
Optional<DecryptedMember> selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), selfAci.uuid());
|
||||
|
||||
if (selfInGroup.isPresent()) {
|
||||
Log.w(TAG, "Self already in group");
|
||||
@@ -553,7 +554,7 @@ final class GroupManagerV2 {
|
||||
private @NonNull GroupManager.GroupActionResult commitChangeWithConflictResolution(@NonNull GroupChange.Actions.Builder change)
|
||||
throws GroupChangeFailedException, GroupNotAMemberException, GroupInsufficientRightsException, IOException
|
||||
{
|
||||
change.setSourceUuid(UuidUtil.toByteString(Recipient.self().getUuid().get()));
|
||||
change.setSourceUuid(UuidUtil.toByteString(selfAci.uuid()));
|
||||
|
||||
for (int attempt = 0; attempt < 5; attempt++) {
|
||||
try {
|
||||
@@ -602,7 +603,7 @@ final class GroupManagerV2 {
|
||||
GroupChange.Actions changeActions = change.build();
|
||||
|
||||
return GroupChangeUtil.resolveConflict(groupUpdateResult.getLatestServer(),
|
||||
groupOperations.decryptChange(changeActions, selfUuid),
|
||||
groupOperations.decryptChange(changeActions, selfAci.uuid()),
|
||||
changeActions);
|
||||
} catch (VerificationFailedException | InvalidGroupStateException ex) {
|
||||
throw new GroupChangeFailedException(ex);
|
||||
@@ -622,7 +623,7 @@ final class GroupManagerV2 {
|
||||
|
||||
try {
|
||||
previousGroupState = v2GroupProperties.getDecryptedGroup();
|
||||
decryptedChange = groupOperations.decryptChange(changeActions, selfUuid);
|
||||
decryptedChange = groupOperations.decryptChange(changeActions, selfAci.uuid());
|
||||
decryptedGroupState = DecryptedGroupUtil.apply(previousGroupState, decryptedChange);
|
||||
} catch (VerificationFailedException | InvalidGroupStateException | NotAbleToApplyGroupV2ChangeException e) {
|
||||
Log.w(TAG, e);
|
||||
@@ -644,7 +645,7 @@ final class GroupManagerV2 {
|
||||
throws GroupNotAMemberException, GroupChangeFailedException, IOException, GroupInsufficientRightsException
|
||||
{
|
||||
try {
|
||||
return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfUuid, groupSecretParams), Optional.absent());
|
||||
return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfAci, groupSecretParams), Optional.absent());
|
||||
} catch (NotInGroupException e) {
|
||||
Log.w(TAG, e);
|
||||
throw new GroupNotAMemberException(e);
|
||||
@@ -727,9 +728,9 @@ final class GroupManagerV2 {
|
||||
disappearingMessageTimerSeconds);
|
||||
|
||||
try {
|
||||
groupsV2Api.putNewGroup(newGroup, authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
groupsV2Api.putNewGroup(newGroup, authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
|
||||
DecryptedGroup decryptedGroup = groupsV2Api.getGroup(groupSecretParams, ApplicationDependencies.getGroupsV2Authorization().getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
DecryptedGroup decryptedGroup = groupsV2Api.getGroup(groupSecretParams, ApplicationDependencies.getGroupsV2Authorization().getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
if (decryptedGroup == null) {
|
||||
throw new GroupChangeFailedException();
|
||||
}
|
||||
@@ -922,7 +923,7 @@ final class GroupManagerV2 {
|
||||
.setRevision(GroupsV2StateProcessor.PLACEHOLDER_REVISION);
|
||||
|
||||
Recipient self = Recipient.self();
|
||||
ByteString selfUuid = UuidUtil.toByteString(self.requireUuid());
|
||||
ByteString selfUuid = selfAci.toByteString();
|
||||
ByteString profileKey = ByteString.copyFrom(Objects.requireNonNull(self.getProfileKey()));
|
||||
|
||||
if (requestToJoin) {
|
||||
@@ -956,7 +957,7 @@ final class GroupManagerV2 {
|
||||
GroupChange.Actions.Builder change = requestToJoin ? groupOperations.createGroupJoinRequest(profileKeyCredential)
|
||||
: groupOperations.createGroupJoinDirect(profileKeyCredential);
|
||||
|
||||
change.setSourceUuid(UuidUtil.toByteString(Recipient.self().getUuid().get()));
|
||||
change.setSourceUuid(selfAci.toByteString());
|
||||
|
||||
return commitJoinChangeWithConflictResolution(currentRevision, change);
|
||||
}
|
||||
@@ -1000,7 +1001,7 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, IOException, GroupLinkNotActiveException
|
||||
{
|
||||
try {
|
||||
return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfUuid, groupSecretParams), Optional.fromNullable(password).transform(GroupLinkPassword::serialize));
|
||||
return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfAci, groupSecretParams), Optional.fromNullable(password).transform(GroupLinkPassword::serialize));
|
||||
} catch (NotInGroupException | VerificationFailedException e) {
|
||||
Log.w(TAG, e);
|
||||
throw new GroupChangeFailedException(e);
|
||||
@@ -1044,7 +1045,7 @@ final class GroupManagerV2 {
|
||||
throws IOException, VerificationFailedException, InvalidGroupStateException
|
||||
{
|
||||
try {
|
||||
groupsV2Api.getGroup(groupSecretParams, authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
groupsV2Api.getGroup(groupSecretParams, authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
return true;
|
||||
} catch (NotInGroupException ex) {
|
||||
return false;
|
||||
@@ -1055,7 +1056,7 @@ final class GroupManagerV2 {
|
||||
void cancelJoinRequest()
|
||||
throws GroupChangeFailedException, IOException
|
||||
{
|
||||
Set<UUID> uuids = Collections.singleton(Recipient.self().getUuid().get());
|
||||
Set<UUID> uuids = Collections.singleton(selfAci.uuid());
|
||||
|
||||
GroupChange signedGroupChange;
|
||||
try {
|
||||
@@ -1158,7 +1159,7 @@ final class GroupManagerV2 {
|
||||
|
||||
private static @NonNull List<RecipientId> getPendingMemberRecipientIds(@NonNull List<DecryptedPendingMember> newPendingMembersList) {
|
||||
return Stream.of(DecryptedGroupUtil.pendingToUuidList(newPendingMembersList))
|
||||
.map(uuid-> RecipientId.from(uuid,null))
|
||||
.map(uuid -> RecipientId.from(ACI.from(uuid), null))
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
|
||||
@@ -85,27 +86,26 @@ public final class GroupProtoUtil {
|
||||
|
||||
@WorkerThread
|
||||
public static Recipient uuidByteStringToRecipient(@NonNull Context context, @NonNull ByteString uuidByteString) {
|
||||
UUID uuid = UUIDUtil.deserialize(uuidByteString.toByteArray());
|
||||
ACI aci = ACI.fromByteString(uuidByteString);
|
||||
|
||||
if (uuid.equals(GroupsV2Operations.UNKNOWN_UUID)) {
|
||||
if (aci.isUnknown()) {
|
||||
return Recipient.UNKNOWN;
|
||||
}
|
||||
|
||||
return Recipient.externalPush(context, uuid, null, false);
|
||||
return Recipient.externalPush(context, aci, null, false);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static @NonNull RecipientId uuidByteStringToRecipientId(@NonNull ByteString uuidByteString) {
|
||||
UUID uuid = UUIDUtil.deserialize(uuidByteString.toByteArray());
|
||||
ACI aci = ACI.fromByteString(uuidByteString);
|
||||
|
||||
if (uuid.equals(GroupsV2Operations.UNKNOWN_UUID)) {
|
||||
if (aci.isUnknown()) {
|
||||
return RecipientId.UNKNOWN;
|
||||
}
|
||||
|
||||
return RecipientId.from(uuid, null);
|
||||
return RecipientId.from(aci, null);
|
||||
}
|
||||
|
||||
|
||||
public static boolean isMember(@NonNull UUID uuid, @NonNull List<DecryptedMember> membersList) {
|
||||
ByteString uuidBytes = UuidUtil.toByteString(uuid);
|
||||
|
||||
|
||||
@@ -232,10 +232,10 @@ public final class GroupsV1MigrationUtil {
|
||||
* True if the user meets all the requirements to be auto-migrated, otherwise false.
|
||||
*/
|
||||
public static boolean isAutoMigratable(@NonNull Recipient recipient) {
|
||||
return recipient.hasUuid() &&
|
||||
recipient.getGroupsV2Capability() == Recipient.Capability.SUPPORTED &&
|
||||
return recipient.hasAci() &&
|
||||
recipient.getGroupsV2Capability() == Recipient.Capability.SUPPORTED &&
|
||||
recipient.getGroupsV1MigrationCapability() == Recipient.Capability.SUPPORTED &&
|
||||
recipient.getRegistered() == RecipientDatabase.RegisteredState.REGISTERED &&
|
||||
recipient.getRegistered() == RecipientDatabase.RegisteredState.REGISTERED &&
|
||||
recipient.getProfileKey() != null;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.signal.zkgroup.groups.GroupSecretParams;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString;
|
||||
import org.whispersystems.signalservice.api.groupsv2.NoCredentialForRedemptionTimeException;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
@@ -27,7 +28,7 @@ public final class GroupsV2Authorization {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public GroupsV2AuthorizationString getAuthorizationForToday(@NonNull UUID self,
|
||||
public GroupsV2AuthorizationString getAuthorizationForToday(@NonNull ACI self,
|
||||
@NonNull GroupSecretParams groupSecretParams)
|
||||
throws IOException, VerificationFailedException
|
||||
{
|
||||
@@ -65,7 +66,7 @@ public final class GroupsV2Authorization {
|
||||
return (int) TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
private GroupsV2AuthorizationString getAuthorization(UUID self,
|
||||
private GroupsV2AuthorizationString getAuthorization(ACI self,
|
||||
GroupSecretParams groupSecretParams,
|
||||
Map<Integer, AuthCredentialResponse> credentials,
|
||||
int today)
|
||||
|
||||
@@ -86,7 +86,7 @@ public final class GroupsV2CapabilityChecker {
|
||||
}
|
||||
}
|
||||
|
||||
if (!member.hasUuid()) {
|
||||
if (!member.hasAci()) {
|
||||
noUuidCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -108,7 +109,7 @@ public final class LiveGroup {
|
||||
|
||||
return Stream.of(requestingMembersList)
|
||||
.map(requestingMember -> {
|
||||
Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), UuidUtil.fromByteString(requestingMember.getUuid()), null, false);
|
||||
Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), ACI.fromByteString(requestingMember.getUuid()), null, false);
|
||||
return new GroupMemberEntry.RequestingMember(recipient, selfAdmin);
|
||||
})
|
||||
.toList();
|
||||
|
||||
@@ -55,7 +55,7 @@ final class PendingMemberInvitesRepository {
|
||||
List<DecryptedPendingMember> pendingMembersList = decryptedGroup.getPendingMembersList();
|
||||
List<SinglePendingMemberInvitedByYou> byMe = new ArrayList<>(pendingMembersList.size());
|
||||
List<MultiplePendingMembersInvitedByAnother> byOthers = new ArrayList<>(pendingMembersList.size());
|
||||
ByteString self = ByteString.copyFrom(UUIDUtil.serialize(Recipient.self().getUuid().get()));
|
||||
ByteString self = Recipient.self().requireAci().toByteString();
|
||||
boolean selfIsAdmin = v2GroupProperties.isAdmin(Recipient.self());
|
||||
|
||||
Stream.of(pendingMembersList)
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
@@ -96,8 +95,8 @@ final class GroupsV1MigrationRepository {
|
||||
group = group.fresh();
|
||||
|
||||
List<Recipient> ineligible = Stream.of(group.getParticipants())
|
||||
.filter(r -> !r.hasUuid() ||
|
||||
r.getGroupsV2Capability() != Recipient.Capability.SUPPORTED ||
|
||||
.filter(r -> !r.hasAci() ||
|
||||
r.getGroupsV2Capability() != Recipient.Capability.SUPPORTED ||
|
||||
r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED ||
|
||||
r.getRegistered() != RecipientDatabase.RegisteredState.REGISTERED)
|
||||
.toList();
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupCandidate;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
@@ -47,13 +48,13 @@ public final class GroupCandidateHelper {
|
||||
{
|
||||
final Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
UUID uuid = recipient.getUuid().orNull();
|
||||
if (uuid == null) {
|
||||
ACI aci = recipient.getAci().orNull();
|
||||
if (aci == null) {
|
||||
throw new AssertionError("Non UUID members should have need detected by now");
|
||||
}
|
||||
|
||||
Optional<ProfileKeyCredential> profileKeyCredential = Optional.fromNullable(recipient.getProfileKeyCredential());
|
||||
GroupCandidate candidate = new GroupCandidate(uuid, profileKeyCredential);
|
||||
GroupCandidate candidate = new GroupCandidate(aci.uuid(), profileKeyCredential);
|
||||
|
||||
if (!candidate.hasProfileKeyCredential()) {
|
||||
ProfileKey profileKey = ProfileKeyUtil.profileKeyOrNull(recipient.getProfileKey());
|
||||
@@ -61,7 +62,7 @@ public final class GroupCandidateHelper {
|
||||
if (profileKey != null) {
|
||||
Log.i(TAG, String.format("No profile key credential on recipient %s, fetching", recipient.getId()));
|
||||
|
||||
Optional<ProfileKeyCredential> profileKeyCredentialOptional = signalServiceAccountManager.resolveProfileKeyCredential(uuid, profileKey, Locale.getDefault());
|
||||
Optional<ProfileKeyCredential> profileKeyCredentialOptional = signalServiceAccountManager.resolveProfileKeyCredential(aci, profileKey, Locale.getDefault());
|
||||
|
||||
if (profileKeyCredentialOptional.isPresent()) {
|
||||
boolean updatedProfileKey = recipientDatabase.setProfileKeyCredential(recipient.getId(), profileKey, profileKeyCredentialOptional.get());
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedRequestingMember;
|
||||
import org.signal.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.profiles.ProfileKey;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -30,8 +31,8 @@ public final class ProfileKeySet {
|
||||
|
||||
private static final String TAG = Log.tag(ProfileKeySet.class);
|
||||
|
||||
private final Map<UUID, ProfileKey> profileKeys = new LinkedHashMap<>();
|
||||
private final Map<UUID, ProfileKey> authoritativeProfileKeys = new LinkedHashMap<>();
|
||||
private final Map<ACI, ProfileKey> profileKeys = new LinkedHashMap<>();
|
||||
private final Map<ACI, ProfileKey> authoritativeProfileKeys = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Add new profile keys from a group change.
|
||||
@@ -96,20 +97,20 @@ public final class ProfileKeySet {
|
||||
}
|
||||
|
||||
if (memberUuid.equals(changeSource)) {
|
||||
authoritativeProfileKeys.put(memberUuid, profileKey);
|
||||
profileKeys.remove(memberUuid);
|
||||
authoritativeProfileKeys.put(ACI.from(memberUuid), profileKey);
|
||||
profileKeys.remove(ACI.from(memberUuid));
|
||||
} else {
|
||||
if (!authoritativeProfileKeys.containsKey(memberUuid)) {
|
||||
profileKeys.put(memberUuid, profileKey);
|
||||
if (!authoritativeProfileKeys.containsKey(ACI.from(memberUuid))) {
|
||||
profileKeys.put(ACI.from(memberUuid), profileKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<UUID, ProfileKey> getProfileKeys() {
|
||||
public Map<ACI, ProfileKey> getProfileKeys() {
|
||||
return profileKeys;
|
||||
}
|
||||
|
||||
public Map<UUID, ProfileKey> getAuthoritativeProfileKeys() {
|
||||
public Map<ACI, ProfileKey> getAuthoritativeProfileKeys() {
|
||||
return authoritativeProfileKeys;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api;
|
||||
import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException;
|
||||
import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.push.exceptions.GroupNotFoundException;
|
||||
import org.whispersystems.signalservice.internal.push.exceptions.NotInGroupException;
|
||||
@@ -206,7 +207,7 @@ public final class GroupsV2StateProcessor {
|
||||
}
|
||||
|
||||
if (inputGroupState == null) {
|
||||
if (localState != null && DecryptedGroupUtil.isPendingOrRequesting(localState, Recipient.self().getUuid().get())) {
|
||||
if (localState != null && DecryptedGroupUtil.isPendingOrRequesting(localState, Recipient.self().requireAci().uuid())) {
|
||||
Log.w(TAG, "Unable to query server for group " + groupId + " server says we're not in group, but we think we are a pending or requesting member");
|
||||
} else {
|
||||
Log.w(TAG, "Unable to query server for group " + groupId + " server says we're not in group, inserting leave message");
|
||||
@@ -250,7 +251,7 @@ public final class GroupsV2StateProcessor {
|
||||
throws IOException, GroupNotAMemberException, GroupDoesNotExistException
|
||||
{
|
||||
try {
|
||||
return groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
return groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireAci(), groupSecretParams));
|
||||
} catch (GroupNotFoundException e) {
|
||||
throw new GroupDoesNotExistException(e);
|
||||
} catch (NotInGroupException e) {
|
||||
@@ -265,7 +266,7 @@ public final class GroupsV2StateProcessor {
|
||||
throws IOException, GroupNotAMemberException, GroupDoesNotExistException
|
||||
{
|
||||
try {
|
||||
return groupsV2Api.getGroupHistory(groupSecretParams, revision, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams))
|
||||
return groupsV2Api.getGroupHistory(groupSecretParams, revision, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireAci(), groupSecretParams))
|
||||
.get(0)
|
||||
.getGroup()
|
||||
.orNull();
|
||||
@@ -285,7 +286,7 @@ public final class GroupsV2StateProcessor {
|
||||
}
|
||||
|
||||
Recipient groupRecipient = Recipient.externalGroupExact(context, groupId);
|
||||
UUID selfUuid = Recipient.self().getUuid().get();
|
||||
UUID selfUuid = Recipient.self().requireAci().uuid();
|
||||
DecryptedGroup decryptedGroup = groupDatabase.requireGroup(groupId)
|
||||
.requireV2GroupProperties()
|
||||
.getDecryptedGroup();
|
||||
@@ -359,7 +360,7 @@ public final class GroupsV2StateProcessor {
|
||||
@NonNull DecryptedGroup newLocalState)
|
||||
{
|
||||
if (inputGroupState.getLocalState() != null) {
|
||||
boolean wasAMemberAlready = DecryptedGroupUtil.findMemberByUuid(inputGroupState.getLocalState().getMembersList(), Recipient.self().getUuid().get()).isPresent();
|
||||
boolean wasAMemberAlready = DecryptedGroupUtil.findMemberByUuid(inputGroupState.getLocalState().getMembersList(), Recipient.self().requireAci().uuid()).isPresent();
|
||||
|
||||
if (wasAMemberAlready) {
|
||||
Log.i(TAG, "Skipping profile sharing detection as was already a full member before update");
|
||||
@@ -367,7 +368,7 @@ public final class GroupsV2StateProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
Optional<DecryptedMember> selfAsMemberOptional = DecryptedGroupUtil.findMemberByUuid(newLocalState.getMembersList(), Recipient.self().getUuid().get());
|
||||
Optional<DecryptedMember> selfAsMemberOptional = DecryptedGroupUtil.findMemberByUuid(newLocalState.getMembersList(), Recipient.self().requireAci().uuid());
|
||||
|
||||
if (selfAsMemberOptional.isPresent()) {
|
||||
DecryptedMember selfAsMember = selfAsMemberOptional.get();
|
||||
@@ -378,7 +379,7 @@ public final class GroupsV2StateProcessor {
|
||||
.filter(c -> c != null && c.getRevision() == revisionJoinedAt)
|
||||
.findFirst()
|
||||
.map(c -> Optional.fromNullable(UuidUtil.fromByteStringOrNull(c.getEditor()))
|
||||
.transform(a -> Recipient.externalPush(context, UuidUtil.fromByteStringOrNull(c.getEditor()), null, false)))
|
||||
.transform(a -> Recipient.externalPush(context, ACI.fromByteStringOrNull(c.getEditor()), null, false)))
|
||||
.orElse(Optional.absent());
|
||||
|
||||
if (addedByOptional.isPresent()) {
|
||||
@@ -446,33 +447,33 @@ public final class GroupsV2StateProcessor {
|
||||
private @NonNull GlobalGroupState queryServer(@Nullable DecryptedGroup localState, boolean latestOnly)
|
||||
throws IOException, GroupNotAMemberException
|
||||
{
|
||||
UUID selfUuid = Recipient.self().getUuid().get();
|
||||
ACI selfAci = Recipient.self().requireAci();
|
||||
DecryptedGroup latestServerGroup;
|
||||
List<ServerGroupLogEntry> history;
|
||||
|
||||
try {
|
||||
latestServerGroup = groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(selfUuid, groupSecretParams));
|
||||
latestServerGroup = groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
} catch (NotInGroupException | GroupNotFoundException e) {
|
||||
throw new GroupNotAMemberException(e);
|
||||
} catch (VerificationFailedException | InvalidGroupStateException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
if (latestOnly || !GroupProtoUtil.isMember(selfUuid, latestServerGroup.getMembersList())) {
|
||||
if (latestOnly || !GroupProtoUtil.isMember(selfAci.uuid(), latestServerGroup.getMembersList())) {
|
||||
history = Collections.singletonList(new ServerGroupLogEntry(latestServerGroup, null));
|
||||
} else {
|
||||
int revisionWeWereAdded = GroupProtoUtil.findRevisionWeWereAdded(latestServerGroup, selfUuid);
|
||||
int revisionWeWereAdded = GroupProtoUtil.findRevisionWeWereAdded(latestServerGroup, selfAci.uuid());
|
||||
int logsNeededFrom = localState != null ? Math.max(localState.getRevision(), revisionWeWereAdded) : revisionWeWereAdded;
|
||||
|
||||
history = getFullMemberHistory(selfUuid, logsNeededFrom);
|
||||
history = getFullMemberHistory(selfAci, logsNeededFrom);
|
||||
}
|
||||
|
||||
return new GlobalGroupState(localState, history);
|
||||
}
|
||||
|
||||
private List<ServerGroupLogEntry> getFullMemberHistory(@NonNull UUID selfUuid, int logsNeededFromRevision) throws IOException {
|
||||
private List<ServerGroupLogEntry> getFullMemberHistory(@NonNull ACI selfAci, int logsNeededFromRevision) throws IOException {
|
||||
try {
|
||||
Collection<DecryptedGroupHistoryEntry> groupStatesFromRevision = groupsV2Api.getGroupHistory(groupSecretParams, logsNeededFromRevision, groupsV2Authorization.getAuthorizationForToday(selfUuid, groupSecretParams));
|
||||
Collection<DecryptedGroupHistoryEntry> groupStatesFromRevision = groupsV2Api.getGroupHistory(groupSecretParams, logsNeededFromRevision, groupsV2Authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
ArrayList<ServerGroupLogEntry> history = new ArrayList<>(groupStatesFromRevision.size());
|
||||
boolean ignoreServerChanges = SignalStore.internalValues().gv2IgnoreServerChanges();
|
||||
|
||||
@@ -496,9 +497,9 @@ public final class GroupsV2StateProcessor {
|
||||
}
|
||||
|
||||
private void storeMessage(@NonNull DecryptedGroupV2Context decryptedGroupV2Context, long timestamp) {
|
||||
Optional<UUID> editor = getEditor(decryptedGroupV2Context);
|
||||
Optional<ACI> editor = getEditor(decryptedGroupV2Context).transform(ACI::from);
|
||||
|
||||
boolean outgoing = !editor.isPresent() || Recipient.self().requireUuid().equals(editor.get());
|
||||
boolean outgoing = !editor.isPresent() || Recipient.self().requireAci().equals(editor.get());
|
||||
|
||||
if (outgoing) {
|
||||
try {
|
||||
@@ -536,7 +537,7 @@ public final class GroupsV2StateProcessor {
|
||||
if (changeEditor.isPresent()) {
|
||||
return changeEditor;
|
||||
} else {
|
||||
Optional<DecryptedPendingMember> pendingByUuid = DecryptedGroupUtil.findPendingByUuid(decryptedGroupV2Context.getGroupState().getPendingMembersList(), Recipient.self().requireUuid());
|
||||
Optional<DecryptedPendingMember> pendingByUuid = DecryptedGroupUtil.findPendingByUuid(decryptedGroupV2Context.getGroupState().getPendingMembersList(), Recipient.self().requireAci().uuid());
|
||||
if (pendingByUuid.isPresent()) {
|
||||
return Optional.fromNullable(UuidUtil.fromByteStringOrNull(pendingByUuid.get().getAddedByUuid()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user