aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/entities/FileParams.java42
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/db/access/MessageDatabaseAccess.java36
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/db/migrations/FileParamsBodyToDatabaseFieldsMigration.java5
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpFileTransferEntity.java2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java3
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java69
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/UrlUtil.java25
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadRequestSlotPacketGenerator.java2
8 files changed, 178 insertions, 6 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/FileParams.java b/src/main/java/de/thedevstack/conversationsplus/entities/FileParams.java
index 1eef078f..290b87b8 100644
--- a/src/main/java/de/thedevstack/conversationsplus/entities/FileParams.java
+++ b/src/main/java/de/thedevstack/conversationsplus/entities/FileParams.java
@@ -9,6 +9,7 @@ import eu.siacs.conversations.utils.MimeUtils;
*/
public class FileParams {
private String name;
+ private String originalFilename;
private String path;
private String url;
private String mimeType;
@@ -16,6 +17,8 @@ public class FileParams {
private int width = 0;
private int height = 0;
private FileStatus fileStatus;
+ private byte[] aeskey;
+ private byte[] iv;
public FileParams() {
fileStatus = FileStatus.UNDEFINED;
@@ -89,6 +92,37 @@ public class FileParams {
return path;
}
+ public void setKeyAndIv(byte[] keyIvCombo) {
+ if (keyIvCombo.length == 48) {
+ this.aeskey = new byte[32];
+ this.iv = new byte[16];
+ System.arraycopy(keyIvCombo, 0, this.iv, 0, 16);
+ System.arraycopy(keyIvCombo, 16, this.aeskey, 0, 32);
+ } else if (keyIvCombo.length >= 32) {
+ this.aeskey = new byte[32];
+ System.arraycopy(keyIvCombo, 0, aeskey, 0, 32);
+ } else if (keyIvCombo.length >= 16) {
+ this.aeskey = new byte[16];
+ System.arraycopy(keyIvCombo, 0, this.aeskey, 0, 16);
+ }
+ }
+
+ public void setKey(byte[] key) {
+ this.aeskey = key;
+ }
+
+ public void setIv(byte[] iv) {
+ this.iv = iv;
+ }
+
+ public byte[] getKey() {
+ return this.aeskey;
+ }
+
+ public byte[] getIv() {
+ return this.iv;
+ }
+
/**
* Sets the path to the file.
* If no file name is stored yet here - this method tries to extract the file name from the path.
@@ -127,4 +161,12 @@ public class FileParams {
public FileStatus getFileStatus() {
return this.fileStatus;
}
+
+ public void setOriginalFilename(String originalFilename) {
+ this.originalFilename = originalFilename;
+ }
+
+ public String getOriginalFilename() {
+ return this.originalFilename;
+ }
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/db/access/MessageDatabaseAccess.java b/src/main/java/de/thedevstack/conversationsplus/persistance/db/access/MessageDatabaseAccess.java
index 139dc419..0fb85fbf 100644
--- a/src/main/java/de/thedevstack/conversationsplus/persistance/db/access/MessageDatabaseAccess.java
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/db/access/MessageDatabaseAccess.java
@@ -10,6 +10,7 @@ import de.thedevstack.conversationsplus.enums.FileStatus;
import de.thedevstack.conversationsplus.persistance.db.migrations.FileParamsBodyToDatabaseFieldsMigration;
import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.utils.CryptoHelper;
/**
*
@@ -29,6 +30,9 @@ public class MessageDatabaseAccess extends AbstractDatabaseAccess {
private static final String COLUMN_NAME_MSG_PARAMS_FILE_NAME = "file_name";
private static final String COLUMN_NAME_MSG_PARAMS_FILE_PATH = "file_path";
private static final String COLUMN_NAME_MSG_PARAMS_FILE_URL = "file_url";
+ private static final String COLUMN_NAME_MSG_PARAMS_FILE_IV = "file_iv";
+ private static final String COLUMN_NAME_MSG_PARAMS_FILE_KEY = "file_key";
+ private static final String COLUMN_NAME_MSG_PARAMS_ORIGINAL_FILE_NAME = "original_file_name";
private static final String TABLE_ADDITIONAL_PARAMETERS_CREATE_V1 = "CREATE TABLE " + MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS + " ("
+ MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + " TEXT, "
@@ -46,8 +50,11 @@ public class MessageDatabaseAccess extends AbstractDatabaseAccess {
+ MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_WIDTH + " INTEGER DEFAULT 0, "
+ MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_STATUS + " TEXT DEFAULT 'UNDEFINED', "
+ MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_NAME + " TEXT DEFAULT NULL, "
+ + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_ORIGINAL_FILE_NAME + " TEXT DEFAULT NULL, "
+ MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_PATH + " TEXT DEFAULT NULL, "
+ MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_URL + " TEXT DEFAULT NULL, "
+ + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_IV + " TEXT DEFAULT NULL, "
+ + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_KEY + " TEXT DEFAULT NULL, "
+ "FOREIGN KEY(" + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + ") REFERENCES " + Message.TABLENAME + "(" + Message.UUID + ") ON DELETE CASCADE)";
public static void updateMessageParameters(SQLiteDatabase db, Message message, String uuid) {
@@ -66,8 +73,16 @@ public class MessageDatabaseAccess extends AbstractDatabaseAccess {
additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_SIZE, fileParams.getSize());
additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_HEIGHT, fileParams.getHeight());
additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_WIDTH, fileParams.getWidth());
+ additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_NAME, fileParams.getName());
+ additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_ORIGINAL_FILE_NAME, fileParams.getOriginalFilename());
additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_PATH, fileParams.getPath());
additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_URL, fileParams.getUrl());
+ if (null != fileParams.getIv()) {
+ additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_IV, CryptoHelper.bytesToHex(fileParams.getIv()));
+ }
+ if (null != fileParams.getKey()) {
+ additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_KEY, CryptoHelper.bytesToHex(fileParams.getKey()));
+ }
if (null != fileParams.getFileStatus()) {
additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_STATUS, fileParams.getFileStatus().name());
}
@@ -96,10 +111,20 @@ public class MessageDatabaseAccess extends AbstractDatabaseAccess {
fileParams.setMimeType(fileType);
String name = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_FILE_NAME);
fileParams.setName(name);
+ String originalFilename = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_ORIGINAL_FILE_NAME);
+ fileParams.setOriginalFilename(originalFilename);
String path = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_FILE_PATH);
fileParams.setPath(path);
String url = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_FILE_URL);
fileParams.setUrl(url);
+ String iv = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_FILE_IV);
+ if (null != iv && !iv.isEmpty()) {
+ fileParams.setIv(CryptoHelper.hexToBytes(iv));
+ }
+ String key = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_FILE_KEY);
+ if (null != key && !key.isEmpty()) {
+ fileParams.setKey(CryptoHelper.hexToBytes(key));
+ }
long fileSize = CursorHelper.getLong(cursor, COLUMN_NAME_MSG_PARAMS_FILE_SIZE);
fileParams.setSize(fileSize);
int imageHeight = CursorHelper.getInt(cursor, COLUMN_NAME_MSG_PARAMS_FILE_HEIGHT);
@@ -147,7 +172,11 @@ public class MessageDatabaseAccess extends AbstractDatabaseAccess {
MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_WIDTH + " INTEGER DEFAULT 0",
MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_STATUS + " TEXT DEFAULT 'UNDEFINED'",
MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_NAME + " TEXT DEFAULT NULL",
+ MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_ORIGINAL_FILE_NAME + " TEXT DEFAULT NULL",
MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_PATH + " TEXT DEFAULT NULL",
+ MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_URL + " TEXT DEFAULT NULL",
+ MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_IV + " TEXT DEFAULT NULL",
+ MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_KEY + " TEXT DEFAULT NULL",
};
addNewColumns(db, MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS, columnDefinitions);
@@ -167,6 +196,13 @@ public class MessageDatabaseAccess extends AbstractDatabaseAccess {
parameterValues.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_SIZE, fileParams.getSize());
parameterValues.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_HEIGHT, fileParams.getHeight());
parameterValues.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_WIDTH, fileParams.getWidth());
+ parameterValues.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_URL, fileParams.getUrl());
+ if (null != fileParams.getIv()) {
+ parameterValues.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_IV, CryptoHelper.bytesToHex(fileParams.getIv()));
+ }
+ if (null != fileParams.getKey()) {
+ parameterValues.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_KEY, CryptoHelper.bytesToHex(fileParams.getKey()));
+ }
db.update(MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS, parameterValues, MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + "=?", new String[] {uuid});
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/db/migrations/FileParamsBodyToDatabaseFieldsMigration.java b/src/main/java/de/thedevstack/conversationsplus/persistance/db/migrations/FileParamsBodyToDatabaseFieldsMigration.java
index c0aa63c0..8ad94ca0 100644
--- a/src/main/java/de/thedevstack/conversationsplus/persistance/db/migrations/FileParamsBodyToDatabaseFieldsMigration.java
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/db/migrations/FileParamsBodyToDatabaseFieldsMigration.java
@@ -4,6 +4,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import de.thedevstack.conversationsplus.entities.FileParams;
+import de.thedevstack.conversationsplus.utils.UrlUtil;
/**
* Created by steckbrief on 24.08.2016.
@@ -28,6 +29,8 @@ public class FileParamsBodyToDatabaseFieldsMigration {
try {
URL url = new URL(parts[0]);
params.setUrl(url.toString());
+ byte[] ivAndKey = UrlUtil.getIvAndKeyFromURL(url);
+ params.setKeyAndIv(ivAndKey);
} catch (MalformedURLException e1) {
}
}
@@ -37,6 +40,8 @@ public class FileParamsBodyToDatabaseFieldsMigration {
try {
URL url = new URL(parts[0]);
params.setUrl(url.toString());
+ byte[] ivAndKey = UrlUtil.getIvAndKeyFromURL(url);
+ params.setKeyAndIv(ivAndKey);
} catch (MalformedURLException e1) {
}
try {
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpFileTransferEntity.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpFileTransferEntity.java
index 9ec07679..a36db4cd 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpFileTransferEntity.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpFileTransferEntity.java
@@ -31,9 +31,9 @@ public class HttpFileTransferEntity extends FileTransferEntity {
FileParams fileParams = this.getMessage().getFileParams();
if (null == fileParams) {
fileParams = new FileParams();
+ this.getMessage().setFileParams(fileParams);
}
fileParams.setFileStatus(FileStatus.NEEDS_UPLOAD);
- this.getMessage().setFileParams(fileParams);
if (Config.ENCRYPT_ON_HTTP_UPLOADED
|| message.getEncryption() == Message.ENCRYPTION_AXOLOTL
|| message.getEncryption() == Message.ENCRYPTION_OTR) {
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java
index 1b44d09b..8a3de18d 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java
@@ -62,8 +62,9 @@ public class MessageDetailsDialog extends AbstractAlertDialog {
view.findViewById(R.id.dlgMsgDetFileTable).setVisibility(View.VISIBLE);
if (null != message.getFileParams()) {
FileParams params = message.getFileParams();
- TextViewUtil.setText(view, R.id.dlgMsgDetFileSize, UIHelper.getHumanReadableFileSize(params.getSize()));
+ TextViewUtil.setText(view, R.id.dlgMsgDetFileSize, UIHelper.getHumanReadableDetailedFileSize(params.getSize()));
TextViewUtil.setText(view, R.id.dlgMsgDetFileMimeType, params.getMimeType());
+ TextViewUtil.setText(view, R.id.dlgMsgDetFileOriginalName, params.getOriginalFilename());
}
TextViewUtil.setText(view, R.id.dlgMsgDetFileHttpUploaded, message.isHttpUploaded() ? R.string.cplus_yes : R.string.cplus_no);
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
index 37e39285..ed144465 100644
--- a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
@@ -3,6 +3,7 @@ package de.thedevstack.conversationsplus.utils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -14,18 +15,80 @@ import de.thedevstack.conversationsplus.enums.FileStatus;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.entities.Transferable;
import eu.siacs.conversations.persistance.DatabaseBackend;
import eu.siacs.conversations.persistance.FileBackend;
+import eu.siacs.conversations.utils.FileUtils;
+import eu.siacs.conversations.utils.MimeUtils;
/**
* Utility class to work with messages.
*/
public final class MessageUtil {
+ public static void extractFileParamsFromBody(Message message) {
+ if (null == message) {
+ return;
+ }
+ 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;
+ }
+
+ FileParams fileParams = message.getFileParams();
+ if (null == fileParams) {
+ fileParams = new FileParams();
+ message.setFileParams(fileParams);
+ }
+
+ try {
+ URL url = new URL(body);
+ if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) {
+ message.setTreatAsDownloadable(Message.Decision.NEVER);
+ return;
+ }
+ if (message.isHttpUploaded()) {
+ fileParams.setUrl(url.toString());
+ message.setTreatAsDownloadable(Message.Decision.MUST);
+ return;
+ }
+ String extension = FileUtils.getRelevantExtension(url);
+ if (extension == null) {
+ message.setTreatAsDownloadable(Message.Decision.NEVER);
+ return;
+ }
+ byte[] ivAndKey = UrlUtil.getIvAndKeyFromURL(url);
+
+ if (null != ivAndKey) {
+ if (MimeUtils.guessMimeTypeFromExtension(extension) != null) {
+ message.setTreatAsDownloadable(Message.Decision.MUST);
+ fileParams.setKeyAndIv(ivAndKey);
+ fileParams.setUrl(url.toString());
+ } else {
+ message.setTreatAsDownloadable(Message.Decision.NEVER);
+ }
+ } else if (Transferable.VALID_IMAGE_EXTENSIONS.contains(extension)
+ || Transferable.WELL_KNOWN_EXTENSIONS.contains(extension)) {
+ message.setTreatAsDownloadable(Message.Decision.SHOULD);
+ fileParams.setUrl(url.toString());
+ } else {
+ message.setTreatAsDownloadable(Message.Decision.NEVER);
+ }
+
+ } catch (MalformedURLException e) {
+ message.setTreatAsDownloadable(Message.Decision.NEVER);
+ }
+ }
+
public static boolean needsDownload(Message message) {
FileStatus fileStatus = (null != message.getFileParams()) ? message.getFileParams().getFileStatus() : null;
- return (null != fileStatus && (fileStatus == FileStatus.NEEDS_DOWNLOAD
- || fileStatus == FileStatus.UNDEFINED))
+ return (null == fileStatus
+ || (null != fileStatus && (fileStatus == FileStatus.NEEDS_DOWNLOAD || fileStatus == FileStatus.UNDEFINED)))
&& message.treatAsDownloadable() != Message.Decision.NEVER;
}
@@ -122,6 +185,7 @@ public final class MessageUtil {
FileParams fileParams = message.getFileParams();
if (null == fileParams) {
fileParams = new FileParams();
+ message.setFileParams(fileParams);
}
fileParams.setSize(size);
if (null != url) {
@@ -137,7 +201,6 @@ public final class MessageUtil {
if (null != relativeFilePathFromMessage && relativeFilePathFromMessage.startsWith("/")) {
fileParams.setPath(relativeFilePathFromMessage);
}
- message.setFileParams(fileParams);
}
private MessageUtil() {
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/UrlUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/UrlUtil.java
new file mode 100644
index 00000000..50c42288
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/UrlUtil.java
@@ -0,0 +1,25 @@
+package de.thedevstack.conversationsplus.utils;
+
+import java.net.URL;
+
+import eu.siacs.conversations.utils.CryptoHelper;
+
+/**
+ * This utility class provides helper methods to handle URLs.
+ */
+
+public final class UrlUtil {
+ public static byte[] getIvAndKeyFromURL(URL url) {
+ if (null == url) {
+ return null;
+ }
+ String reference = url.getRef();
+ boolean linkHasIvAndKey = reference != null && reference.matches("([A-Fa-f0-9]{2}){48}");
+
+ return linkHasIvAndKey ? CryptoHelper.hexToBytes(reference) : null;
+ }
+
+ private UrlUtil() {
+ // Helper Class
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadRequestSlotPacketGenerator.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadRequestSlotPacketGenerator.java
index 915cf9a7..cdb957c4 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadRequestSlotPacketGenerator.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadRequestSlotPacketGenerator.java
@@ -33,7 +33,7 @@ public final class HttpUploadRequestSlotPacketGenerator {
public static IqPacket generate(Jid host, String filename, long filesize, String mime) {
SlotRequestPacket packet = new SlotRequestPacket(filename, filesize);
packet.setTo(host);
- packet.setMime((mime == null) ? HttpUpload.DEFAULT_MIME_TYPE : mime);
+ packet.setMime((mime == null || mime.isEmpty()) ? HttpUpload.DEFAULT_MIME_TYPE : mime);
return packet;
}