Set profile sharing based on who added you to the group.

This commit is contained in:
Alan Evans
2020-09-05 10:09:31 -03:00
committed by Cody Henthorne
parent a870ef0030
commit c797b09228
7 changed files with 155 additions and 55 deletions

View File

@@ -1119,19 +1119,19 @@ public class ThreadDatabase extends Database {
Recipient resolved = Recipient.resolved(threadRecipientId);
if (resolved.isPushGroup()) {
if (resolved.isPushV2Group()) {
DecryptedGroup decryptedGroup = DatabaseFactory.getGroupDatabase(context).requireGroup(resolved.requireGroupId().requireV2()).requireV2GroupProperties().getDecryptedGroup();
Optional<UUID> inviter = DecryptedGroupUtil.findInviter(decryptedGroup.getPendingMembersList(), Recipient.self().getUuid().get());
if (inviter.isPresent()) {
RecipientId recipientId = RecipientId.from(inviter.get(), null);
return Extra.forGroupV2invite(recipientId);
} else if (decryptedGroup.getRevision() == 0) {
Optional<DecryptedMember> foundingMember = DecryptedGroupUtil.firstMember(decryptedGroup.getMembersList());
if (foundingMember.isPresent()) {
return Extra.forGroupMessageRequest(RecipientId.from(UuidUtil.fromByteString(foundingMember.get().getUuid()), null));
MessageRecord.InviteAddState inviteAddState = record.getGv2AddInviteState();
if (inviteAddState != null) {
RecipientId from = RecipientId.from(inviteAddState.getAddedOrInvitedBy(), null);
if (inviteAddState.isInvited()) {
Log.i(TAG, "GV2 invite message request from " + from);
return Extra.forGroupV2invite(from);
} else {
Log.i(TAG, "GV2 message request from " + from);
return Extra.forGroupMessageRequest(from);
}
}
Log.w(TAG, "Falling back to unknown message request state for GV2 message");
return Extra.forMessageRequest();
} else {
RecipientId recipientId = DatabaseFactory.getMmsSmsDatabase(context).getGroupAddedBy(record.getThreadId());

View File

@@ -53,23 +53,24 @@ final class GroupsV2UpdateMessageProducer {
/**
* Describes a group that is new to you, use this when there is no available change record.
* <p>
* Invitation and groups you create are the most common cases where no change is available.
* Invitation and revision 0 groups are the most common use cases for this.
* <p>
* When invited, it's possible there's no change available.
* <p>
* When the revision of the group is 0, the change is very noisy and only the editor is useful.
*/
UpdateDescription describeNewGroup(@NonNull DecryptedGroup group) {
UpdateDescription describeNewGroup(@NonNull DecryptedGroup group, @NonNull DecryptedGroupChange decryptedGroupChange) {
Optional<DecryptedPendingMember> selfPending = DecryptedGroupUtil.findPendingByUuid(group.getPendingMembersList(), selfUuid);
if (selfPending.isPresent()) {
return updateDescription(selfPending.get().getAddedByUuid(), inviteBy -> context.getString(R.string.MessageRecord_s_invited_you_to_the_group, inviteBy));
}
if (group.getRevision() == 0) {
Optional<DecryptedMember> foundingMember = DecryptedGroupUtil.firstMember(group.getMembersList());
if (foundingMember.isPresent()) {
ByteString foundingMemberUuid = foundingMember.get().getUuid();
if (selfUuidBytes.equals(foundingMemberUuid)) {
return updateDescription(context.getString(R.string.MessageRecord_you_created_the_group));
} else {
return updateDescription(foundingMemberUuid, creator -> context.getString(R.string.MessageRecord_s_added_you, creator));
}
ByteString foundingMemberUuid = decryptedGroupChange.getEditor();
if (!foundingMemberUuid.isEmpty()) {
if (selfUuidBytes.equals(foundingMemberUuid)) {
return updateDescription(context.getString(R.string.MessageRecord_you_created_the_group));
} else {
return updateDescription(foundingMemberUuid, creator -> context.getString(R.string.MessageRecord_s_added_you, creator));
}
}

View File

@@ -25,6 +25,7 @@ import android.text.style.StyleSpan;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SmsDatabase;
@@ -41,6 +42,7 @@ import org.thoughtcrime.securesms.util.ExpirationUtil;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.StringUtil;
import org.whispersystems.libsignal.util.guava.Function;
import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
import org.whispersystems.signalservice.api.util.UuidUtil;
import java.io.IOException;
@@ -177,7 +179,7 @@ public abstract class MessageRecord extends DisplayRecord {
if (decryptedGroupV2Context.hasChange() && decryptedGroupV2Context.getGroupState().getRevision() != 0) {
return UpdateDescription.concatWithNewLines(updateMessageProducer.describeChanges(decryptedGroupV2Context.getChange()));
} else {
return updateMessageProducer.describeNewGroup(decryptedGroupV2Context.getGroupState());
return updateMessageProducer.describeNewGroup(decryptedGroupV2Context.getGroupState(), decryptedGroupV2Context.getChange());
}
} catch (IOException e) {
Log.w(TAG, "GV2 Message update detail could not be read", e);
@@ -185,6 +187,29 @@ public abstract class MessageRecord extends DisplayRecord {
}
}
public @Nullable InviteAddState getGv2AddInviteState() {
try {
byte[] decoded = Base64.decode(getBody());
DecryptedGroupV2Context decryptedGroupV2Context = DecryptedGroupV2Context.parseFrom(decoded);
DecryptedGroup groupState = decryptedGroupV2Context.getGroupState();
boolean invited = DecryptedGroupUtil.findPendingByUuid(groupState.getPendingMembersList(), Recipient.self().requireUuid()).isPresent();
if (decryptedGroupV2Context.hasChange()) {
UUID changeEditor = UuidUtil.fromByteStringOrNull(decryptedGroupV2Context.getChange().getEditor());
if (changeEditor != null) {
return new InviteAddState(invited, changeEditor);
}
}
Log.w(TAG, "GV2 Message editor could not be determined");
return null;
} catch (IOException e) {
Log.w(TAG, "GV2 Message update detail could not be read", e);
return null;
}
}
private static @NonNull UpdateDescription fromRecipient(@NonNull Recipient recipient, @NonNull Function<Recipient, String> stringFunction) {
return UpdateDescription.mentioning(Collections.singletonList(recipient.getUuid().or(UuidUtil.UNKNOWN_UUID)), () -> stringFunction.apply(recipient.resolve()));
}
@@ -378,4 +403,23 @@ public abstract class MessageRecord extends DisplayRecord {
public boolean hasSelfMention() {
return false;
}
public static final class InviteAddState {
private final boolean invited;
private final UUID addedOrInvitedBy;
public InviteAddState(boolean invited, @NonNull UUID addedOrInvitedBy) {
this.invited = invited;
this.addedOrInvitedBy = addedOrInvitedBy;
}
public @NonNull UUID getAddedOrInvitedBy() {
return addedOrInvitedBy;
}
public boolean isInvited() {
return invited;
}
}
}