X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/2f9873c35ec08f35e24a2b5f35e23f6c704c8773..2c5a70cc47301bf0f049eb2633976460d3ced1b7:/src/main/java/org/asamk/signal/manager/Manager.java diff --git a/src/main/java/org/asamk/signal/manager/Manager.java b/src/main/java/org/asamk/signal/manager/Manager.java index 9515a2fd..851b7820 100644 --- a/src/main/java/org/asamk/signal/manager/Manager.java +++ b/src/main/java/org/asamk/signal/manager/Manager.java @@ -38,7 +38,6 @@ import org.signal.libsignal.metadata.ProtocolUntrustedIdentityException; import org.signal.libsignal.metadata.SelfSendException; import org.signal.libsignal.metadata.certificate.InvalidCertificateException; import org.signal.zkgroup.InvalidInputException; -import org.signal.zkgroup.VerificationFailedException; import org.signal.zkgroup.profiles.ClientZkProfileOperations; import org.signal.zkgroup.profiles.ProfileKey; import org.whispersystems.libsignal.IdentityKey; @@ -135,6 +134,8 @@ import java.util.Locale; import java.util.Objects; import java.util.Set; import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; @@ -288,18 +289,10 @@ public class Manager implements Closeable { accountManager.setAccountAttributes(account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, account.getRegistrationLockPin(), account.getRegistrationLock(), getSelfUnidentifiedAccessKey(), false, ServiceConfig.capabilities); } - public void setProfileName(String name) throws IOException { - accountManager.setProfileName(account.getProfileKey(), name); - } - - public void setProfileAvatar(File avatar) throws IOException { - final StreamDetails streamDetails = Utils.createStreamDetailsFromFile(avatar); - accountManager.setProfileAvatar(account.getProfileKey(), streamDetails); - streamDetails.getStream().close(); - } - - public void removeProfileAvatar() throws IOException { - accountManager.setProfileAvatar(account.getProfileKey(), null); + public void setProfile(String name, File avatar) throws IOException { + try (final StreamDetails streamDetails = avatar == null ? null : Utils.createStreamDetailsFromFile(avatar)) { + accountManager.setVersionedProfile(account.getUuid(), account.getProfileKey(), name, streamDetails); + } } public void unregister() throws IOException { @@ -421,29 +414,34 @@ public class Manager implements Closeable { // TODO implement ZkGroup support final ClientZkProfileOperations clientZkProfileOperations = null; final boolean attachmentsV3 = false; + final ExecutorService executor = null; return new SignalServiceMessageSender(serviceConfiguration, account.getUuid(), account.getUsername(), account.getPassword(), - account.getDeviceId(), account.getSignalProtocolStore(), userAgent, account.isMultiDevice(), attachmentsV3, Optional.fromNullable(messagePipe), Optional.fromNullable(unidentifiedMessagePipe), Optional.absent(), clientZkProfileOperations); + account.getDeviceId(), account.getSignalProtocolStore(), userAgent, account.isMultiDevice(), attachmentsV3, Optional.fromNullable(messagePipe), Optional.fromNullable(unidentifiedMessagePipe), Optional.absent(), clientZkProfileOperations, executor); } - private SignalServiceProfile getRecipientProfile(SignalServiceAddress address, Optional unidentifiedAccess) throws IOException { + private SignalServiceProfile getEncryptedRecipientProfile(SignalServiceAddress address, Optional unidentifiedAccess) throws IOException { SignalServiceMessagePipe pipe = unidentifiedMessagePipe != null && unidentifiedAccess.isPresent() ? unidentifiedMessagePipe : messagePipe; if (pipe != null) { try { - return pipe.getProfile(address, Optional.absent(), unidentifiedAccess, SignalServiceProfile.RequestType.PROFILE).getProfile(); - } catch (IOException ignored) { + return pipe.getProfile(address, Optional.absent(), unidentifiedAccess, SignalServiceProfile.RequestType.PROFILE).get(10, TimeUnit.SECONDS).getProfile(); + } catch (IOException | InterruptedException | ExecutionException | TimeoutException ignored) { } } SignalServiceMessageReceiver receiver = getMessageReceiver(); try { - return receiver.retrieveProfile(address, Optional.absent(), unidentifiedAccess, SignalServiceProfile.RequestType.PROFILE).getProfile(); - } catch (VerificationFailedException e) { - throw new AssertionError(e); + return receiver.retrieveProfile(address, Optional.absent(), unidentifiedAccess, SignalServiceProfile.RequestType.PROFILE).get(10, TimeUnit.SECONDS).getProfile(); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + throw new IOException("Failed to retrieve profile", e); } } + private SignalProfile getRecipientProfile(SignalServiceAddress address, Optional unidentifiedAccess, ProfileKey profileKey) throws IOException { + return decryptProfile(getEncryptedRecipientProfile(address, unidentifiedAccess), profileKey); + } + private Optional createGroupAvatarAttachment(byte[] groupId) throws IOException { File file = getGroupAvatarFile(groupId); if (!file.exists()) { @@ -558,9 +556,7 @@ public class Manager implements Closeable { for (ContactTokenDetails contact : contacts) { newE164Members.remove(contact.getNumber()); } - System.err.println("Failed to add members " + Util.join(", ", newE164Members) + " to group: Not registered on Signal"); - System.err.println("Aborting…"); - System.exit(1); + throw new IOException("Failed to add members " + Util.join(", ", newE164Members) + " to group: Not registered on Signal"); } g.addMembers(members); @@ -701,9 +697,6 @@ public class Manager implements Closeable { ContactInfo contact = account.getContactStore().getContact(address); if (contact == null) { contact = new ContactInfo(address); - System.err.println("Add contact " + contact.number + " named " + name); - } else { - System.err.println("Updating contact " + contact.number + " name " + contact.name + " -> " + name); } contact.name = name; account.getContactStore().updateContact(contact); @@ -718,9 +711,6 @@ public class Manager implements Closeable { ContactInfo contact = account.getContactStore().getContact(address); if (contact == null) { contact = new ContactInfo(address); - System.err.println("Adding and " + (blocked ? "blocking" : "unblocking") + " contact " + address.getNumber().orNull()); - } else { - System.err.println((blocked ? "Blocking" : "Unblocking") + " contact " + address.getNumber().orNull()); } contact.blocked = blocked; account.getContactStore().updateContact(contact); @@ -731,12 +721,11 @@ public class Manager implements Closeable { GroupInfo group = getGroup(groupId); if (group == null) { throw new GroupNotFoundException(groupId); - } else { - System.err.println((blocked ? "Blocking" : "Unblocking") + " group " + Base64.encodeBytes(groupId)); - group.blocked = blocked; - account.getGroupStore().updateGroup(group); - account.save(); } + + group.blocked = blocked; + account.getGroupStore().updateGroup(group); + account.save(); } public byte[] updateGroup(byte[] groupId, String name, List members, String avatar) throws IOException, EncapsulatedExceptions, GroupNotFoundException, AttachmentInvalidException, InvalidNumberException, NotAGroupMemberException { @@ -980,7 +969,7 @@ public class Manager implements Closeable { } SignalProfile targetProfile; try { - targetProfile = decryptProfile(getRecipientProfile(recipient, Optional.absent()), theirProfileKey); + targetProfile = getRecipientProfile(recipient, Optional.absent(), theirProfileKey); } catch (IOException e) { System.err.println("Failed to get recipient profile: " + e); return null;