if (groupInfoV2.getGroup() == null
|| groupInfoV2.getGroup().getRevision() < groupContext.getRevision()) {
- // TODO check if revision is only 1 behind and a signedGroupChange is available
- groupInfoV2.setGroup(getDecryptedGroup(groupSecretParams));
+ DecryptedGroup group = null;
+ if (groupContext.hasSignedGroupChange()
+ && groupInfoV2.getGroup() != null
+ && groupInfoV2.getGroup().getRevision() + 1 == groupContext.getRevision()) {
+ group = groupHelper.getUpdatedDecryptedGroup(groupInfoV2.getGroup(),
+ groupContext.getSignedGroupChange(),
+ groupMasterKey);
+ }
+ if (group == null) {
+ group = getDecryptedGroup(groupSecretParams);
+ }
+ groupInfoV2.setGroup(group);
account.getGroupStore().updateGroup(groupInfoV2);
}
}
package org.asamk.signal.manager.helper;
+import com.google.protobuf.InvalidProtocolBufferException;
+
+import org.signal.storageservice.protos.groups.GroupChange;
import org.signal.storageservice.protos.groups.Member;
+import org.signal.storageservice.protos.groups.local.DecryptedGroup;
+import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
+import org.signal.zkgroup.VerificationFailedException;
+import org.signal.zkgroup.groups.GroupMasterKey;
import org.signal.zkgroup.groups.GroupSecretParams;
import org.signal.zkgroup.profiles.ProfileKeyCredential;
import org.whispersystems.libsignal.util.guava.Optional;
+import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
import org.whispersystems.signalservice.api.groupsv2.GroupCandidate;
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.SignalServiceAddress;
import java.util.Collection;
0);
}
+ public DecryptedGroup getUpdatedDecryptedGroup(
+ DecryptedGroup group, byte[] signedGroupChange, GroupMasterKey groupMasterKey
+ ) {
+ try {
+ final DecryptedGroupChange decryptedGroupChange = getDecryptedGroupChange(signedGroupChange,
+ groupMasterKey);
+ if (decryptedGroupChange == null) {
+ return null;
+ }
+ return DecryptedGroupUtil.apply(group, decryptedGroupChange);
+ } catch (NotAbleToApplyGroupV2ChangeException e) {
+ return null;
+ }
+ }
+
+ private DecryptedGroupChange getDecryptedGroupChange(byte[] signedGroupChange, GroupMasterKey groupMasterKey) {
+ if (signedGroupChange != null) {
+ GroupsV2Operations.GroupOperations groupOperations = groupsV2Operations.forGroup(GroupSecretParams.deriveFromMasterKey(
+ groupMasterKey));
+
+ try {
+ return groupOperations.decryptChange(GroupChange.parseFrom(signedGroupChange), true).orNull();
+ } catch (VerificationFailedException | InvalidGroupStateException | InvalidProtocolBufferException e) {
+ return null;
+ }
+ }
+
+ return null;
+ }
}