mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 05:09:53 +01:00
Merge branch '1912-specify-group-id-when-loading-attachment' into '214-user-avatars'
Ensure that attachment has expected group ID when loading See merge request briar/briar!1347
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.briar.android.attachment;
|
package org.briarproject.briar.android.attachment;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.UniqueId;
|
import org.briarproject.bramble.api.UniqueId;
|
||||||
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.briar.android.attachment.media.ImageHelper;
|
import org.briarproject.briar.android.attachment.media.ImageHelper;
|
||||||
import org.briarproject.briar.android.attachment.media.ImageSizeCalculator;
|
import org.briarproject.briar.android.attachment.media.ImageSizeCalculator;
|
||||||
@@ -28,6 +29,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
private final AttachmentDimensions dimensions = new AttachmentDimensions(
|
private final AttachmentDimensions dimensions = new AttachmentDimensions(
|
||||||
100, 50, 200, 75, 300
|
100, 50, 200, 75, 300
|
||||||
);
|
);
|
||||||
|
private final GroupId groupId = new GroupId(getRandomId());
|
||||||
private final MessageId msgId = new MessageId(getRandomId());
|
private final MessageId msgId = new MessageId(getRandomId());
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -48,7 +50,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSmallJpegImage() throws Exception {
|
public void testSmallJpegImage() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/jpeg");
|
||||||
InputStream is = getAssetInputStream("kitten_small.jpg");
|
InputStream is = getAssetInputStream("kitten_small.jpg");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -64,7 +66,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBigJpegImage() throws Exception {
|
public void testBigJpegImage() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/jpeg");
|
||||||
InputStream is = getAssetInputStream("kitten_original.jpg");
|
InputStream is = getAssetInputStream("kitten_original.jpg");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -80,7 +82,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSmallPngImage() throws Exception {
|
public void testSmallPngImage() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/png");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/png");
|
||||||
InputStream is = getAssetInputStream("kitten.png");
|
InputStream is = getAssetInputStream("kitten.png");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -96,7 +98,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUberGif() throws Exception {
|
public void testUberGif() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/gif");
|
||||||
InputStream is = getAssetInputStream("uber.gif");
|
InputStream is = getAssetInputStream("uber.gif");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -111,7 +113,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLottaPixels() throws Exception {
|
public void testLottaPixels() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/jpeg");
|
||||||
InputStream is = getAssetInputStream("lottapixel.jpg");
|
InputStream is = getAssetInputStream("lottapixel.jpg");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -126,7 +128,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testImageIoCrash() throws Exception {
|
public void testImageIoCrash() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/png");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/png");
|
||||||
InputStream is = getAssetInputStream("image_io_crash.png");
|
InputStream is = getAssetInputStream("image_io_crash.png");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -141,7 +143,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGimpCrash() throws Exception {
|
public void testGimpCrash() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/gif");
|
||||||
InputStream is = getAssetInputStream("gimp_crash.gif");
|
InputStream is = getAssetInputStream("gimp_crash.gif");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -156,7 +158,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOptiPngAfl() throws Exception {
|
public void testOptiPngAfl() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/gif");
|
||||||
InputStream is = getAssetInputStream("opti_png_afl.gif");
|
InputStream is = getAssetInputStream("opti_png_afl.gif");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -171,7 +173,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLibrawError() throws Exception {
|
public void testLibrawError() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/jpeg");
|
||||||
InputStream is = getAssetInputStream("libraw_error.jpg");
|
InputStream is = getAssetInputStream("libraw_error.jpg");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -180,7 +182,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSmallAnimatedGifMaxDimensions() throws Exception {
|
public void testSmallAnimatedGifMaxDimensions() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/gif");
|
||||||
InputStream is = getAssetInputStream("animated.gif");
|
InputStream is = getAssetInputStream("animated.gif");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -195,7 +197,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSmallAnimatedGifHugeDimensions() throws Exception {
|
public void testSmallAnimatedGifHugeDimensions() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/gif");
|
||||||
InputStream is = getAssetInputStream("animated2.gif");
|
InputStream is = getAssetInputStream("animated2.gif");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -210,7 +212,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSmallGifLargeDimensions() throws Exception {
|
public void testSmallGifLargeDimensions() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/gif");
|
||||||
InputStream is = getAssetInputStream("error_large.gif");
|
InputStream is = getAssetInputStream("error_large.gif");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -225,7 +227,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHighError() throws Exception {
|
public void testHighError() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/jpeg");
|
||||||
InputStream is = getAssetInputStream("error_high.jpg");
|
InputStream is = getAssetInputStream("error_high.jpg");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
@@ -240,7 +242,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWideError() throws Exception {
|
public void testWideError() throws Exception {
|
||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(groupId, msgId, "image/jpeg");
|
||||||
InputStream is = getAssetInputStream("error_wide.jpg");
|
InputStream is = getAssetInputStream("error_wide.jpg");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
AttachmentItem item = retriever.createAttachmentItem(a, true);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.os.Parcel;
|
|||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.briar.api.attachment.AttachmentHeader;
|
import org.briarproject.briar.api.attachment.AttachmentHeader;
|
||||||
|
|
||||||
@@ -78,6 +79,9 @@ public class AttachmentItem implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected AttachmentItem(Parcel in) {
|
protected AttachmentItem(Parcel in) {
|
||||||
|
byte[] groupIdByte = new byte[GroupId.LENGTH];
|
||||||
|
in.readByteArray(groupIdByte);
|
||||||
|
GroupId groupId = new GroupId(groupIdByte);
|
||||||
byte[] messageIdByte = new byte[MessageId.LENGTH];
|
byte[] messageIdByte = new byte[MessageId.LENGTH];
|
||||||
in.readByteArray(messageIdByte);
|
in.readByteArray(messageIdByte);
|
||||||
MessageId messageId = new MessageId(messageIdByte);
|
MessageId messageId = new MessageId(messageIdByte);
|
||||||
@@ -88,7 +92,7 @@ public class AttachmentItem implements Parcelable {
|
|||||||
thumbnailWidth = in.readInt();
|
thumbnailWidth = in.readInt();
|
||||||
thumbnailHeight = in.readInt();
|
thumbnailHeight = in.readInt();
|
||||||
state = State.valueOf(requireNonNull(in.readString()));
|
state = State.valueOf(requireNonNull(in.readString()));
|
||||||
header = new AttachmentHeader(messageId, mimeType);
|
header = new AttachmentHeader(groupId, messageId, mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AttachmentHeader getHeader() {
|
public AttachmentHeader getHeader() {
|
||||||
@@ -142,6 +146,7 @@ public class AttachmentItem implements Parcelable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeByteArray(header.getGroupId().getBytes());
|
||||||
dest.writeByteArray(header.getMessageId().getBytes());
|
dest.writeByteArray(header.getMessageId().getBytes());
|
||||||
dest.writeInt(width);
|
dest.writeInt(width);
|
||||||
dest.writeInt(height);
|
dest.writeInt(height);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.briar.android.attachment;
|
package org.briarproject.briar.android.attachment;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
import org.briarproject.bramble.test.ImmediateExecutor;
|
import org.briarproject.bramble.test.ImmediateExecutor;
|
||||||
@@ -28,6 +29,7 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
|||||||
private final AttachmentDimensions dimensions = new AttachmentDimensions(
|
private final AttachmentDimensions dimensions = new AttachmentDimensions(
|
||||||
100, 50, 200, 75, 300
|
100, 50, 200, 75, 300
|
||||||
);
|
);
|
||||||
|
private final GroupId groupId = new GroupId(getRandomId());
|
||||||
private final MessageId msgId = new MessageId(getRandomId());
|
private final MessageId msgId = new MessageId(getRandomId());
|
||||||
private final ImageHelper imageHelper = context.mock(ImageHelper.class);
|
private final ImageHelper imageHelper = context.mock(ImageHelper.class);
|
||||||
private final ImageSizeCalculator imageSizeCalculator;
|
private final ImageSizeCalculator imageSizeCalculator;
|
||||||
@@ -136,7 +138,8 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Attachment getAttachment(String contentType) {
|
private Attachment getAttachment(String contentType) {
|
||||||
AttachmentHeader header = new AttachmentHeader(msgId, contentType);
|
AttachmentHeader header =
|
||||||
|
new AttachmentHeader(groupId, msgId, contentType);
|
||||||
InputStream in = new ByteArrayInputStream(getRandomBytes(42));
|
InputStream in = new ByteArrayInputStream(getRandomBytes(42));
|
||||||
return new Attachment(header, in);
|
return new Attachment(header, in);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.briar.api.attachment;
|
package org.briarproject.briar.api.attachment;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
@@ -9,14 +10,21 @@ import javax.annotation.concurrent.Immutable;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class AttachmentHeader {
|
public class AttachmentHeader {
|
||||||
|
|
||||||
|
private final GroupId groupId;
|
||||||
private final MessageId messageId;
|
private final MessageId messageId;
|
||||||
private final String contentType;
|
private final String contentType;
|
||||||
|
|
||||||
public AttachmentHeader(MessageId messageId, String contentType) {
|
public AttachmentHeader(GroupId groupId, MessageId messageId,
|
||||||
|
String contentType) {
|
||||||
|
this.groupId = groupId;
|
||||||
this.messageId = messageId;
|
this.messageId = messageId;
|
||||||
this.contentType = contentType;
|
this.contentType = contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GroupId getGroupId() {
|
||||||
|
return groupId;
|
||||||
|
}
|
||||||
|
|
||||||
public MessageId getMessageId() {
|
public MessageId getMessageId() {
|
||||||
return messageId;
|
return messageId;
|
||||||
}
|
}
|
||||||
@@ -27,13 +35,15 @@ public class AttachmentHeader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
return o instanceof AttachmentHeader &&
|
if (o instanceof AttachmentHeader) {
|
||||||
messageId.equals(((AttachmentHeader) o).messageId);
|
AttachmentHeader h = (AttachmentHeader) o;
|
||||||
|
return groupId.equals(h.groupId) && messageId.equals(h.messageId);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return messageId.hashCode();
|
return messageId.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
package org.briarproject.briar.api.attachment;
|
package org.briarproject.briar.api.attachment;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
||||||
|
|
||||||
public interface AttachmentReader {
|
public interface AttachmentReader {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the attachment with the given attachment header.
|
* Returns the attachment with the given attachment header.
|
||||||
*
|
*
|
||||||
* @throws InvalidAttachmentException If the header refers to a message
|
* @throws NoSuchMessageException If the header refers to a message in
|
||||||
|
* a different group from the one specified in the header, to a message
|
||||||
* that is not an attachment, or to an attachment that does not have the
|
* that is not an attachment, or to an attachment that does not have the
|
||||||
* expected content type
|
* expected content type. This is meant to prevent social engineering
|
||||||
|
* attacks that use invalid attachment IDs to test whether messages exist
|
||||||
|
* in the victim's database
|
||||||
*/
|
*/
|
||||||
Attachment getAttachment(AttachmentHeader h) throws DbException;
|
Attachment getAttachment(AttachmentHeader h) throws DbException;
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package org.briarproject.briar.api.attachment;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An exception that is thrown when an {@link AttachmentHeader} is used to
|
|
||||||
* load an {@link Attachment}, and the header refers to a message that is not
|
|
||||||
* an attachment, or to an attachment that does not have the expected content
|
|
||||||
* type.
|
|
||||||
*/
|
|
||||||
@NotNullByDefault
|
|
||||||
public class InvalidAttachmentException extends DbException {
|
|
||||||
public InvalidAttachmentException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvalidAttachmentException(Throwable t) {
|
|
||||||
super(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.briar.api.identity;
|
package org.briarproject.briar.api.identity;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
import org.briarproject.briar.api.attachment.AttachmentHeader;
|
import org.briarproject.briar.api.attachment.AttachmentHeader;
|
||||||
@@ -17,7 +18,8 @@ public class AuthorInfoTest extends BrambleTestCase {
|
|||||||
|
|
||||||
private final String contentType = getRandomString(MAX_CONTENT_TYPE_BYTES);
|
private final String contentType = getRandomString(MAX_CONTENT_TYPE_BYTES);
|
||||||
private final AttachmentHeader avatarHeader =
|
private final AttachmentHeader avatarHeader =
|
||||||
new AttachmentHeader(new MessageId(getRandomId()), contentType);
|
new AttachmentHeader(new GroupId(getRandomId()),
|
||||||
|
new MessageId(getRandomId()), contentType);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEquals() {
|
public void testEquals() {
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import org.briarproject.bramble.api.FormatException;
|
|||||||
import org.briarproject.bramble.api.client.ClientHelper;
|
import org.briarproject.bramble.api.client.ClientHelper;
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
||||||
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.briar.api.attachment.Attachment;
|
import org.briarproject.briar.api.attachment.Attachment;
|
||||||
import org.briarproject.briar.api.attachment.AttachmentHeader;
|
import org.briarproject.briar.api.attachment.AttachmentHeader;
|
||||||
import org.briarproject.briar.api.attachment.AttachmentReader;
|
import org.briarproject.briar.api.attachment.AttachmentReader;
|
||||||
import org.briarproject.briar.api.attachment.InvalidAttachmentException;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -31,18 +32,24 @@ public class AttachmentReaderImpl implements AttachmentReader {
|
|||||||
public Attachment getAttachment(AttachmentHeader h) throws DbException {
|
public Attachment getAttachment(AttachmentHeader h) throws DbException {
|
||||||
// TODO: Support large messages
|
// TODO: Support large messages
|
||||||
MessageId m = h.getMessageId();
|
MessageId m = h.getMessageId();
|
||||||
byte[] body = clientHelper.getMessage(m).getBody();
|
Message message = clientHelper.getMessage(m);
|
||||||
|
// Check that the message is in the expected group, to prevent it from
|
||||||
|
// being loaded in the context of a different group
|
||||||
|
if (!message.getGroupId().equals(h.getGroupId())) {
|
||||||
|
throw new NoSuchMessageException();
|
||||||
|
}
|
||||||
|
byte[] body = message.getBody();
|
||||||
try {
|
try {
|
||||||
BdfDictionary meta = clientHelper.getMessageMetadataAsDictionary(m);
|
BdfDictionary meta = clientHelper.getMessageMetadataAsDictionary(m);
|
||||||
String contentType = meta.getString(MSG_KEY_CONTENT_TYPE);
|
String contentType = meta.getString(MSG_KEY_CONTENT_TYPE);
|
||||||
if (!contentType.equals(h.getContentType()))
|
if (!contentType.equals(h.getContentType()))
|
||||||
throw new InvalidAttachmentException();
|
throw new NoSuchMessageException();
|
||||||
int offset = meta.getLong(MSG_KEY_DESCRIPTOR_LENGTH).intValue();
|
int offset = meta.getLong(MSG_KEY_DESCRIPTOR_LENGTH).intValue();
|
||||||
InputStream stream = new ByteArrayInputStream(body, offset,
|
InputStream stream = new ByteArrayInputStream(body, offset,
|
||||||
body.length - offset);
|
body.length - offset);
|
||||||
return new Attachment(h, stream);
|
return new Attachment(h, stream);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new InvalidAttachmentException(e);
|
throw new NoSuchMessageException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,7 +149,8 @@ class AvatarManagerImpl implements AvatarManager, OpenDatabaseHook, ContactHook,
|
|||||||
}
|
}
|
||||||
ContactId contactId = getContactId(txn, m.getGroupId());
|
ContactId contactId = getContactId(txn, m.getGroupId());
|
||||||
String contentType = d.getString(MSG_KEY_CONTENT_TYPE);
|
String contentType = d.getString(MSG_KEY_CONTENT_TYPE);
|
||||||
AttachmentHeader a = new AttachmentHeader(m.getId(), contentType);
|
AttachmentHeader a = new AttachmentHeader(m.getGroupId(), m.getId(),
|
||||||
|
contentType);
|
||||||
txn.attach(new AvatarUpdatedEvent(contactId, a));
|
txn.attach(new AvatarUpdatedEvent(contactId, a));
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new InvalidMessageException(e);
|
throw new InvalidMessageException(e);
|
||||||
@@ -184,7 +185,7 @@ class AvatarManagerImpl implements AvatarManager, OpenDatabaseHook, ContactHook,
|
|||||||
if (newLatest != null && newLatest.version > version) {
|
if (newLatest != null && newLatest.version > version) {
|
||||||
// latest update is newer than our own
|
// latest update is newer than our own
|
||||||
// no need to store or delete anything, just return latest
|
// no need to store or delete anything, just return latest
|
||||||
return new AttachmentHeader(newLatest.messageId,
|
return new AttachmentHeader(groupId, newLatest.messageId,
|
||||||
newLatest.contentType);
|
newLatest.contentType);
|
||||||
} else if (newLatest != null) {
|
} else if (newLatest != null) {
|
||||||
// delete latest update if it has the same or lower version
|
// delete latest update if it has the same or lower version
|
||||||
@@ -192,7 +193,7 @@ class AvatarManagerImpl implements AvatarManager, OpenDatabaseHook, ContactHook,
|
|||||||
db.deleteMessageMetadata(txn2, newLatest.messageId);
|
db.deleteMessageMetadata(txn2, newLatest.messageId);
|
||||||
}
|
}
|
||||||
clientHelper.addLocalMessage(txn2, m, meta, true, false);
|
clientHelper.addLocalMessage(txn2, m, meta, true, false);
|
||||||
return new AttachmentHeader(m.getId(), contentType);
|
return new AttachmentHeader(groupId, m.getId(), contentType);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +226,8 @@ class AvatarManagerImpl implements AvatarManager, OpenDatabaseHook, ContactHook,
|
|||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
LatestUpdate latest = findLatest(txn, groupId);
|
LatestUpdate latest = findLatest(txn, groupId);
|
||||||
if (latest == null) return null;
|
if (latest == null) return null;
|
||||||
return new AttachmentHeader(latest.messageId, latest.contentType);
|
return new AttachmentHeader(groupId, latest.messageId,
|
||||||
|
latest.contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
} else if (messageType == PRIVATE_MESSAGE) {
|
} else if (messageType == PRIVATE_MESSAGE) {
|
||||||
boolean hasText = metaDict.getBoolean(MSG_KEY_HAS_TEXT);
|
boolean hasText = metaDict.getBoolean(MSG_KEY_HAS_TEXT);
|
||||||
List<AttachmentHeader> headers =
|
List<AttachmentHeader> headers =
|
||||||
parseAttachmentHeaders(metaDict);
|
parseAttachmentHeaders(m.getGroupId(), metaDict);
|
||||||
incomingPrivateMessage(txn, m, metaDict, hasText, headers);
|
incomingPrivateMessage(txn, m, metaDict, hasText, headers);
|
||||||
} else if (messageType == ATTACHMENT) {
|
} else if (messageType == ATTACHMENT) {
|
||||||
incomingAttachment(txn, m);
|
incomingAttachment(txn, m);
|
||||||
@@ -203,16 +203,17 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
messageTracker.trackIncomingMessage(txn, m);
|
messageTracker.trackIncomingMessage(txn, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AttachmentHeader> parseAttachmentHeaders(BdfDictionary meta)
|
private List<AttachmentHeader> parseAttachmentHeaders(GroupId g,
|
||||||
|
BdfDictionary meta)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
BdfList attachmentHeaders = meta.getList(MSG_KEY_ATTACHMENT_HEADERS);
|
BdfList attachmentHeaders = meta.getList(MSG_KEY_ATTACHMENT_HEADERS);
|
||||||
int length = attachmentHeaders.size();
|
int length = attachmentHeaders.size();
|
||||||
List<AttachmentHeader> headers = new ArrayList<>(length);
|
List<AttachmentHeader> headers = new ArrayList<>(length);
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
BdfList header = attachmentHeaders.getList(i);
|
BdfList header = attachmentHeaders.getList(i);
|
||||||
MessageId id = new MessageId(header.getRaw(0));
|
MessageId m = new MessageId(header.getRaw(0));
|
||||||
String contentType = header.getString(1);
|
String contentType = header.getString(1);
|
||||||
headers.add(new AttachmentHeader(id, contentType));
|
headers.add(new AttachmentHeader(g, m, contentType));
|
||||||
}
|
}
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
@@ -280,7 +281,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
// Mark attachments as temporary, not shared until we're ready to send
|
// Mark attachments as temporary, not shared until we're ready to send
|
||||||
db.transaction(false, txn ->
|
db.transaction(false, txn ->
|
||||||
clientHelper.addLocalMessage(txn, m, meta, false, true));
|
clientHelper.addLocalMessage(txn, m, meta, false, true));
|
||||||
return new AttachmentHeader(m.getId(), contentType);
|
return new AttachmentHeader(groupId, m.getId(), contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -357,7 +358,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
boolean hasText = meta.getBoolean(MSG_KEY_HAS_TEXT);
|
boolean hasText = meta.getBoolean(MSG_KEY_HAS_TEXT);
|
||||||
headers.add(new PrivateMessageHeader(id, g, timestamp,
|
headers.add(new PrivateMessageHeader(id, g, timestamp,
|
||||||
local, read, s.isSent(), s.isSeen(), hasText,
|
local, read, s.isSent(), s.isSeen(), hasText,
|
||||||
parseAttachmentHeaders(meta)));
|
parseAttachmentHeaders(g, meta)));
|
||||||
}
|
}
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
@@ -424,6 +425,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
public DeletionResult deleteMessages(Transaction txn, ContactId c,
|
public DeletionResult deleteMessages(Transaction txn, ContactId c,
|
||||||
Set<MessageId> messageIds) throws DbException {
|
Set<MessageId> messageIds) throws DbException {
|
||||||
DeletionResult result = new DeletionResult();
|
DeletionResult result = new DeletionResult();
|
||||||
|
GroupId g = getContactGroup(db.getContact(txn, c)).getId();
|
||||||
for (MessageId m : messageIds) {
|
for (MessageId m : messageIds) {
|
||||||
// get attachment headers
|
// get attachment headers
|
||||||
List<AttachmentHeader> headers;
|
List<AttachmentHeader> headers;
|
||||||
@@ -434,7 +436,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
if (messageType != null && messageType != PRIVATE_MESSAGE)
|
if (messageType != null && messageType != PRIVATE_MESSAGE)
|
||||||
throw new AssertionError("not supported");
|
throw new AssertionError("not supported");
|
||||||
headers = messageType == null ? emptyList() :
|
headers = messageType == null ? emptyList() :
|
||||||
parseAttachmentHeaders(meta);
|
parseAttachmentHeaders(g, meta);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
@@ -460,7 +462,6 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
result.addNotFullyDownloaded();
|
result.addNotFullyDownloaded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GroupId g = getContactGroup(db.getContact(txn, c)).getId();
|
|
||||||
recalculateGroupCount(txn, g);
|
recalculateGroupCount(txn, g);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package org.briarproject.briar.attachment;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.client.ClientHelper;
|
||||||
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
|
import org.briarproject.bramble.api.data.BdfEntry;
|
||||||
|
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
||||||
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
|
import org.briarproject.briar.api.attachment.Attachment;
|
||||||
|
import org.briarproject.briar.api.attachment.AttachmentHeader;
|
||||||
|
import org.jmock.Expectations;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import static java.lang.System.arraycopy;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getMessage;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||||
|
import static org.briarproject.bramble.util.IoUtils.copyAndClose;
|
||||||
|
import static org.briarproject.briar.api.attachment.MediaConstants.MSG_KEY_CONTENT_TYPE;
|
||||||
|
import static org.briarproject.briar.api.attachment.MediaConstants.MSG_KEY_DESCRIPTOR_LENGTH;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
|
||||||
|
public class AttachmentReaderImplTest extends BrambleMockTestCase {
|
||||||
|
|
||||||
|
private final ClientHelper clientHelper = context.mock(ClientHelper.class);
|
||||||
|
|
||||||
|
private final GroupId groupId = new GroupId(getRandomId());
|
||||||
|
private final Message message = getMessage(groupId, 1234);
|
||||||
|
private final String contentType = "image/jpeg";
|
||||||
|
private final AttachmentHeader header = new AttachmentHeader(groupId,
|
||||||
|
message.getId(), contentType);
|
||||||
|
|
||||||
|
private final AttachmentReaderImpl attachmentReader =
|
||||||
|
new AttachmentReaderImpl(clientHelper);
|
||||||
|
|
||||||
|
@Test(expected = NoSuchMessageException.class)
|
||||||
|
public void testWrongGroup() throws Exception {
|
||||||
|
GroupId wrongGroupId = new GroupId(getRandomId());
|
||||||
|
AttachmentHeader wrongGroup = new AttachmentHeader(wrongGroupId,
|
||||||
|
message.getId(), contentType);
|
||||||
|
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(clientHelper).getMessage(message.getId());
|
||||||
|
will(returnValue(message));
|
||||||
|
}});
|
||||||
|
|
||||||
|
attachmentReader.getAttachment(wrongGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NoSuchMessageException.class)
|
||||||
|
public void testMissingContentType() throws Exception {
|
||||||
|
BdfDictionary meta = new BdfDictionary();
|
||||||
|
|
||||||
|
testInvalidMetadata(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NoSuchMessageException.class)
|
||||||
|
public void testWrongContentType() throws Exception {
|
||||||
|
BdfDictionary meta = BdfDictionary.of(
|
||||||
|
new BdfEntry(MSG_KEY_CONTENT_TYPE, "image/png"));
|
||||||
|
|
||||||
|
testInvalidMetadata(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NoSuchMessageException.class)
|
||||||
|
public void testMissingDescriptorLength() throws Exception {
|
||||||
|
BdfDictionary meta = BdfDictionary.of(
|
||||||
|
new BdfEntry(MSG_KEY_CONTENT_TYPE, contentType));
|
||||||
|
|
||||||
|
testInvalidMetadata(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testInvalidMetadata(BdfDictionary meta) throws Exception {
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(clientHelper).getMessage(message.getId());
|
||||||
|
will(returnValue(message));
|
||||||
|
oneOf(clientHelper).getMessageMetadataAsDictionary(message.getId());
|
||||||
|
will(returnValue(meta));
|
||||||
|
}});
|
||||||
|
|
||||||
|
attachmentReader.getAttachment(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSkipsDescriptor() throws Exception {
|
||||||
|
int descriptorLength = 123;
|
||||||
|
BdfDictionary meta = BdfDictionary.of(
|
||||||
|
new BdfEntry(MSG_KEY_CONTENT_TYPE, contentType),
|
||||||
|
new BdfEntry(MSG_KEY_DESCRIPTOR_LENGTH, descriptorLength));
|
||||||
|
|
||||||
|
byte[] body = message.getBody();
|
||||||
|
byte[] expectedData = new byte[body.length - descriptorLength];
|
||||||
|
arraycopy(body, descriptorLength, expectedData, 0, expectedData.length);
|
||||||
|
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(clientHelper).getMessage(message.getId());
|
||||||
|
will(returnValue(message));
|
||||||
|
oneOf(clientHelper).getMessageMetadataAsDictionary(message.getId());
|
||||||
|
will(returnValue(meta));
|
||||||
|
}});
|
||||||
|
|
||||||
|
Attachment attachment = attachmentReader.getAttachment(header);
|
||||||
|
InputStream in = attachment.getStream();
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
copyAndClose(in, out);
|
||||||
|
byte[] data = out.toByteArray();
|
||||||
|
|
||||||
|
assertArrayEquals(expectedData, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.identity.Author;
|
|||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
import org.briarproject.bramble.test.DbExpectations;
|
import org.briarproject.bramble.test.DbExpectations;
|
||||||
@@ -49,7 +50,8 @@ public class AuthorManagerImplTest extends BrambleMockTestCase {
|
|||||||
private final Contact contact = getContact(remote, local, verified);
|
private final Contact contact = getContact(remote, local, verified);
|
||||||
private final String contentType = getRandomString(MAX_CONTENT_TYPE_BYTES);
|
private final String contentType = getRandomString(MAX_CONTENT_TYPE_BYTES);
|
||||||
private final AttachmentHeader avatarHeader =
|
private final AttachmentHeader avatarHeader =
|
||||||
new AttachmentHeader(new MessageId(getRandomId()), contentType);
|
new AttachmentHeader(new GroupId(getRandomId()),
|
||||||
|
new MessageId(getRandomId()), contentType);
|
||||||
|
|
||||||
private final AuthorManagerImpl authorManager =
|
private final AuthorManagerImpl authorManager =
|
||||||
new AuthorManagerImpl(db, identityManager, avatarManager);
|
new AuthorManagerImpl(db, identityManager, avatarManager);
|
||||||
|
|||||||
@@ -73,7 +73,8 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
|||||||
// Create the maximum number of maximum-length attachment headers
|
// Create the maximum number of maximum-length attachment headers
|
||||||
List<AttachmentHeader> headers = new ArrayList<>();
|
List<AttachmentHeader> headers = new ArrayList<>();
|
||||||
for (int i = 0; i < MAX_ATTACHMENTS_PER_MESSAGE; i++) {
|
for (int i = 0; i < MAX_ATTACHMENTS_PER_MESSAGE; i++) {
|
||||||
headers.add(new AttachmentHeader(new MessageId(getRandomId()),
|
headers.add(new AttachmentHeader(groupId,
|
||||||
|
new MessageId(getRandomId()),
|
||||||
getRandomString(MAX_CONTENT_TYPE_BYTES)));
|
getRandomString(MAX_CONTENT_TYPE_BYTES)));
|
||||||
}
|
}
|
||||||
PrivateMessage message = privateMessageFactory.createPrivateMessage(
|
PrivateMessage message = privateMessageFactory.createPrivateMessage(
|
||||||
|
|||||||
Reference in New Issue
Block a user