]> nmode's Git Repositories - signal-cli/blobdiff - lib/src/main/java/org/asamk/signal/manager/helper/AttachmentHelper.java
Update libsignal-service-java
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / helper / AttachmentHelper.java
index 4944c7b328a297d4b933536d808ef6347becdf88..08526c726ac33747f2952677a8edf0a2a799a5e0 100644 (file)
@@ -1,18 +1,20 @@
 package org.asamk.signal.manager.helper;
 
-import org.asamk.signal.manager.AttachmentInvalidException;
-import org.asamk.signal.manager.AttachmentStore;
-import org.asamk.signal.manager.SignalDependencies;
+import org.asamk.signal.manager.api.AttachmentInvalidException;
 import org.asamk.signal.manager.config.ServiceConfig;
+import org.asamk.signal.manager.internal.SignalDependencies;
+import org.asamk.signal.manager.storage.AttachmentStore;
 import org.asamk.signal.manager.util.AttachmentUtils;
 import org.asamk.signal.manager.util.IOUtils;
+import org.signal.libsignal.protocol.InvalidMessageException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.whispersystems.libsignal.InvalidMessageException;
+import org.whispersystems.signalservice.api.crypto.AttachmentCipherInputStream;
 import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
 import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
-import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentRemoteId;
+import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
 import org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException;
+import org.whispersystems.signalservice.api.util.StreamDetails;
 
 import java.io.File;
 import java.io.IOException;
@@ -24,36 +26,62 @@ import java.util.List;
 
 public class AttachmentHelper {
 
-    private final static Logger logger = LoggerFactory.getLogger(AttachmentHelper.class);
+    private static final Logger logger = LoggerFactory.getLogger(AttachmentHelper.class);
 
     private final SignalDependencies dependencies;
     private final AttachmentStore attachmentStore;
 
-    public AttachmentHelper(
-            final SignalDependencies dependencies, final AttachmentStore attachmentStore
-    ) {
-        this.dependencies = dependencies;
-        this.attachmentStore = attachmentStore;
+    public AttachmentHelper(final Context context) {
+        this.dependencies = context.getDependencies();
+        this.attachmentStore = context.getAttachmentStore();
     }
 
-    public File getAttachmentFile(SignalServiceAttachmentRemoteId attachmentId) {
-        return attachmentStore.getAttachmentFile(attachmentId);
+    public File getAttachmentFile(SignalServiceAttachmentPointer pointer) {
+        return attachmentStore.getAttachmentFile(pointer);
+    }
+
+    public StreamDetails retrieveAttachment(final String id) throws IOException {
+        return attachmentStore.retrieveAttachment(id);
     }
 
     public List<SignalServiceAttachment> uploadAttachments(final List<String> attachments) throws AttachmentInvalidException, IOException {
-        var attachmentStreams = AttachmentUtils.getSignalServiceAttachments(attachments);
+        final var attachmentStreams = createAttachmentStreams(attachments);
 
-        // Upload attachments here, so we only upload once even for multiple recipients
-        var messageSender = dependencies.getMessageSender();
-        var attachmentPointers = new ArrayList<SignalServiceAttachment>(attachmentStreams.size());
-        for (var attachment : attachmentStreams) {
-            if (attachment.isStream()) {
-                attachmentPointers.add(messageSender.uploadAttachment(attachment.asStream()));
-            } else if (attachment.isPointer()) {
-                attachmentPointers.add(attachment.asPointer());
+        try {
+            // Upload attachments here, so we only upload once even for multiple recipients
+            final var attachmentPointers = new ArrayList<SignalServiceAttachment>(attachmentStreams.size());
+            for (final var attachmentStream : attachmentStreams) {
+                attachmentPointers.add(uploadAttachment(attachmentStream));
+            }
+            return attachmentPointers;
+        } finally {
+            for (final var attachmentStream : attachmentStreams) {
+                attachmentStream.close();
             }
         }
-        return attachmentPointers;
+    }
+
+    private List<SignalServiceAttachmentStream> createAttachmentStreams(List<String> attachments) throws AttachmentInvalidException, IOException {
+        if (attachments == null) {
+            return null;
+        }
+        final var signalServiceAttachments = new ArrayList<SignalServiceAttachmentStream>(attachments.size());
+        for (var attachment : attachments) {
+            final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec();
+            signalServiceAttachments.add(AttachmentUtils.createAttachmentStream(attachment, uploadSpec));
+        }
+        return signalServiceAttachments;
+    }
+
+    public SignalServiceAttachmentPointer uploadAttachment(String attachment) throws IOException, AttachmentInvalidException {
+        final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec();
+        var attachmentStream = AttachmentUtils.createAttachmentStream(attachment, uploadSpec);
+        return uploadAttachment(attachmentStream);
+    }
+
+    public SignalServiceAttachmentPointer uploadAttachment(SignalServiceAttachmentStream attachment) throws IOException {
+        var messageSender = dependencies.getMessageSender();
+        return messageSender.uploadAttachment(attachment);
     }
 
     public void downloadAttachment(final SignalServiceAttachment attachment) {
@@ -65,7 +93,7 @@ public class AttachmentHelper {
         if (pointer.getPreview().isPresent()) {
             final var preview = pointer.getPreview().get();
             try {
-                attachmentStore.storeAttachmentPreview(pointer.getRemoteId(),
+                attachmentStore.storeAttachmentPreview(pointer,
                         outputStream -> outputStream.write(preview, 0, preview.length));
             } catch (IOException e) {
                 logger.warn("Failed to download attachment preview, ignoring: {}", e.getMessage());
@@ -73,8 +101,7 @@ public class AttachmentHelper {
         }
 
         try {
-            attachmentStore.storeAttachment(pointer.getRemoteId(),
-                    outputStream -> this.retrieveAttachment(pointer, outputStream));
+            attachmentStore.storeAttachment(pointer, outputStream -> this.retrieveAttachment(pointer, outputStream));
         } catch (IOException e) {
             logger.warn("Failed to download attachment ({}), ignoring: {}", pointer.getRemoteId(), e.getMessage());
         }
@@ -84,9 +111,7 @@ public class AttachmentHelper {
         retrieveAttachment(attachment, input -> IOUtils.copyStream(input, outputStream));
     }
 
-    public void retrieveAttachment(
-            SignalServiceAttachment attachment, AttachmentHandler consumer
-    ) throws IOException {
+    public void retrieveAttachment(SignalServiceAttachment attachment, AttachmentHandler consumer) throws IOException {
         if (attachment.isStream()) {
             var input = attachment.asStream().getInputStream();
             // don't close input stream here, it might be reused later (e.g. with contact sync messages ...)
@@ -111,11 +136,18 @@ public class AttachmentHelper {
     }
 
     private InputStream retrieveAttachmentAsStream(
-            SignalServiceAttachmentPointer pointer, File tmpFile
+            SignalServiceAttachmentPointer pointer,
+            File tmpFile
     ) throws IOException {
+        if (pointer.getDigest().isEmpty()) {
+            throw new IOException("Attachment pointer has no digest.");
+        }
         try {
             return dependencies.getMessageReceiver()
-                    .retrieveAttachment(pointer, tmpFile, ServiceConfig.MAX_ATTACHMENT_SIZE);
+                    .retrieveAttachment(pointer,
+                            tmpFile,
+                            ServiceConfig.MAX_ATTACHMENT_SIZE,
+                            AttachmentCipherInputStream.IntegrityCheck.forEncryptedDigest(pointer.getDigest().get()));
         } catch (MissingConfigurationException | InvalidMessageException e) {
             throw new IOException(e);
         }