]> nmode's Git Repositories - signal-cli/blobdiff - lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java
Rotate profile key after blocking a contact/group
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / ManagerImpl.java
index fa041c55d4898666b01d7b05cfa5064e772f4c38..b3e6a0ae7b02461943d1bb7e996197bcba2ce851 100644 (file)
@@ -38,6 +38,7 @@ import org.asamk.signal.manager.api.StickerPackUrl;
 import org.asamk.signal.manager.api.TypingAction;
 import org.asamk.signal.manager.api.UnregisteredRecipientException;
 import org.asamk.signal.manager.api.UpdateGroup;
+import org.asamk.signal.manager.api.UserStatus;
 import org.asamk.signal.manager.config.ServiceEnvironmentConfig;
 import org.asamk.signal.manager.groups.GroupId;
 import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
@@ -78,13 +79,13 @@ import java.io.IOException;
 import java.net.URI;
 import java.time.Duration;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
-import java.util.UUID;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -190,7 +191,7 @@ class ManagerImpl implements Manager {
     }
 
     @Override
-    public Map<String, Pair<String, UUID>> areUsersRegistered(Set<String> numbers) throws IOException {
+    public Map<String, UserStatus> getUserStatus(Set<String> numbers) throws IOException {
         final var canonicalizedNumbers = numbers.stream().collect(Collectors.toMap(n -> n, n -> {
             try {
                 final var canonicalizedNumber = PhoneNumberFormatter.formatNumber(n, account.getNumber());
@@ -213,7 +214,13 @@ class ManagerImpl implements Manager {
         return numbers.stream().collect(Collectors.toMap(n -> n, n -> {
             final var number = canonicalizedNumbers.get(n);
             final var aci = registeredUsers.get(number);
-            return new Pair<>(number.isEmpty() ? null : number, aci == null ? null : aci.uuid());
+            final var profile = aci == null
+                    ? null
+                    : context.getProfileHelper().getRecipientProfile(account.getRecipientStore().resolveRecipient(aci));
+            return new UserStatus(number.isEmpty() ? null : number,
+                    aci == null ? null : aci.uuid(),
+                    profile != null
+                            && profile.getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.UNRESTRICTED);
         }));
     }
 
@@ -677,26 +684,58 @@ class ManagerImpl implements Manager {
     }
 
     @Override
-    public void setContactBlocked(
-            RecipientIdentifier.Single recipient, boolean blocked
+    public void setContactsBlocked(
+            Collection<RecipientIdentifier.Single> recipients, boolean blocked
     ) throws NotMasterDeviceException, IOException, UnregisteredRecipientException {
         if (!account.isMasterDevice()) {
             throw new NotMasterDeviceException();
         }
-        context.getContactHelper().setContactBlocked(context.getRecipientHelper().resolveRecipient(recipient), blocked);
-        // TODO cycle our profile key, if we're not together in a group with recipient
+        if (recipients.size() == 0) {
+            return;
+        }
+        final var recipientIds = context.getRecipientHelper().resolveRecipients(recipients);
+        final var selfRecipientId = account.getSelfRecipientId();
+        boolean shouldRotateProfileKey = false;
+        for (final var recipientId : recipientIds) {
+            if (context.getContactHelper().isContactBlocked(recipientId) == blocked) {
+                continue;
+            }
+            context.getContactHelper().setContactBlocked(recipientId, blocked);
+            // if we don't have a common group with the blocked contact we need to rotate the profile key
+            shouldRotateProfileKey = blocked && (
+                    shouldRotateProfileKey || account.getGroupStore()
+                            .getGroups()
+                            .stream()
+                            .noneMatch(g -> g.isMember(selfRecipientId) && g.isMember(recipientId))
+            );
+        }
+        if (shouldRotateProfileKey) {
+            context.getProfileHelper().rotateProfileKey();
+        }
         context.getSyncHelper().sendBlockedList();
     }
 
     @Override
-    public void setGroupBlocked(
-            final GroupId groupId, final boolean blocked
-    ) throws GroupNotFoundException, NotMasterDeviceException {
+    public void setGroupsBlocked(
+            final Collection<GroupId> groupIds, final boolean blocked
+    ) throws GroupNotFoundException, NotMasterDeviceException, IOException {
         if (!account.isMasterDevice()) {
             throw new NotMasterDeviceException();
         }
-        context.getGroupHelper().setGroupBlocked(groupId, blocked);
-        // TODO cycle our profile key
+        if (groupIds.size() == 0) {
+            return;
+        }
+        boolean shouldRotateProfileKey = false;
+        for (final var groupId : groupIds) {
+            if (context.getGroupHelper().isGroupBlocked(groupId) == blocked) {
+                continue;
+            }
+            context.getGroupHelper().setGroupBlocked(groupId, blocked);
+            shouldRotateProfileKey = blocked;
+        }
+        if (shouldRotateProfileKey) {
+            context.getProfileHelper().rotateProfileKey();
+        }
         context.getSyncHelper().sendBlockedList();
     }