]> nmode's Git Repositories - signal-cli/commitdiff
Don't repeatedly try to refetch group info if permission was denied
authorAsamK <asamk@gmx.de>
Sat, 2 Oct 2021 16:40:36 +0000 (18:40 +0200)
committerAsamK <asamk@gmx.de>
Sat, 2 Oct 2021 16:40:36 +0000 (18:40 +0200)
i.e. if the user is no longer a member of that group

lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java
lib/src/main/java/org/asamk/signal/manager/helper/GroupV2Helper.java
lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java
lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupStore.java

index 3ddd6eddeaf942b783d2927170c89044c72687ca..62f4f11134b7169f747c24a522129c08e708c570 100644 (file)
@@ -145,7 +145,10 @@ public class GroupHelper {
                         groupMasterKey);
             }
             if (group == null) {
                         groupMasterKey);
             }
             if (group == null) {
-                group = groupV2Helper.getDecryptedGroup(groupSecretParams);
+                try {
+                    group = groupV2Helper.getDecryptedGroup(groupSecretParams);
+                } catch (NotAGroupMemberException ignored) {
+                }
             }
             if (group != null) {
                 storeProfileKeysFromMembers(group);
             }
             if (group != null) {
                 storeProfileKeysFromMembers(group);
@@ -348,10 +351,20 @@ public class GroupHelper {
 
     private GroupInfo getGroup(GroupId groupId, boolean forceUpdate) {
         final var group = account.getGroupStore().getGroup(groupId);
 
     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;
     }
         }
         return group;
     }
index 3187fca1877c0a934bc324ff2a8a0c272ab0d120..746af2f91ecc9f5bd3d93b9aa77e2dd09261e779 100644 (file)
@@ -6,6 +6,7 @@ import org.asamk.signal.manager.groups.GroupLinkPassword;
 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.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.asamk.signal.manager.storage.groups.GroupInfoV2;
 import org.asamk.signal.manager.storage.recipients.Profile;
 import org.asamk.signal.manager.storage.recipients.RecipientId;
@@ -35,6 +36,7 @@ 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 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;
 import org.whispersystems.signalservice.api.util.UuidUtil;
 
 import java.io.File;
@@ -78,10 +80,16 @@ public class GroupV2Helper {
         this.addressResolver = addressResolver;
     }
 
         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);
         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;
         } catch (IOException | VerificationFailedException | InvalidGroupStateException e) {
             logger.warn("Failed to retrieve Group V2 info, ignoring: {}", e.getMessage());
             return null;
index f86dcb047234570ffc62859067bfdadaad469e67..a06b83dfa3203d064533266429c1d92dcfac91ee 100644 (file)
@@ -22,16 +22,23 @@ public class GroupInfoV2 extends GroupInfo {
     private boolean blocked;
     private DecryptedGroup group; // stored as a file with hexadecimal groupId as name
     private RecipientResolver recipientResolver;
     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) {
         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.groupId = groupId;
         this.masterKey = masterKey;
         this.blocked = blocked;
+        this.permissionDenied = permissionDenied;
     }
 
     @Override
     }
 
     @Override
@@ -44,6 +51,9 @@ public class GroupInfoV2 extends GroupInfo {
     }
 
     public void setGroup(final DecryptedGroup group, final RecipientResolver recipientResolver) {
     }
 
     public void setGroup(final DecryptedGroup group, final RecipientResolver recipientResolver) {
+        if (group != null) {
+            this.permissionDenied = false;
+        }
         this.group = group;
         this.recipientResolver = recipientResolver;
     }
         this.group = group;
         this.recipientResolver = recipientResolver;
     }
@@ -151,4 +161,12 @@ public class GroupInfoV2 extends GroupInfo {
     public boolean isAnnouncementGroup() {
         return this.group != null && this.group.getIsAnnouncementGroup() == EnabledState.ENABLED;
     }
     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;
+    }
 }
 }
index 4adc413ad07a32fbb0b4bf9d4daeccb6eedbd580..fe8f85a6740184ef49002803b15deadd57176740 100644 (file)
@@ -104,7 +104,7 @@ public class GroupStore {
                 throw new AssertionError("Invalid master key for group " + groupId.toBase64());
             }
 
                 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);
         }).collect(Collectors.toMap(GroupInfo::getGroupId, g -> g));
 
         return new GroupStore(groupCachePath, groups, recipientResolver, saver);
@@ -268,13 +268,13 @@ public class GroupStore {
             final var g2 = (GroupInfoV2) g;
             return new Storage.GroupV2(g2.getGroupId().toBase64(),
                     Base64.getEncoder().encodeToString(g2.getMasterKey().serialize()),
             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 {
 
         }).collect(Collectors.toList()));
     }
 
     public static class Storage {
 
-        //        @JsonSerialize(using = GroupsSerializer.class)
         @JsonDeserialize(using = GroupsDeserializer.class)
         public List<Storage.Group> groups;
 
         @JsonDeserialize(using = GroupsDeserializer.class)
         public List<Storage.Group> groups;
 
@@ -408,46 +408,24 @@ public class GroupStore {
             public String groupId;
             public String masterKey;
             public boolean blocked;
             public String groupId;
             public String masterKey;
             public boolean blocked;
+            public boolean permissionDenied;
 
             // For deserialization
             private GroupV2() {
             }
 
 
             // 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.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
     private static class GroupsDeserializer extends JsonDeserializer<List<Storage.Group>> {
 
         @Override