Search in sources :

Example 36 with DecryptedGroupChange

use of org.signal.storageservice.protos.groups.local.DecryptedGroupChange in project Signal-Android by WhisperSystems.

the class GroupDatabase method update.

public void update(@NonNull GroupId.V2 groupId, @NonNull DecryptedGroup decryptedGroup) {
    RecipientDatabase recipientDatabase = SignalDatabase.recipients();
    RecipientId groupRecipientId = recipientDatabase.getOrInsertFromGroupId(groupId);
    Optional<GroupRecord> existingGroup = getGroup(groupId);
    String title = decryptedGroup.getTitle();
    ContentValues contentValues = new ContentValues();
    if (existingGroup.isPresent() && existingGroup.get().getUnmigratedV1Members().size() > 0 && existingGroup.get().isV2Group()) {
        Set<RecipientId> unmigratedV1Members = new HashSet<>(existingGroup.get().getUnmigratedV1Members());
        DecryptedGroupChange change = GroupChangeReconstruct.reconstructGroupChange(existingGroup.get().requireV2GroupProperties().getDecryptedGroup(), decryptedGroup);
        List<RecipientId> addedMembers = uuidsToRecipientIds(DecryptedGroupUtil.membersToUuidList(change.getNewMembersList()));
        List<RecipientId> removedMembers = uuidsToRecipientIds(DecryptedGroupUtil.removedMembersUuidList(change));
        List<RecipientId> addedInvites = uuidsToRecipientIds(DecryptedGroupUtil.pendingToUuidList(change.getNewPendingMembersList()));
        List<RecipientId> removedInvites = uuidsToRecipientIds(DecryptedGroupUtil.removedPendingMembersUuidList(change));
        List<RecipientId> acceptedInvites = uuidsToRecipientIds(DecryptedGroupUtil.membersToUuidList(change.getPromotePendingMembersList()));
        unmigratedV1Members.removeAll(addedMembers);
        unmigratedV1Members.removeAll(removedMembers);
        unmigratedV1Members.removeAll(addedInvites);
        unmigratedV1Members.removeAll(removedInvites);
        unmigratedV1Members.removeAll(acceptedInvites);
        contentValues.put(UNMIGRATED_V1_MEMBERS, unmigratedV1Members.isEmpty() ? null : RecipientId.toSerializedList(unmigratedV1Members));
    }
    List<RecipientId> groupMembers = getV2GroupMembers(decryptedGroup, true);
    contentValues.put(TITLE, title);
    contentValues.put(V2_REVISION, decryptedGroup.getRevision());
    contentValues.put(V2_DECRYPTED_GROUP, decryptedGroup.toByteArray());
    contentValues.put(MEMBERS, RecipientId.toSerializedList(groupMembers));
    contentValues.put(ACTIVE, gv2GroupActive(decryptedGroup) ? 1 : 0);
    DistributionId distributionId = Objects.requireNonNull(existingGroup.get().getDistributionId());
    if (existingGroup.isPresent() && existingGroup.get().isV2Group()) {
        DecryptedGroupChange change = GroupChangeReconstruct.reconstructGroupChange(existingGroup.get().requireV2GroupProperties().getDecryptedGroup(), decryptedGroup);
        List<UUID> removed = DecryptedGroupUtil.removedMembersUuidList(change);
        if (removed.size() > 0) {
            Log.i(TAG, removed.size() + " members were removed from group " + groupId + ". Rotating the DistributionId " + distributionId);
            SenderKeyUtil.rotateOurKey(context, distributionId);
        }
    }
    databaseHelper.getSignalWritableDatabase().update(TABLE_NAME, contentValues, GROUP_ID + " = ?", new String[] { groupId.toString() });
    if (decryptedGroup.hasDisappearingMessagesTimer()) {
        recipientDatabase.setExpireMessages(groupRecipientId, decryptedGroup.getDisappearingMessagesTimer().getDuration());
    }
    if (groupId.isMms() || Recipient.resolved(groupRecipientId).isProfileSharing()) {
        recipientDatabase.setHasGroupsInCommon(groupMembers);
    }
    Recipient.live(groupRecipientId).refresh();
    notifyConversationListListeners();
}
Also used : ContentValues(android.content.ContentValues) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) DistributionId(org.whispersystems.signalservice.api.push.DistributionId) DecryptedGroupChange(org.signal.storageservice.protos.groups.local.DecryptedGroupChange) UUID(java.util.UUID) HashSet(java.util.HashSet)

Example 37 with DecryptedGroupChange

use of org.signal.storageservice.protos.groups.local.DecryptedGroupChange in project Signal-Android by WhisperSystems.

the class GroupsV2UpdateMessageProducer method describePromotePending.

private void describePromotePending(@NonNull DecryptedGroupChange change, @NonNull List<UpdateDescription> updates) {
    boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
    for (DecryptedMember newMember : change.getPromotePendingMembersList()) {
        ByteString uuid = newMember.getUuid();
        boolean newMemberIsYou = uuid.equals(selfUuidBytes);
        if (editorIsYou) {
            if (newMemberIsYou) {
                updates.add(updateDescription(context.getString(R.string.MessageRecord_you_accepted_invite), R.drawable.ic_update_group_accept_16));
            } else {
                updates.add(updateDescription(uuid, newPromotedMember -> context.getString(R.string.MessageRecord_you_added_invited_member_s, newPromotedMember), R.drawable.ic_update_group_add_16));
            }
        } else {
            if (newMemberIsYou) {
                updates.add(updateDescription(change.getEditor(), editor -> context.getString(R.string.MessageRecord_s_added_you, editor), R.drawable.ic_update_group_add_16));
            } else {
                if (uuid.equals(change.getEditor())) {
                    updates.add(updateDescription(uuid, newAcceptedMember -> context.getString(R.string.MessageRecord_s_accepted_invite, newAcceptedMember), R.drawable.ic_update_group_accept_16));
                } else {
                    updates.add(updateDescription(change.getEditor(), uuid, (editor, newAcceptedMember) -> context.getString(R.string.MessageRecord_s_added_invited_member_s, editor, newAcceptedMember), R.drawable.ic_update_group_add_16));
                }
            }
        }
    }
}
Also used : Context(android.content.Context) Arrays(java.util.Arrays) NonNull(androidx.annotation.NonNull) StringUtil(org.thoughtcrime.securesms.util.StringUtil) WorkerThread(androidx.annotation.WorkerThread) GV2AccessLevelUtil(org.thoughtcrime.securesms.groups.GV2AccessLevelUtil) ExpirationUtil(org.thoughtcrime.securesms.util.ExpirationUtil) DrawableRes(androidx.annotation.DrawableRes) AccessControl(org.signal.storageservice.protos.groups.AccessControl) R(org.thoughtcrime.securesms.R) Member(org.signal.storageservice.protos.groups.Member) DecryptedModifyMemberRole(org.signal.storageservice.protos.groups.local.DecryptedModifyMemberRole) DecryptedGroupChange(org.signal.storageservice.protos.groups.local.DecryptedGroupChange) DecryptedApproveMember(org.signal.storageservice.protos.groups.local.DecryptedApproveMember) LinkedList(java.util.LinkedList) DecryptedRequestingMember(org.signal.storageservice.protos.groups.local.DecryptedRequestingMember) DecryptedMember(org.signal.storageservice.protos.groups.local.DecryptedMember) ACI(org.whispersystems.signalservice.api.push.ACI) DecryptedGroupUtil(org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil) EnabledState(org.signal.storageservice.protos.groups.local.EnabledState) UuidUtil(org.whispersystems.signalservice.api.util.UuidUtil) DecryptedPendingMember(org.signal.storageservice.protos.groups.local.DecryptedPendingMember) UUID(java.util.UUID) Optional(org.whispersystems.libsignal.util.guava.Optional) ByteString(com.google.protobuf.ByteString) DecryptedGroup(org.signal.storageservice.protos.groups.local.DecryptedGroup) List(java.util.List) Nullable(androidx.annotation.Nullable) DecryptedPendingMemberRemoval(org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval) ServiceId(org.whispersystems.signalservice.api.push.ServiceId) Collections(java.util.Collections) ByteString(com.google.protobuf.ByteString) DecryptedMember(org.signal.storageservice.protos.groups.local.DecryptedMember)

Example 38 with DecryptedGroupChange

use of org.signal.storageservice.protos.groups.local.DecryptedGroupChange in project Signal-Android by WhisperSystems.

the class GroupsV2UpdateMessageProducer method describeInvitations.

private void describeInvitations(@NonNull DecryptedGroupChange change, @NonNull List<UpdateDescription> updates) {
    boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
    int notYouInviteCount = 0;
    for (DecryptedPendingMember invitee : change.getNewPendingMembersList()) {
        boolean newMemberIsYou = invitee.getUuid().equals(selfUuidBytes);
        if (newMemberIsYou) {
            updates.add(0, updateDescription(change.getEditor(), editor -> context.getString(R.string.MessageRecord_s_invited_you_to_the_group, editor), R.drawable.ic_update_group_add_16));
        } else {
            if (editorIsYou) {
                updates.add(updateDescription(invitee.getUuid(), newInvitee -> context.getString(R.string.MessageRecord_you_invited_s_to_the_group, newInvitee), R.drawable.ic_update_group_add_16));
            } else {
                notYouInviteCount++;
            }
        }
    }
    if (notYouInviteCount > 0) {
        final int notYouInviteCountFinalCopy = notYouInviteCount;
        updates.add(updateDescription(change.getEditor(), editor -> context.getResources().getQuantityString(R.plurals.MessageRecord_s_invited_members, notYouInviteCountFinalCopy, editor, notYouInviteCountFinalCopy), R.drawable.ic_update_group_add_16));
    }
}
Also used : Context(android.content.Context) Arrays(java.util.Arrays) NonNull(androidx.annotation.NonNull) StringUtil(org.thoughtcrime.securesms.util.StringUtil) WorkerThread(androidx.annotation.WorkerThread) GV2AccessLevelUtil(org.thoughtcrime.securesms.groups.GV2AccessLevelUtil) ExpirationUtil(org.thoughtcrime.securesms.util.ExpirationUtil) DrawableRes(androidx.annotation.DrawableRes) AccessControl(org.signal.storageservice.protos.groups.AccessControl) R(org.thoughtcrime.securesms.R) Member(org.signal.storageservice.protos.groups.Member) DecryptedModifyMemberRole(org.signal.storageservice.protos.groups.local.DecryptedModifyMemberRole) DecryptedGroupChange(org.signal.storageservice.protos.groups.local.DecryptedGroupChange) DecryptedApproveMember(org.signal.storageservice.protos.groups.local.DecryptedApproveMember) LinkedList(java.util.LinkedList) DecryptedRequestingMember(org.signal.storageservice.protos.groups.local.DecryptedRequestingMember) DecryptedMember(org.signal.storageservice.protos.groups.local.DecryptedMember) ACI(org.whispersystems.signalservice.api.push.ACI) DecryptedGroupUtil(org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil) EnabledState(org.signal.storageservice.protos.groups.local.EnabledState) UuidUtil(org.whispersystems.signalservice.api.util.UuidUtil) DecryptedPendingMember(org.signal.storageservice.protos.groups.local.DecryptedPendingMember) UUID(java.util.UUID) Optional(org.whispersystems.libsignal.util.guava.Optional) ByteString(com.google.protobuf.ByteString) DecryptedGroup(org.signal.storageservice.protos.groups.local.DecryptedGroup) List(java.util.List) Nullable(androidx.annotation.Nullable) DecryptedPendingMemberRemoval(org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval) ServiceId(org.whispersystems.signalservice.api.push.ServiceId) Collections(java.util.Collections) DecryptedPendingMember(org.signal.storageservice.protos.groups.local.DecryptedPendingMember)

Example 39 with DecryptedGroupChange

use of org.signal.storageservice.protos.groups.local.DecryptedGroupChange in project Signal-Android by WhisperSystems.

the class MessageRecord method isSelfCreatedGroup.

public boolean isSelfCreatedGroup() {
    DecryptedGroupV2Context decryptedGroupV2Context = getDecryptedGroupV2Context();
    if (decryptedGroupV2Context == null) {
        return false;
    }
    DecryptedGroupChange change = decryptedGroupV2Context.getChange();
    return selfCreatedGroup(change);
}
Also used : DecryptedGroupChange(org.signal.storageservice.protos.groups.local.DecryptedGroupChange) DecryptedGroupV2Context(org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2Context)

Example 40 with DecryptedGroupChange

use of org.signal.storageservice.protos.groups.local.DecryptedGroupChange in project Signal-Android by WhisperSystems.

the class GroupChangeUtil_resolveConflict_decryptedOnly_Test method field_13__no_attribute_access_change_is_removed.

@Test
public void field_13__no_attribute_access_change_is_removed() {
    DecryptedGroup groupState = DecryptedGroup.newBuilder().setAccessControl(AccessControl.newBuilder().setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)).build();
    DecryptedGroupChange decryptedChange = DecryptedGroupChange.newBuilder().setNewAttributeAccess(AccessControl.AccessRequired.ADMINISTRATOR).build();
    DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
    assertTrue(DecryptedGroupUtil.changeIsEmpty(resolvedChanges));
}
Also used : DecryptedGroupChange(org.signal.storageservice.protos.groups.local.DecryptedGroupChange) DecryptedGroup(org.signal.storageservice.protos.groups.local.DecryptedGroup) Test(org.junit.Test)

Aggregations

DecryptedGroupChange (org.signal.storageservice.protos.groups.local.DecryptedGroupChange)486 Test (org.junit.Test)460 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)234 DecryptedGroup (org.signal.storageservice.protos.groups.local.DecryptedGroup)190 UUID (java.util.UUID)110 GroupChange (org.signal.storageservice.protos.groups.GroupChange)62 ProfileKey (org.signal.zkgroup.profiles.ProfileKey)34 ProtoTestUtils.randomProfileKey (org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.randomProfileKey)34 ByteString (com.google.protobuf.ByteString)18 DecryptedMember (org.signal.storageservice.protos.groups.local.DecryptedMember)14 NonNull (androidx.annotation.NonNull)12 DecryptedPendingMember (org.signal.storageservice.protos.groups.local.DecryptedPendingMember)12 DecryptedGroupV2Context (org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2Context)12 ProtoTestUtils.newProfileKey (org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.newProfileKey)12 ProtoTestUtils.withProfileKey (org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.withProfileKey)12 DecryptedPendingMemberRemoval (org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval)10 DecryptedRequestingMember (org.signal.storageservice.protos.groups.local.DecryptedRequestingMember)10 Context (android.content.Context)8 DrawableRes (androidx.annotation.DrawableRes)8 Nullable (androidx.annotation.Nullable)8