groupMasterKey);
}
if (group == null) {
- group = groupV2Helper.getDecryptedGroup(groupSecretParams);
+ try {
+ group = groupV2Helper.getDecryptedGroup(groupSecretParams);
+ } catch (NotAGroupMemberException ignored) {
+ }
}
if (group != null) {
storeProfileKeysFromMembers(group);
private GroupInfo getGroup(GroupId groupId, boolean forceUpdate) {
final var group = account.getGroupStore().getGroup(groupId);
- if (group instanceof GroupInfoV2 && (forceUpdate || ((GroupInfoV2) group).getGroup() == null)) {
- final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(((GroupInfoV2) group).getMasterKey());
- ((GroupInfoV2) group).setGroup(groupV2Helper.getDecryptedGroup(groupSecretParams), recipientResolver);
- account.getGroupStore().updateGroup(group);
+ if (group instanceof GroupInfoV2) {
+ final var groupInfoV2 = (GroupInfoV2) group;
+ if (forceUpdate || (!groupInfoV2.isPermissionDenied() && groupInfoV2.getGroup() == null)) {
+ final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
+ DecryptedGroup decryptedGroup;
+ try {
+ decryptedGroup = groupV2Helper.getDecryptedGroup(groupSecretParams);
+ } catch (NotAGroupMemberException e) {
+ groupInfoV2.setPermissionDenied(true);
+ decryptedGroup = null;
+ }
+ groupInfoV2.setGroup(decryptedGroup, recipientResolver);
+ account.getGroupStore().updateGroup(group);
+ }
}
return group;
}
import org.asamk.signal.manager.groups.GroupLinkState;
import org.asamk.signal.manager.groups.GroupPermission;
import org.asamk.signal.manager.groups.GroupUtils;
+import org.asamk.signal.manager.groups.NotAGroupMemberException;
import org.asamk.signal.manager.storage.groups.GroupInfoV2;
import org.asamk.signal.manager.storage.recipients.Profile;
import org.asamk.signal.manager.storage.recipients.RecipientId;
import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException;
import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
+import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
import org.whispersystems.signalservice.api.util.UuidUtil;
import java.io.File;
this.addressResolver = addressResolver;
}
- public DecryptedGroup getDecryptedGroup(final GroupSecretParams groupSecretParams) {
+ public DecryptedGroup getDecryptedGroup(final GroupSecretParams groupSecretParams) throws NotAGroupMemberException {
try {
final var groupsV2AuthorizationString = getGroupAuthForToday(groupSecretParams);
return groupsV2Api.getGroup(groupSecretParams, groupsV2AuthorizationString);
+ } catch (NonSuccessfulResponseCodeException e) {
+ if (e.getCode() == 403) {
+ throw new NotAGroupMemberException(GroupUtils.getGroupIdV2(groupSecretParams), null);
+ }
+ logger.warn("Failed to retrieve Group V2 info, ignoring: {}", e.getMessage());
+ return null;
} catch (IOException | VerificationFailedException | InvalidGroupStateException e) {
logger.warn("Failed to retrieve Group V2 info, ignoring: {}", e.getMessage());
return null;
private boolean blocked;
private DecryptedGroup group; // stored as a file with hexadecimal groupId as name
private RecipientResolver recipientResolver;
+ private boolean permissionDenied;
public GroupInfoV2(final GroupIdV2 groupId, final GroupMasterKey masterKey) {
this.groupId = groupId;
this.masterKey = masterKey;
}
- public GroupInfoV2(final GroupIdV2 groupId, final GroupMasterKey masterKey, final boolean blocked) {
+ public GroupInfoV2(
+ final GroupIdV2 groupId,
+ final GroupMasterKey masterKey,
+ final boolean blocked,
+ final boolean permissionDenied
+ ) {
this.groupId = groupId;
this.masterKey = masterKey;
this.blocked = blocked;
+ this.permissionDenied = permissionDenied;
}
@Override
}
public void setGroup(final DecryptedGroup group, final RecipientResolver recipientResolver) {
+ if (group != null) {
+ this.permissionDenied = false;
+ }
this.group = group;
this.recipientResolver = recipientResolver;
}
public boolean isAnnouncementGroup() {
return this.group != null && this.group.getIsAnnouncementGroup() == EnabledState.ENABLED;
}
+
+ public void setPermissionDenied(final boolean permissionDenied) {
+ this.permissionDenied = permissionDenied;
+ }
+
+ public boolean isPermissionDenied() {
+ return permissionDenied;
+ }
}
throw new AssertionError("Invalid master key for group " + groupId.toBase64());
}
- return new GroupInfoV2(groupId, masterKey, g2.blocked);
+ return new GroupInfoV2(groupId, masterKey, g2.blocked, g2.permissionDenied);
}).collect(Collectors.toMap(GroupInfo::getGroupId, g -> g));
return new GroupStore(groupCachePath, groups, recipientResolver, saver);
final var g2 = (GroupInfoV2) g;
return new Storage.GroupV2(g2.getGroupId().toBase64(),
Base64.getEncoder().encodeToString(g2.getMasterKey().serialize()),
- g2.isBlocked());
+ g2.isBlocked(),
+ g2.isPermissionDenied());
}).collect(Collectors.toList()));
}
public static class Storage {
- // @JsonSerialize(using = GroupsSerializer.class)
@JsonDeserialize(using = GroupsDeserializer.class)
public List<Storage.Group> groups;
public String groupId;
public String masterKey;
public boolean blocked;
+ public boolean permissionDenied;
// For deserialization
private GroupV2() {
}
- public GroupV2(final String groupId, final String masterKey, final boolean blocked) {
+ public GroupV2(
+ final String groupId, final String masterKey, final boolean blocked, final boolean permissionDenied
+ ) {
this.groupId = groupId;
this.masterKey = masterKey;
this.blocked = blocked;
+ this.permissionDenied = permissionDenied;
}
}
}
- // private static class GroupsSerializer extends JsonSerializer<List<Storage.Group>> {
-//
-// @Override
-// public void serialize(
-// final List<Storage.Group> groups, final JsonGenerator jgen, final SerializerProvider provider
-// ) throws IOException {
-// jgen.writeStartArray(groups.size());
-// for (var group : groups) {
-// if (group instanceof GroupInfoV1) {
-// jgen.writeObject(group);
-// } else if (group instanceof GroupInfoV2) {
-// final var groupV2 = (GroupInfoV2) group;
-// jgen.writeStartObject();
-// jgen.writeStringField("groupId", groupV2.getGroupId().toBase64());
-// jgen.writeStringField("masterKey",
-// Base64.getEncoder().encodeToString(groupV2.getMasterKey().serialize()));
-// jgen.writeBooleanField("blocked", groupV2.isBlocked());
-// jgen.writeEndObject();
-// } else {
-// throw new AssertionError("Unknown group version");
-// }
-// }
-// jgen.writeEndArray();
-// }
-// }
-//
private static class GroupsDeserializer extends JsonDeserializer<List<Storage.Group>> {
@Override