Reject attachments that exceed the allowed size

Closes #1468
This commit is contained in:
Torsten Grote
2019-02-18 15:05:04 -03:00
parent 6167ba5c46
commit f76f9be4ed
9 changed files with 125 additions and 30 deletions

View File

@@ -0,0 +1,43 @@
package org.briarproject.briar.android.conversation;
import android.net.Uri;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class AttachmentResult {
@Nullable
private final Uri uri;
@Nullable
private final String errorMsg;
public AttachmentResult(Uri uri) {
this.uri = uri;
this.errorMsg = null;
}
public AttachmentResult(@Nullable String errorMsg) {
this.uri = null;
this.errorMsg = errorMsg;
}
@Nullable
public Uri getUri() {
return uri;
}
public boolean isError() {
return errorMsg != null;
}
@Nullable
public String getErrorMsg() {
return errorMsg;
}
}

View File

@@ -27,11 +27,13 @@ import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.briar.R;
import org.briarproject.briar.android.util.UiUtils;
import org.briarproject.briar.android.view.TextAttachmentController.AttachmentManager;
import org.briarproject.briar.android.viewmodel.LiveEvent;
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
import org.briarproject.briar.api.messaging.AttachmentHeader;
import org.briarproject.briar.api.messaging.FileTooBigException;
import org.briarproject.briar.api.messaging.MessagingManager;
import org.briarproject.briar.api.messaging.PrivateMessage;
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
@@ -54,6 +56,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.android.conversation.AttachmentDimensions.getAttachmentDimensions;
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
import static org.briarproject.briar.android.util.UiUtils.observeForeverOnce;
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_IMAGE_SIZE;
@NotNullByDefault
public class ConversationViewModel extends AndroidViewModel implements
@@ -192,9 +195,11 @@ public class ConversationViewModel extends AndroidViewModel implements
}
@Override
public void storeAttachment(Uri uri, boolean needsSize, Runnable onSuccess,
Runnable onError) {
public LiveData<AttachmentResult> storeAttachment(Uri uri,
boolean needsSize) {
if (messagingGroupId.getValue() == null) loadGroupId();
// use LiveData to not keep references to view scope
MutableLiveData<AttachmentResult> result = new MutableLiveData<>();
observeForeverOnce(messagingGroupId, groupId -> dbExecutor.execute(()
-> {
if (groupId == null) throw new IllegalStateException();
@@ -204,13 +209,20 @@ public class ConversationViewModel extends AndroidViewModel implements
getApplication().getContentResolver();
attachmentController.createAttachmentHeader(contentResolver,
groupId, uri, needsSize);
androidExecutor.runOnUiThread(onSuccess);
result.postValue(new AttachmentResult(uri));
} catch(FileTooBigException e) {
logException(LOG, WARNING, e);
int mb = MAX_IMAGE_SIZE / 1024 / 1024;
String errorMsg = getApplication()
.getString(R.string.image_attach_error_too_big, mb);
result.postValue(new AttachmentResult(errorMsg));
} catch (DbException | IOException e) {
logException(LOG, WARNING, e);
androidExecutor.runOnUiThread(onError);
result.postValue(new AttachmentResult((String) null));
}
logDuration(LOG, "Storing attachment", start);
}));
return result;
}
@Override

View File

@@ -15,7 +15,7 @@ class ImagePreviewItem {
private final Uri uri;
private boolean waitForLoading = true;
private ImagePreviewItem(Uri uri) {
ImagePreviewItem(Uri uri) {
this.uri = uri;
}

View File

@@ -1,6 +1,8 @@
package org.briarproject.briar.android.view;
import android.app.Activity;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.LiveData;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
@@ -15,6 +17,7 @@ import android.widget.Toast;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.conversation.AttachmentResult;
import org.briarproject.briar.android.view.ImagePreview.ImagePreviewListener;
import org.briarproject.briar.api.messaging.AttachmentHeader;
@@ -149,9 +152,17 @@ public class TextAttachmentController extends TextSendController
// store attachments and show preview when successful
boolean needsSize = items.size() == 1;
for (ImagePreviewItem item : items) {
attachmentManager.storeAttachment(item.getUri(), needsSize,
() -> imagePreview.loadPreviewImage(item),
this::onError);
attachmentManager.storeAttachment(item.getUri(), needsSize)
.observe(imageListener, this::onAttachmentResultReceived);
}
}
private void onAttachmentResultReceived(AttachmentResult result) {
if (result.isError() || result.getUri() == null) {
onError(result.getErrorMsg());
} else {
ImagePreviewItem item = new ImagePreviewItem(result.getUri());
imagePreview.loadPreviewImage(item);
}
}
@@ -194,8 +205,16 @@ public class TextAttachmentController extends TextSendController
@Override
public void onError() {
Toast.makeText(textInput.getContext(), R.string.image_attach_error,
LENGTH_LONG).show();
onError(null);
}
@UiThread
private void onError(@Nullable String errorMsg) {
if (errorMsg == null) {
errorMsg = imagePreview.getContext()
.getString(R.string.image_attach_error);
}
Toast.makeText(textInput.getContext(), errorMsg, LENGTH_LONG).show();
onCancel();
}
@@ -268,7 +287,7 @@ public class TextAttachmentController extends TextSendController
};
}
public interface AttachImageListener {
public interface AttachImageListener extends LifecycleOwner {
void onAttachImage(Intent intent);
}
@@ -277,11 +296,10 @@ public class TextAttachmentController extends TextSendController
* Stores a new attachment in the database.
*
* @param uri The Uri of the attachment to store.
* @param onSuccess will be run on the UiThread when the attachment was stored successfully.
* @param onError will be run on the UiThread when the attachment could not be stored.
* @param needsSize true if this is the only image in the message
* and therefore needs to know its size.
*/
void storeAttachment(Uri uri, boolean needsSize, Runnable onSuccess,
Runnable onError);
LiveData<AttachmentResult> storeAttachment(Uri uri, boolean needsSize);
List<AttachmentHeader> getAttachmentHeaders();