Added base64 encoded attachment support

This commit is contained in:
Kevin R 2022-06-03 00:08:20 +02:00
parent 63e94a9fb4
commit ed8793f354
No known key found for this signature in database
GPG key ID: A4AD5E0732960C98
4 changed files with 47 additions and 7 deletions

View file

@ -51,7 +51,7 @@ public class AttachmentHelper {
}
public SignalServiceAttachmentPointer uploadAttachment(String attachment) throws IOException, AttachmentInvalidException {
var attachmentStream = AttachmentUtils.createAttachmentStream(new File(attachment));
var attachmentStream = AttachmentUtils.createAttachmentStream(attachment);
return uploadAttachment(attachmentStream);
}

View file

@ -6,6 +6,7 @@ import org.whispersystems.signalservice.api.util.StreamDetails;
import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -19,17 +20,21 @@ public class AttachmentUtils {
}
final var signalServiceAttachments = new ArrayList<SignalServiceAttachmentStream>(attachments.size());
for (var attachment : attachments) {
signalServiceAttachments.add(createAttachmentStream(new File(attachment)));
signalServiceAttachments.add(createAttachmentStream(attachment));
}
return signalServiceAttachments;
}
public static SignalServiceAttachmentStream createAttachmentStream(File attachmentFile) throws AttachmentInvalidException {
public static SignalServiceAttachmentStream createAttachmentStream(String attachment) throws AttachmentInvalidException {
try {
final var streamDetails = Utils.createStreamDetailsFromFile(attachmentFile);
return createAttachmentStream(streamDetails, Optional.of(attachmentFile.getName()));
final var streamDetails = Utils.createStreamDetails(attachment);
final var name = streamDetails.getStream() instanceof FileInputStream
? new File(attachment).getName()
: null;
return createAttachmentStream(streamDetails, Optional.ofNullable(name));
} catch (IOException e) {
throw new AttachmentInvalidException(attachmentFile.toString(), e);
throw new AttachmentInvalidException(attachment, e);
}
}

View file

@ -9,6 +9,7 @@ import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.util.StreamDetails;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@ -17,6 +18,7 @@ import java.net.URLConnection;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Base64;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@ -44,6 +46,29 @@ public class Utils {
return mime;
}
private static boolean isBase64DataString(String[] parts) {
return parts.length == 2
&& parts[0].startsWith("data:")
&& parts[0].contains("/")
&& parts[1].startsWith("base64,");
}
public static boolean isBase64DataString(String value) {
return isBase64DataString(value.split(";", 2));
}
public static StreamDetails createStreamDetailsFromBase64(String base64) {
final String[] parts = base64.split(";", 2);
if (!isBase64DataString(parts)) {
throw new IllegalArgumentException("The given argument is not a valid base64 string.");
}
parts[0] = parts[0].substring(5);
byte[] bytes = Base64.getDecoder().decode(parts[1].substring(7).getBytes(StandardCharsets.UTF_8));
return new StreamDetails(new ByteArrayInputStream(bytes), parts[0], bytes.length);
}
public static StreamDetails createStreamDetailsFromFile(File file) throws IOException {
InputStream stream = new FileInputStream(file);
final var size = file.length();
@ -51,6 +76,14 @@ public class Utils {
return new StreamDetails(stream, mime, size);
}
public static StreamDetails createStreamDetails(String value) throws IOException {
if (isBase64DataString(value)) {
return createStreamDetailsFromBase64(value);
}
return createStreamDetailsFromFile(new File(value));
}
public static Fingerprint computeSafetyNumber(
boolean isUuidCapable,
SignalServiceAddress ownAddress,

View file

@ -55,7 +55,9 @@ public class SendCommand implements JsonRpcLocalCommand {
mut.addArgument("--message-from-stdin")
.action(Arguments.storeTrue())
.help("Read the message from standard input.");
subparser.addArgument("-a", "--attachment").nargs("*").help("Add file as attachment");
subparser.addArgument("-a", "--attachment").nargs("*").help("Add file as attachment."
+ "Base64 encoded attachments can be added and must follow the format "
+ "data:<MIME-TYPE>;base64,<BASE64 ENCODED DATA>.");
subparser.addArgument("-e", "--end-session", "--endsession")
.help("Clear session state and send end session message.")
.action(Arguments.storeTrue());