]> nmode's Git Repositories - signal-cli/commitdiff
Refactor resolve recipient
authorAsamK <asamk@gmx.de>
Sat, 8 Oct 2022 15:41:42 +0000 (17:41 +0200)
committerAsamK <asamk@gmx.de>
Sat, 8 Oct 2022 15:42:03 +0000 (17:42 +0200)
lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java
lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientResolver.java
lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java
lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientTrustedResolver.java

index 880089e7e9328d68b38fac550c370fc1e36ae924..85e5cadd032ed8859536fe5f0c81324f1bebdc6f 100644 (file)
@@ -1179,38 +1179,11 @@ public class SignalAccount implements Closeable {
     }
 
     public RecipientResolver getRecipientResolver() {
-        return new RecipientResolver() {
-            @Override
-            public RecipientId resolveRecipient(final RecipientAddress address) {
-                return getRecipientStore().resolveRecipient(address);
-            }
-
-            @Override
-            public RecipientId resolveRecipient(final long recipientId) {
-                return getRecipientStore().resolveRecipient(recipientId);
-            }
-        };
+        return new RecipientResolver.RecipientResolverWrapper(this::getRecipientStore);
     }
 
     public RecipientTrustedResolver getRecipientTrustedResolver() {
-        return new RecipientTrustedResolver() {
-            @Override
-            public RecipientId resolveSelfRecipientTrusted(final RecipientAddress address) {
-                return getRecipientStore().resolveSelfRecipientTrusted(address);
-            }
-
-            @Override
-            public RecipientId resolveRecipientTrusted(final SignalServiceAddress address) {
-                return getRecipientStore().resolveRecipientTrusted(address);
-            }
-
-            @Override
-            public RecipientId resolveRecipientTrusted(
-                    final Optional<ACI> aci, final Optional<PNI> pni, final Optional<String> number
-            ) {
-                return getRecipientStore().resolveRecipientTrusted(aci, pni, number);
-            }
-        };
+        return new RecipientTrustedResolver.RecipientTrustedResolverWrapper(this::getRecipientStore);
     }
 
     public RecipientAddressResolver getRecipientAddressResolver() {
index 85ece822b821ca9954041d0a43b3f4349d65543a..00c532f20e13daf0248c6078a436d94777345869 100644 (file)
@@ -1,24 +1,50 @@
 package org.asamk.signal.manager.storage.recipients;
 
-import org.asamk.signal.manager.storage.Utils;
 import org.whispersystems.signalservice.api.push.ServiceId;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 
+import java.util.function.Supplier;
+
 public interface RecipientResolver {
 
     RecipientId resolveRecipient(RecipientAddress address);
 
     RecipientId resolveRecipient(long recipientId);
 
-    default RecipientId resolveRecipient(String identifier) {
-        return resolveRecipient(Utils.getRecipientAddressFromIdentifier(identifier));
-    }
+    RecipientId resolveRecipient(String identifier);
 
     default RecipientId resolveRecipient(SignalServiceAddress address) {
         return resolveRecipient(new RecipientAddress(address));
     }
 
-    default RecipientId resolveRecipient(ServiceId serviceId) {
-        return resolveRecipient(new RecipientAddress(serviceId));
+    RecipientId resolveRecipient(ServiceId serviceId);
+
+    class RecipientResolverWrapper implements RecipientResolver {
+
+        private final Supplier<RecipientResolver> recipientResolverSupplier;
+
+        public RecipientResolverWrapper(final Supplier<RecipientResolver> recipientResolverSupplier) {
+            this.recipientResolverSupplier = recipientResolverSupplier;
+        }
+
+        @Override
+        public RecipientId resolveRecipient(final RecipientAddress address) {
+            return recipientResolverSupplier.get().resolveRecipient(address);
+        }
+
+        @Override
+        public RecipientId resolveRecipient(final long recipientId) {
+            return recipientResolverSupplier.get().resolveRecipient(recipientId);
+        }
+
+        @Override
+        public RecipientId resolveRecipient(final String identifier) {
+            return recipientResolverSupplier.get().resolveRecipient(identifier);
+        }
+
+        @Override
+        public RecipientId resolveRecipient(final ServiceId serviceId) {
+            return recipientResolverSupplier.get().resolveRecipient(serviceId);
+        }
     }
 }
index f932d49727ff720be2b28c7c285c68750e643ebd..1b6019803d135308600d2c7f45b4a943af42a89c 100644 (file)
@@ -145,6 +145,44 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
         }
     }
 
+    @Override
+    public RecipientId resolveRecipient(final String identifier) {
+        if (UuidUtil.isUuid(identifier)) {
+            return resolveRecipient(ServiceId.parseOrThrow(identifier));
+        } else {
+            return resolveRecipientByNumber(identifier);
+        }
+    }
+
+    private RecipientId resolveRecipientByNumber(final String number) {
+        synchronized (recipientsLock) {
+            final RecipientId recipientId;
+            try (final var connection = database.getConnection()) {
+                connection.setAutoCommit(false);
+                recipientId = resolveRecipientLocked(connection, number);
+                connection.commit();
+            } catch (SQLException e) {
+                throw new RuntimeException("Failed read recipient store", e);
+            }
+            return recipientId;
+        }
+    }
+
+    @Override
+    public RecipientId resolveRecipient(final ServiceId serviceId) {
+        synchronized (recipientsLock) {
+            final RecipientId recipientId;
+            try (final var connection = database.getConnection()) {
+                connection.setAutoCommit(false);
+                recipientId = resolveRecipientLocked(connection, serviceId);
+                connection.commit();
+            } catch (SQLException e) {
+                throw new RuntimeException("Failed read recipient store", e);
+            }
+            return recipientId;
+        }
+    }
+
     /**
      * Should only be used for recipientIds from the database.
      * Where the foreign key relations ensure a valid recipientId.
@@ -170,27 +208,37 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
                         number));
             }
 
-            return resolveRecipient(new RecipientAddress(serviceId, number), false, false);
+            return resolveRecipient(serviceId);
         }
         return byNumber.get().id();
     }
 
     public RecipientId resolveRecipient(RecipientAddress address) {
-        return resolveRecipient(address, false, false);
+        synchronized (recipientsLock) {
+            final RecipientId recipientId;
+            try (final var connection = database.getConnection()) {
+                connection.setAutoCommit(false);
+                recipientId = resolveRecipientLocked(connection, address);
+                connection.commit();
+            } catch (SQLException e) {
+                throw new RuntimeException("Failed read recipient store", e);
+            }
+            return recipientId;
+        }
     }
 
     @Override
     public RecipientId resolveSelfRecipientTrusted(RecipientAddress address) {
-        return resolveRecipient(address, true, true);
+        return resolveRecipientTrusted(address, true);
     }
 
     public RecipientId resolveRecipientTrusted(RecipientAddress address) {
-        return resolveRecipient(address, true, false);
+        return resolveRecipientTrusted(address, false);
     }
 
     @Override
     public RecipientId resolveRecipientTrusted(SignalServiceAddress address) {
-        return resolveRecipient(new RecipientAddress(address), true, false);
+        return resolveRecipientTrusted(new RecipientAddress(address), false);
     }
 
     @Override
@@ -198,7 +246,7 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
             final Optional<ACI> aci, final Optional<PNI> pni, final Optional<String> number
     ) {
         final var serviceId = aci.map(a -> (ServiceId) a).or(() -> pni);
-        return resolveRecipient(new RecipientAddress(serviceId, number), true, false);
+        return resolveRecipientTrusted(new RecipientAddress(serviceId, number), false);
     }
 
     @Override
@@ -552,16 +600,12 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
         }
     }
 
-    /**
-     * @param isHighTrust true, if the number/uuid connection was obtained from a trusted source.
-     *                    Has no effect, if the address contains only a number or a uuid.
-     */
-    private RecipientId resolveRecipient(RecipientAddress address, boolean isHighTrust, boolean isSelf) {
+    private RecipientId resolveRecipientTrusted(RecipientAddress address, boolean isSelf) {
         final Pair<RecipientId, Optional<RecipientId>> pair;
         synchronized (recipientsLock) {
             try (final var connection = database.getConnection()) {
                 connection.setAutoCommit(false);
-                pair = resolveRecipientLocked(connection, address, isHighTrust, isSelf);
+                pair = resolveRecipientTrustedLocked(connection, address, isSelf);
                 connection.commit();
             } catch (SQLException e) {
                 throw new RuntimeException("Failed update recipient store", e);
@@ -579,12 +623,12 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
         return pair.first();
     }
 
-    private Pair<RecipientId, Optional<RecipientId>> resolveRecipientLocked(
-            Connection connection, RecipientAddress address, boolean isHighTrust, boolean isSelf
+    private Pair<RecipientId, Optional<RecipientId>> resolveRecipientTrustedLocked(
+            Connection connection, RecipientAddress address, boolean isSelf
     ) throws SQLException {
-        if (isHighTrust && !isSelf) {
+        if (!isSelf) {
             if (selfAddressProvider.getSelfAddress().matches(address)) {
-                isHighTrust = false;
+                return new Pair<>(resolveRecipientLocked(connection, address), Optional.empty());
             }
         }
         final var byNumber = address.number().isEmpty()
@@ -596,16 +640,10 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
 
         if (byNumber.isEmpty() && byUuid.isEmpty()) {
             logger.debug("Got new recipient, both uuid and number are unknown");
-
-            if (isHighTrust || address.serviceId().isEmpty() || address.number().isEmpty()) {
-                return new Pair<>(addNewRecipient(connection, address), Optional.empty());
-            }
-
-            return new Pair<>(addNewRecipient(connection, new RecipientAddress(address.serviceId().get())),
-                    Optional.empty());
+            return new Pair<>(addNewRecipient(connection, address), Optional.empty());
         }
 
-        if (!isHighTrust || address.serviceId().isEmpty() || address.number().isEmpty() || byNumber.equals(byUuid)) {
+        if (address.serviceId().isEmpty() || address.number().isEmpty() || byNumber.equals(byUuid)) {
             return new Pair<>(byUuid.or(() -> byNumber).map(RecipientWithAddress::id).get(), Optional.empty());
         }
 
@@ -661,6 +699,64 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
         return new Pair<>(byUuidRecipient.id(), Optional.of(toBeMergedRecipientId));
     }
 
+    private RecipientId resolveRecipientLocked(
+            Connection connection, RecipientAddress address
+    ) throws SQLException {
+        final var byServiceId = address.serviceId().isEmpty()
+                ? Optional.<RecipientWithAddress>empty()
+                : findByServiceId(connection, address.serviceId().get());
+
+        if (byServiceId.isPresent()) {
+            return byServiceId.get().id();
+        }
+
+        final var byPni = address.pni().isEmpty()
+                ? Optional.<RecipientWithAddress>empty()
+                : findByServiceId(connection, address.pni().get());
+
+        if (byPni.isPresent()) {
+            return byPni.get().id();
+        }
+
+        final var byNumber = address.number().isEmpty()
+                ? Optional.<RecipientWithAddress>empty()
+                : findByNumber(connection, address.number().get());
+
+        if (byNumber.isPresent()) {
+            return byNumber.get().id();
+        }
+
+        logger.debug("Got new recipient, both serviceId and number are unknown");
+
+        if (address.serviceId().isEmpty()) {
+            return addNewRecipient(connection, address);
+        }
+
+        return addNewRecipient(connection, new RecipientAddress(address.serviceId().get()));
+    }
+
+    private RecipientId resolveRecipientLocked(Connection connection, ServiceId serviceId) throws SQLException {
+        final var recipient = findByServiceId(connection, serviceId);
+
+        if (recipient.isEmpty()) {
+            logger.debug("Got new recipient, serviceId is unknown");
+            return addNewRecipient(connection, new RecipientAddress(serviceId));
+        }
+
+        return recipient.get().id();
+    }
+
+    private RecipientId resolveRecipientLocked(Connection connection, String number) throws SQLException {
+        final var recipient = findByNumber(connection, number);
+
+        if (recipient.isEmpty()) {
+            logger.debug("Got new recipient, number is unknown");
+            return addNewRecipient(connection, new RecipientAddress(null, number));
+        }
+
+        return recipient.get().id();
+    }
+
     private RecipientId addNewRecipient(
             final Connection connection, final RecipientAddress address
     ) throws SQLException {
index 5020caf3f1106b05ae4a907046b8bd41a96cd1b9..38949c64da18942c64f5cc01e8eba787db850238 100644 (file)
@@ -5,6 +5,7 @@ import org.whispersystems.signalservice.api.push.PNI;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 
 import java.util.Optional;
+import java.util.function.Supplier;
 
 public interface RecipientTrustedResolver {
 
@@ -13,4 +14,30 @@ public interface RecipientTrustedResolver {
     RecipientId resolveRecipientTrusted(SignalServiceAddress address);
 
     RecipientId resolveRecipientTrusted(Optional<ACI> aci, Optional<PNI> pni, Optional<String> number);
+
+    class RecipientTrustedResolverWrapper implements RecipientTrustedResolver {
+
+        private final Supplier<RecipientTrustedResolver> recipientTrustedResolverSupplier;
+
+        public RecipientTrustedResolverWrapper(final Supplier<RecipientTrustedResolver> recipientTrustedResolverSupplier) {
+            this.recipientTrustedResolverSupplier = recipientTrustedResolverSupplier;
+        }
+
+        @Override
+        public RecipientId resolveSelfRecipientTrusted(final RecipientAddress address) {
+            return recipientTrustedResolverSupplier.get().resolveSelfRecipientTrusted(address);
+        }
+
+        @Override
+        public RecipientId resolveRecipientTrusted(final SignalServiceAddress address) {
+            return recipientTrustedResolverSupplier.get().resolveRecipientTrusted(address);
+        }
+
+        @Override
+        public RecipientId resolveRecipientTrusted(
+                final Optional<ACI> aci, final Optional<PNI> pni, final Optional<String> number
+        ) {
+            return recipientTrustedResolverSupplier.get().resolveRecipientTrusted(aci, pni, number);
+        }
+    }
 }