mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-30 16:26:48 +00:00
Get authoritative profile keys from group changes only.
This commit is contained in:
committed by
Greyson Parrelli
parent
17c0364eda
commit
26868ae668
@@ -4,6 +4,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
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.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.profiles.ProfileKey;
|
||||
@@ -30,38 +31,62 @@ public final class ProfileKeySet {
|
||||
private final Map<UUID, ProfileKey> authoritativeProfileKeys = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Add new profile keys from the group state.
|
||||
* Add new profile keys from a group change.
|
||||
* <p>
|
||||
* If the change came from the member whose profile key is changing then it is regarded as
|
||||
* authoritative.
|
||||
*/
|
||||
public void addKeysFromGroupState(@NonNull DecryptedGroup group,
|
||||
@Nullable UUID changeSource)
|
||||
{
|
||||
public void addKeysFromGroupChange(@NonNull DecryptedGroupChange change) {
|
||||
UUID editor = UuidUtil.fromByteStringOrNull(change.getEditor());
|
||||
|
||||
for (DecryptedMember member : change.getNewMembersList()) {
|
||||
addMemberKey(member, editor);
|
||||
}
|
||||
|
||||
for (DecryptedMember member : change.getPromotePendingMembersList()) {
|
||||
addMemberKey(member, editor);
|
||||
}
|
||||
|
||||
for (DecryptedMember member : change.getModifiedProfileKeysList()) {
|
||||
addMemberKey(member, editor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new profile keys from the group state.
|
||||
* <p>
|
||||
* Profile keys found in group state are never authoritative as the change cannot be easily
|
||||
* attributed to a member and it's possible that the group is out of date. So profile keys
|
||||
* gathered from a group state can only be used to fill in gaps in knowledge.
|
||||
*/
|
||||
public void addKeysFromGroupState(@NonNull DecryptedGroup group) {
|
||||
for (DecryptedMember member : group.getMembersList()) {
|
||||
UUID memberUuid = UuidUtil.fromByteString(member.getUuid());
|
||||
addMemberKey(member, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (UuidUtil.UNKNOWN_UUID.equals(memberUuid)) {
|
||||
Log.w(TAG, "Seen unknown member UUID");
|
||||
continue;
|
||||
}
|
||||
private void addMemberKey(@NonNull DecryptedMember member, @Nullable UUID changeSource) {
|
||||
UUID memberUuid = UuidUtil.fromByteString(member.getUuid());
|
||||
|
||||
ProfileKey profileKey;
|
||||
try {
|
||||
profileKey = new ProfileKey(member.getProfileKey().toByteArray());
|
||||
} catch (InvalidInputException e) {
|
||||
Log.w(TAG, "Bad profile key in group");
|
||||
continue;
|
||||
}
|
||||
if (UuidUtil.UNKNOWN_UUID.equals(memberUuid)) {
|
||||
Log.w(TAG, "Seen unknown member UUID");
|
||||
return;
|
||||
}
|
||||
|
||||
if (changeSource != null) {
|
||||
Log.d(TAG, String.format("Change %s by %s", memberUuid, changeSource));
|
||||
ProfileKey profileKey;
|
||||
try {
|
||||
profileKey = new ProfileKey(member.getProfileKey().toByteArray());
|
||||
} catch (InvalidInputException e) {
|
||||
Log.w(TAG, "Bad profile key in group");
|
||||
return;
|
||||
}
|
||||
|
||||
if (changeSource.equals(memberUuid)) {
|
||||
authoritativeProfileKeys.put(memberUuid, profileKey);
|
||||
profileKeys.remove(memberUuid);
|
||||
} else {
|
||||
if (!authoritativeProfileKeys.containsKey(memberUuid)) {
|
||||
profileKeys.put(memberUuid, profileKey);
|
||||
}
|
||||
}
|
||||
if (memberUuid.equals(changeSource)) {
|
||||
authoritativeProfileKeys.put(memberUuid, profileKey);
|
||||
profileKeys.remove(memberUuid);
|
||||
} else {
|
||||
if (!authoritativeProfileKeys.containsKey(memberUuid)) {
|
||||
profileKeys.put(memberUuid, profileKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
||||
@@ -16,8 +14,6 @@ import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
||||
import org.signal.zkgroup.VerificationFailedException;
|
||||
import org.signal.zkgroup.groups.GroupMasterKey;
|
||||
import org.signal.zkgroup.groups.GroupSecretParams;
|
||||
import org.signal.zkgroup.util.UUIDUtil;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
@@ -320,9 +316,11 @@ public final class GroupsV2StateProcessor {
|
||||
final ProfileKeySet profileKeys = new ProfileKeySet();
|
||||
|
||||
for (ServerGroupLogEntry entry : globalGroupState.getServerHistory()) {
|
||||
Optional<UUID> editor = DecryptedGroupUtil.editorUuid(entry.getChange());
|
||||
if (editor.isPresent() && entry.getGroup() != null) {
|
||||
profileKeys.addKeysFromGroupState(entry.getGroup(), editor.get());
|
||||
if (entry.getGroup() != null) {
|
||||
profileKeys.addKeysFromGroupState(entry.getGroup());
|
||||
}
|
||||
if (entry.getChange() != null) {
|
||||
profileKeys.addKeysFromGroupChange(entry.getChange());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user