From: AsamK Date: Sat, 8 Oct 2022 15:41:42 +0000 (+0200) Subject: Refactor resolve recipient X-Git-Tag: v0.11.4~17 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/51fef480164562c0225285eea9cd3ede29d2505e?ds=sidebyside Refactor resolve recipient --- diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java b/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java index 880089e7..85e5cadd 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java @@ -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, final Optional pni, final Optional number - ) { - return getRecipientStore().resolveRecipientTrusted(aci, pni, number); - } - }; + return new RecipientTrustedResolver.RecipientTrustedResolverWrapper(this::getRecipientStore); } public RecipientAddressResolver getRecipientAddressResolver() { diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientResolver.java b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientResolver.java index 85ece822..00c532f2 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientResolver.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientResolver.java @@ -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 recipientResolverSupplier; + + public RecipientResolverWrapper(final Supplier 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); + } } } diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java index f932d497..1b601980 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java @@ -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, final Optional pni, final Optional 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> 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> resolveRecipientLocked( - Connection connection, RecipientAddress address, boolean isHighTrust, boolean isSelf + private Pair> 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.empty() + : findByServiceId(connection, address.serviceId().get()); + + if (byServiceId.isPresent()) { + return byServiceId.get().id(); + } + + final var byPni = address.pni().isEmpty() + ? Optional.empty() + : findByServiceId(connection, address.pni().get()); + + if (byPni.isPresent()) { + return byPni.get().id(); + } + + final var byNumber = address.number().isEmpty() + ? Optional.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 { diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientTrustedResolver.java b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientTrustedResolver.java index 5020caf3..38949c64 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientTrustedResolver.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientTrustedResolver.java @@ -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, Optional pni, Optional number); + + class RecipientTrustedResolverWrapper implements RecipientTrustedResolver { + + private final Supplier recipientTrustedResolverSupplier; + + public RecipientTrustedResolverWrapper(final Supplier 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, final Optional pni, final Optional number + ) { + return recipientTrustedResolverSupplier.get().resolveRecipientTrusted(aci, pni, number); + } + } }