package de.thedevstack.conversationsplus.utils; import java.net.MalformedURLException; import java.net.URL; import de.thedevstack.conversationsplus.entities.FileParams; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.entities.Transferable; import de.thedevstack.conversationsplus.enums.FileStatus; import de.thedevstack.conversationsplus.enums.MessageConfirmation; import de.thedevstack.conversationsplus.xmpp.chatmarkers.ChatMarkers; import de.thedevstack.conversationsplus.xmpp.receipts.MessageDeliveryReceipts; import de.thedevstack.conversationsplus.xmpp.stanzas.MessagePacket; /** */ public class MessageParserUtil { public static MessageConfirmation extractMessageConfirmation(MessagePacket messagePacket) { if (messagePacket.hasChild(ChatMarkers.MARKABLE) && messagePacket.hasChild(MessageDeliveryReceipts.REQUEST)) { return MessageConfirmation.DELIVERY_RECEIPT_CHAT_MARKERS; } else if (messagePacket.hasChild(ChatMarkers.MARKABLE)) { return MessageConfirmation.CHAT_MARKERS; } else if (messagePacket.hasChild(MessageDeliveryReceipts.REQUEST)) { return MessageConfirmation.DELIVERY_RECEIPT; } else { return MessageConfirmation.NONE; } } public static void extractFileParamsFromBody(Message message) { if (null == message) { return; } // Ensure that for every message the fileParams are set after calling this method FileParams fileParams = message.getFileParams(); if (null == fileParams) { fileParams = new FileParams(); message.setFileParams(fileParams); } String body = message.getBody(); /** * there are a few cases where spaces result in an unwanted behavior, e.g. * "http://example.com/image.jpg" text that will not be shown /abc.png" * or more than one image link in one message. */ if (null == body || body.isEmpty() || body.contains(" ")) { return; } URL url = MessageParserUtil.extractValidUrlFromBody(message); if (null != url) { String extension = FileUtils.getRelevantExtension(url); if (message.isHttpUploaded()) { fileParams.setUrl(url.toString()); if (null != extension && (Transferable.WELL_KNOWN_EXTENSIONS.contains(extension.toLowerCase()) || Transferable.VALID_IMAGE_EXTENSIONS.contains(extension.toLowerCase()))) { message.setTreatAsDownloadable(Message.Decision.MUST); } else { MessageParserUtil.setParamsToAvoidDownload(message, fileParams); } extractFilename(message, url.toString()); return; } if (extension == null) { MessageParserUtil.setParamsToAvoidDownload(message, fileParams); return; } byte[] ivAndKey = UrlUtil.getIvAndKeyFromURL(url); if (null != ivAndKey) { if (MimeUtils.guessMimeTypeFromExtension(extension) != null) { message.setTreatAsDownloadable(Message.Decision.MUST); fileParams.setKeyAndIv(ivAndKey); } else { MessageParserUtil.setParamsToAvoidDownload(message, fileParams); } } else if (Transferable.VALID_IMAGE_EXTENSIONS.contains(extension) || Transferable.WELL_KNOWN_EXTENSIONS.contains(extension)) { message.setTreatAsDownloadable(Message.Decision.SHOULD); MessageUtil.setFileStatus(message, FileStatus.NEEDS_DOWNLOAD); } else { MessageParserUtil.setParamsToAvoidDownload(message, fileParams); } if (message.treatAsDownloadable() == Message.Decision.MUST || message.treatAsDownloadable() == Message.Decision.SHOULD) { fileParams.setUrl(url.toString()); extractFilename(message, url.toString()); MessageUtil.setFileStatus(message, FileStatus.NEEDS_DOWNLOAD); } } else { MessageParserUtil.setParamsToAvoidDownload(message, fileParams); } } private static void setParamsToAvoidDownload(Message message, FileParams fileParams) { message.setTreatAsDownloadable(Message.Decision.NEVER); MessageUtil.setFileStatus(message, FileStatus.UNDEFINED); } private static void extractFilename(Message message, String url) { String originalFilename = FileUtils.getFilenameFromPath(url); final String lowerCaseFilename = originalFilename.toLowerCase(); final String lastPart = FileUtils.getLastExtension(lowerCaseFilename); detectAndSetEncryption(lastPart, message); String filenameExtension; if (!lastPart.isEmpty() && Transferable.VALID_CRYPTO_EXTENSIONS.contains(lastPart)) { filenameExtension = FileUtils.getSecondToLastExtension(lowerCaseFilename); originalFilename = originalFilename.replace("." + lastPart, ""); } else { filenameExtension = lastPart; } message.setRelativeFilePath(message.getUuid() + "." + filenameExtension); message.getFileParams().setOriginalFilename(originalFilename); } private static void detectAndSetEncryption(String lastPart, Message message) { if (!lastPart.isEmpty() && ("pgp".equals(lastPart) || "gpg".equals(lastPart))) { message.setEncryption(Message.ENCRYPTION_PGP); } else if (message.getEncryption() != Message.ENCRYPTION_OTR && message.getEncryption() != Message.ENCRYPTION_AXOLOTL) { message.setEncryption(Message.ENCRYPTION_NONE); } else if ((message.getEncryption() == Message.ENCRYPTION_OTR || message.getEncryption() == Message.ENCRYPTION_AXOLOTL) && message.getFileParams() != null && message.getFileParams().getKey() == null) { // If an encryption is set for the message, but no key given -> decryption not possible message.setEncryption(Message.ENCRYPTION_NONE); } } private static URL extractValidUrlFromBody(Message message) { if (null == message) { return null; } String body = message.getBody(); /** * there are a few cases where spaces result in an unwanted behavior, e.g. * "http://example.com/image.jpg" text that will not be shown /abc.png" * or more than one image link in one message. */ if (null == body || body.isEmpty() || body.contains(" ")) { return null; } try { URL url = new URL(body); if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { return null; } return url; } catch (MalformedURLException e) { return null; } } }