Merge tag 'release-1.3.6' into briar-as-subproject

release-1.3.6
This commit is contained in:
ialokim
2021-09-09 13:16:27 +02:00
1014 changed files with 42340 additions and 15502 deletions

View File

@@ -10,4 +10,7 @@ dependencies {
implementation project(path: ':briar:bramble-api', configuration: 'default')
signature 'org.codehaus.mojo.signature:java16:1.1@signature'
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
testImplementation "junit:junit:$junit_version"
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.briar.api.messaging;
package org.briarproject.briar.api.attachment;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;

View File

@@ -1,6 +1,7 @@
package org.briarproject.briar.api.messaging;
package org.briarproject.briar.api.attachment;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import javax.annotation.concurrent.Immutable;
@@ -9,14 +10,21 @@ import javax.annotation.concurrent.Immutable;
@NotNullByDefault
public class AttachmentHeader {
private final GroupId groupId;
private final MessageId messageId;
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.contentType = contentType;
}
public GroupId getGroupId() {
return groupId;
}
public MessageId getMessageId() {
return messageId;
}
@@ -27,13 +35,15 @@ public class AttachmentHeader {
@Override
public boolean equals(Object o) {
return o instanceof AttachmentHeader &&
messageId.equals(((AttachmentHeader) o).messageId);
if (o instanceof AttachmentHeader) {
AttachmentHeader h = (AttachmentHeader) o;
return groupId.equals(h.groupId) && messageId.equals(h.messageId);
}
return false;
}
@Override
public int hashCode() {
return messageId.hashCode();
}
}

View File

@@ -0,0 +1,20 @@
package org.briarproject.briar.api.attachment;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.NoSuchMessageException;
public interface AttachmentReader {
/**
* Returns the attachment with the given attachment header.
*
* @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
* 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;
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.briar.api.messaging;
package org.briarproject.briar.api.attachment;
import java.io.IOException;

View File

@@ -0,0 +1,21 @@
package org.briarproject.briar.api.attachment;
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
public interface MediaConstants {
// Metadata keys for messages
String MSG_KEY_CONTENT_TYPE = "contentType";
String MSG_KEY_DESCRIPTOR_LENGTH = "descriptorLength";
/**
* The maximum length of an attachment's content type in UTF-8 bytes.
*/
int MAX_CONTENT_TYPE_BYTES = 80;
/**
* The maximum allowed size of image attachments.
* TODO: Different limit for GIFs?
*/
int MAX_IMAGE_SIZE = MAX_MESSAGE_BODY_LENGTH - 100; // 6 * 1024 * 1024;
}

View File

@@ -0,0 +1,23 @@
package org.briarproject.briar.api.autodelete;
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.MINUTES;
public interface AutoDeleteConstants {
/**
* The minimum valid auto-delete timer duration in milliseconds.
*/
long MIN_AUTO_DELETE_TIMER_MS = MINUTES.toMillis(1);
/**
* The maximum valid auto-delete timer duration in milliseconds.
*/
long MAX_AUTO_DELETE_TIMER_MS = DAYS.toMillis(365);
/**
* Placeholder value indicating that a message has no auto-delete timer.
* This value should not be sent over the wire - send null instead.
*/
long NO_AUTO_DELETE_TIMER = -1;
}

View File

@@ -0,0 +1,64 @@
package org.briarproject.briar.api.autodelete;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId;
import static java.util.concurrent.TimeUnit.DAYS;
@NotNullByDefault
public interface AutoDeleteManager {
/**
* The unique ID of the auto-delete client.
*/
ClientId CLIENT_ID = new ClientId("org.briarproject.briar.autodelete");
/**
* The current major version of the auto-delete client.
*/
int MAJOR_VERSION = 0;
/**
* The current minor version of the auto-delete client.
*/
int MINOR_VERSION = 0;
/**
* The default auto-delete timer duration.
*/
long DEFAULT_TIMER_DURATION = DAYS.toMillis(7);
/**
* Returns the auto-delete timer duration for the given contact. Use
* {@link #getAutoDeleteTimer(Transaction, ContactId, long)} if the timer
* will be used in an outgoing message.
*/
long getAutoDeleteTimer(Transaction txn, ContactId c) throws DbException;
/**
* Returns the auto-delete timer duration for the given contact, for use in
* a message with the given timestamp. The timestamp is stored. This method
* requires a read-write transaction.
*/
long getAutoDeleteTimer(Transaction txn, ContactId c, long timestamp)
throws DbException;
/**
* Sets the auto-delete timer duration for the given contact.
*/
void setAutoDeleteTimer(Transaction txn, ContactId c, long timer)
throws DbException;
/**
* Receives an auto-delete timer duration from the given contact, carried
* in a message with the given timestamp. The local timer is set to the
* same duration unless it has been
* {@link #setAutoDeleteTimer(Transaction, ContactId, long) changed} more
* recently than the remote timer.
*/
void receiveAutoDeleteTimer(Transaction txn, ContactId c, long timer,
long timestamp) throws DbException;
}

View File

@@ -0,0 +1,12 @@
package org.briarproject.briar.api.autodelete;
import org.briarproject.bramble.api.db.DbException;
/**
* Thrown when a database operation is attempted as part of message storing
* and the operation is expecting a different timer state. This
* exception may occur due to concurrent updates and does not indicate a
* database error.
*/
public class UnexpectedTimerException extends DbException {
}

View File

@@ -0,0 +1,28 @@
package org.briarproject.briar.api.autodelete.event;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class AutoDeleteTimerMirroredEvent extends Event {
private final ContactId contactId;
private final long newTimer;
public AutoDeleteTimerMirroredEvent(ContactId contactId, long newTimer) {
this.contactId = contactId;
this.newTimer = newTimer;
}
public ContactId getContactId() {
return contactId;
}
public long getNewTimer() {
return newTimer;
}
}

View File

@@ -0,0 +1,36 @@
package org.briarproject.briar.api.autodelete.event;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageId;
import java.util.Collection;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when one or more messages
* in the private conversation with a contact have been deleted.
*/
@Immutable
@NotNullByDefault
public class ConversationMessagesDeletedEvent extends Event {
private final ContactId contactId;
private final Collection<MessageId> messageIds;
public ConversationMessagesDeletedEvent(ContactId contactId,
Collection<MessageId> messageIds) {
this.contactId = contactId;
this.messageIds = messageIds;
}
public ContactId getContactId() {
return contactId;
}
public Collection<MessageId> getMessageIds() {
return messageIds;
}
}

View File

@@ -0,0 +1,53 @@
package org.briarproject.briar.api.avatar;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.briar.api.attachment.AttachmentHeader;
import java.io.IOException;
import java.io.InputStream;
import javax.annotation.Nullable;
@NotNullByDefault
public interface AvatarManager {
/**
* The unique ID of the avatar client.
*/
ClientId CLIENT_ID = new ClientId("org.briarproject.briar.avatar");
/**
* The current major version of the avatar client.
*/
int MAJOR_VERSION = 0;
/**
* The current minor version of the avatar client.
*/
int MINOR_VERSION = 0;
/**
* Store a new profile image represented by the given InputStream
* and share it with all contacts.
*/
AttachmentHeader addAvatar(String contentType, InputStream in)
throws DbException, IOException;
/**
* Returns the current known profile image header for the given contact
* or null if none is known.
*/
@Nullable
AttachmentHeader getAvatarHeader(Transaction txn, Contact c)
throws DbException;
/**
* Returns our current profile image header or null if none has been added.
*/
@Nullable
AttachmentHeader getMyAvatarHeader(Transaction txn) throws DbException;
}

View File

@@ -0,0 +1,18 @@
package org.briarproject.briar.api.avatar;
import org.briarproject.bramble.api.Pair;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import java.io.IOException;
import java.io.InputStream;
public interface AvatarMessageEncoder {
/**
* Returns an update message and its metadata.
*/
Pair<Message, BdfDictionary> encodeUpdateMessage(GroupId groupId,
long version, String contentType, InputStream in)
throws IOException;
}

View File

@@ -0,0 +1,33 @@
package org.briarproject.briar.api.avatar.event;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.api.attachment.AttachmentHeader;
import javax.annotation.concurrent.Immutable;
/**
* An event that is broadcast when a new avatar is received.
*/
@Immutable
@NotNullByDefault
public class AvatarUpdatedEvent extends Event {
private final ContactId contactId;
private final AttachmentHeader attachmentHeader;
public AvatarUpdatedEvent(ContactId contactId,
AttachmentHeader attachmentHeader) {
this.contactId = contactId;
this.attachmentHeader = attachmentHeader;
}
public ContactId getContactId() {
return contactId;
}
public AttachmentHeader getAttachmentHeader() {
return attachmentHeader;
}
}

View File

@@ -1,7 +1,7 @@
package org.briarproject.briar.api.blog;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.briar.api.identity.AuthorInfo;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;

View File

@@ -15,9 +15,9 @@ public class BlogInvitationRequest extends InvitationRequest<Blog> {
public BlogInvitationRequest(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, Blog blog, @Nullable String text,
boolean available, boolean canBeOpened) {
boolean available, boolean canBeOpened, long autoDeleteTimer) {
super(id, groupId, time, local, read, sent, seen, sessionId, blog,
text, available, canBeOpened);
text, available, canBeOpened, autoDeleteTimer);
}
@Override

View File

@@ -12,9 +12,10 @@ public class BlogInvitationResponse extends InvitationResponse {
public BlogInvitationResponse(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accept, GroupId shareableId) {
SessionId sessionId, boolean accept, GroupId shareableId,
long autoDeleteTimer, boolean isAutoDecline) {
super(id, groupId, time, local, read, sent, seen, sessionId,
accept, shareableId);
accept, shareableId, autoDeleteTimer, isAutoDecline);
}
@Override

View File

@@ -10,6 +10,7 @@ import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
@@ -98,21 +99,38 @@ public interface BlogManager {
*/
Collection<Blog> getBlogs() throws DbException;
/**
* Returns the group IDs of all blogs to which the user subscribes.
*/
Collection<GroupId> getBlogIds(Transaction txn) throws DbException;
/**
* Returns the header of the blog post with the given ID.
*/
BlogPostHeader getPostHeader(GroupId g, MessageId m) throws DbException;
BlogPostHeader getPostHeader(Transaction txn, GroupId g, MessageId m)
throws DbException;
/**
* Returns the text of the blog post with the given ID.
*/
String getPostText(MessageId m) throws DbException;
/**
* Returns the text of the blog post with the given ID.
*/
String getPostText(Transaction txn, MessageId m) throws DbException;
/**
* Returns the headers of all posts in the given blog.
*/
Collection<BlogPostHeader> getPostHeaders(GroupId g) throws DbException;
/**
* Returns the headers of all posts in the given blog.
*/
List<BlogPostHeader> getPostHeaders(Transaction txn, GroupId g)
throws DbException;
/**
* Marks a blog post as read or unread.
*/

View File

@@ -1,7 +1,7 @@
package org.briarproject.briar.api.blog;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.briar.api.identity.AuthorInfo;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;

View File

@@ -18,5 +18,5 @@ public interface BlogSharingManager extends SharingManager<Blog> {
/**
* The current minor version of the blog sharing client.
*/
int MINOR_VERSION = 0;
int MINOR_VERSION = 1;
}

View File

@@ -61,8 +61,11 @@ public interface MessageTracker {
/**
* Marks a message as read or unread and updates the group count.
*
* @return True if the message was previously marked as read
*/
void setReadFlag(GroupId g, MessageId m, boolean read) throws DbException;
boolean setReadFlag(Transaction txn, GroupId g, MessageId m, boolean read)
throws DbException;
/**
* Resets the {@link GroupCount} to the given msgCount and unreadCount.

View File

@@ -4,7 +4,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageId;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import javax.annotation.Nullable;
@@ -15,11 +15,9 @@ public interface MessageTree<T extends MessageTree.MessageNode> {
void add(T node);
void setComparator(Comparator<T> comparator);
void clear();
Collection<T> depthFirstOrder();
List<T> depthFirstOrder();
boolean contains(MessageId m);

View File

@@ -1,8 +1,8 @@
package org.briarproject.briar.api.client;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.identity.AuthorInfo.Status;
import org.briarproject.briar.api.identity.AuthorInfo;
import org.briarproject.briar.api.identity.AuthorInfo.Status;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageId;

View File

@@ -21,7 +21,6 @@ public interface ConversationManager {
int DELETE_SESSION_INVITATION_INCOMPLETE = 1 << 1;
int DELETE_SESSION_INTRODUCTION_IN_PROGRESS = 1 << 2;
int DELETE_SESSION_INVITATION_IN_PROGRESS = 1 << 3;
int DELETE_NOT_DOWNLOADED = 1 << 4;
/**
* Clients that present messages in a private conversation need to
@@ -43,6 +42,21 @@ public interface ConversationManager {
*/
GroupCount getGroupCount(ContactId c) throws DbException;
/**
* Returns the unified group count for all private conversation messages.
*/
GroupCount getGroupCount(Transaction txn, ContactId c) throws DbException;
void setReadFlag(GroupId g, MessageId m, boolean read)
throws DbException;
/**
* Returns a timestamp for an outgoing message, which is later than the
* timestamp of any message in the conversation with the given contact.
*/
long getTimestampForOutgoingMessage(Transaction txn, ContactId c)
throws DbException;
/**
* Deletes all messages exchanged with the given contact.
*/
@@ -72,9 +86,6 @@ public interface ConversationManager {
GroupCount getGroupCount(Transaction txn, ContactId c)
throws DbException;
void setReadFlag(GroupId g, MessageId m, boolean read)
throws DbException;
/**
* Deletes all messages associated with the given contact.
*/

View File

@@ -12,18 +12,20 @@ public abstract class ConversationMessageHeader {
private final MessageId id;
private final GroupId groupId;
private final long timestamp;
private final boolean local, sent, seen, read;
private final long timestamp, autoDeleteTimer;
private final boolean local, read, sent, seen;
public ConversationMessageHeader(MessageId id, GroupId groupId, long timestamp,
boolean local, boolean read, boolean sent, boolean seen) {
public ConversationMessageHeader(MessageId id, GroupId groupId,
long timestamp, boolean local, boolean read, boolean sent,
boolean seen, long autoDeleteTimer) {
this.id = id;
this.groupId = groupId;
this.timestamp = timestamp;
this.local = local;
this.read = read;
this.sent = sent;
this.seen = seen;
this.read = read;
this.autoDeleteTimer = autoDeleteTimer;
}
public MessageId getId() {
@@ -55,4 +57,8 @@ public abstract class ConversationMessageHeader {
}
public abstract <T> T accept(ConversationMessageVisitor<T> v);
public long getAutoDeleteTimer() {
return autoDeleteTimer;
}
}

View File

@@ -20,11 +20,12 @@ public abstract class ConversationRequest<N extends Nameable>
private final String text;
private final boolean answered;
public ConversationRequest(MessageId messageId, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, N nameable, @Nullable String text,
boolean answered) {
super(messageId, groupId, time, local, read, sent, seen);
public ConversationRequest(MessageId messageId, GroupId groupId,
long timestamp, boolean local, boolean read, boolean sent,
boolean seen, SessionId sessionId, N nameable,
@Nullable String text, boolean answered, long autoDeleteTimer) {
super(messageId, groupId, timestamp, local, read, sent, seen,
autoDeleteTimer);
this.sessionId = sessionId;
this.nameable = nameable;
this.text = text;

View File

@@ -12,14 +12,16 @@ import javax.annotation.concurrent.Immutable;
public abstract class ConversationResponse extends ConversationMessageHeader {
private final SessionId sessionId;
private final boolean accepted;
private final boolean accepted, isAutoDecline;
public ConversationResponse(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accepted) {
super(id, groupId, time, local, read, sent, seen);
SessionId sessionId, boolean accepted, long autoDeleteTimer,
boolean isAutoDecline) {
super(id, groupId, time, local, read, sent, seen, autoDeleteTimer);
this.sessionId = sessionId;
this.accepted = accepted;
this.isAutoDecline = isAutoDecline;
}
public SessionId getSessionId() {
@@ -30,4 +32,7 @@ public abstract class ConversationResponse extends ConversationMessageHeader {
return accepted;
}
public boolean isAutoDecline() {
return isAutoDecline;
}
}

View File

@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.concurrent.NotThreadSafe;
import static org.briarproject.briar.api.conversation.ConversationManager.DELETE_NOT_DOWNLOADED;
import static org.briarproject.briar.api.conversation.ConversationManager.DELETE_SESSION_INTRODUCTION_INCOMPLETE;
import static org.briarproject.briar.api.conversation.ConversationManager.DELETE_SESSION_INTRODUCTION_IN_PROGRESS;
import static org.briarproject.briar.api.conversation.ConversationManager.DELETE_SESSION_INVITATION_INCOMPLETE;
@@ -36,10 +35,6 @@ public class DeletionResult {
result |= DELETE_SESSION_INTRODUCTION_IN_PROGRESS;
}
public void addNotFullyDownloaded() {
result |= DELETE_NOT_DOWNLOADED;
}
public boolean allDeleted() {
return result == 0;
}
@@ -59,9 +54,4 @@ public class DeletionResult {
public boolean hasNotAllInvitationSelected() {
return (result & DELETE_SESSION_INVITATION_INCOMPLETE) != 0;
}
public boolean hasNotFullyDownloaded() {
return (result & DELETE_NOT_DOWNLOADED) != 0;
}
}

View File

@@ -10,7 +10,7 @@ import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class Feed {
public class Feed implements Comparable<Feed> {
private final String url;
private final Blog blog;
@@ -94,4 +94,13 @@ public class Feed {
return false;
}
@Override
public int compareTo(Feed o) {
if (this == o) return 0;
long aTime = getAdded(), bTime = o.getAdded();
if (aTime > bTime) return -1;
if (aTime < bTime) return 1;
return 0;
}
}

View File

@@ -1,6 +1,7 @@
package org.briarproject.briar.api.feed;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId;
@@ -23,7 +24,7 @@ public interface FeedManager {
/**
* Adds an RSS feed as a new dedicated blog.
*/
void addFeed(String url) throws DbException, IOException;
Feed addFeed(String url) throws DbException, IOException;
/**
* Removes an RSS feed.
@@ -35,4 +36,8 @@ public interface FeedManager {
*/
List<Feed> getFeeds() throws DbException;
/**
* Returns a list of all added RSS feeds
*/
List<Feed> getFeeds(Transaction txn) throws DbException;
}

View File

@@ -17,9 +17,9 @@ public class ForumInvitationRequest extends InvitationRequest<Forum> {
public ForumInvitationRequest(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, Forum forum, @Nullable String text,
boolean available, boolean canBeOpened) {
boolean available, boolean canBeOpened, long autoDeleteTimer) {
super(id, groupId, time, local, read, sent, seen, sessionId, forum,
text, available, canBeOpened);
text, available, canBeOpened, autoDeleteTimer);
}
@Override

View File

@@ -15,9 +15,10 @@ public class ForumInvitationResponse extends InvitationResponse {
public ForumInvitationResponse(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accept, GroupId shareableId) {
SessionId sessionId, boolean accept, GroupId shareableId,
long autoDeleteTimer, boolean isAutoDecline) {
super(id, groupId, time, local, read, sent, seen, sessionId,
accept, shareableId);
accept, shareableId, autoDeleteTimer, isAutoDecline);
}
@Override

View File

@@ -11,6 +11,7 @@ import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
@@ -59,6 +60,12 @@ public interface ForumManager {
*/
ForumPostHeader addLocalPost(ForumPost p) throws DbException;
/**
* Stores a local forum post.
*/
ForumPostHeader addLocalPost(Transaction txn, ForumPost p)
throws DbException;
/**
* Returns the forum with the given ID.
*/
@@ -74,16 +81,32 @@ public interface ForumManager {
*/
Collection<Forum> getForums() throws DbException;
/**
* Returns all forums to which the user subscribes.
*/
Collection<Forum> getForums(Transaction txn) throws DbException;
/**
* Returns the text of the forum post with the given ID.
*/
String getPostText(MessageId m) throws DbException;
/**
* Returns the text of the forum post with the given ID.
*/
String getPostText(Transaction txn, MessageId m) throws DbException;
/**
* Returns the headers of all posts in the given forum.
*/
Collection<ForumPostHeader> getPostHeaders(GroupId g) throws DbException;
/**
* Returns the headers of all posts in the given forum.
*/
List<ForumPostHeader> getPostHeaders(Transaction txn, GroupId g)
throws DbException;
/**
* Registers a hook to be called whenever a forum is removed.
*/
@@ -94,6 +117,11 @@ public interface ForumManager {
*/
GroupCount getGroupCount(GroupId g) throws DbException;
/**
* Returns the group count for the given forum.
*/
GroupCount getGroupCount(Transaction txn, GroupId g) throws DbException;
/**
* Marks a message as read or unread and updates the group count.
*/

View File

@@ -1,7 +1,7 @@
package org.briarproject.briar.api.forum;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.briar.api.identity.AuthorInfo;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.client.PostHeader;

View File

@@ -18,5 +18,5 @@ public interface ForumSharingManager extends SharingManager<Forum> {
/**
* The current minor version of the forum sharing client.
*/
int MINOR_VERSION = 0;
int MINOR_VERSION = 1;
}

View File

@@ -0,0 +1,70 @@
package org.briarproject.briar.api.identity;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.nullsafety.NullSafety;
import org.briarproject.briar.api.attachment.AttachmentHeader;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class AuthorInfo {
public enum Status {
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES;
public boolean isContact() {
return this == UNVERIFIED || this == VERIFIED;
}
}
private final Status status;
@Nullable
private final String alias;
@Nullable
private final AttachmentHeader avatarHeader;
public AuthorInfo(Status status, @Nullable String alias,
@Nullable AttachmentHeader avatarHeader) {
this.status = status;
this.alias = alias;
this.avatarHeader = avatarHeader;
}
public AuthorInfo(Status status) {
this(status, null, null);
}
public Status getStatus() {
return status;
}
@Nullable
public String getAlias() {
return alias;
}
@Nullable
public AttachmentHeader getAvatarHeader() {
return avatarHeader;
}
@Override
public int hashCode() {
int hashCode = status.ordinal();
if (alias != null) hashCode += alias.hashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof AuthorInfo)) return false;
AuthorInfo info = (AuthorInfo) o;
return status == info.status &&
// aliases are equal
NullSafety.equals(alias, info.alias) &&
// avatars are equal
NullSafety.equals(avatarHeader, info.avatarHeader);
}
}

View File

@@ -0,0 +1,43 @@
package org.briarproject.briar.api.identity;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@NotNullByDefault
public interface AuthorManager {
/**
* Returns the {@link AuthorInfo} for the given author.
*/
AuthorInfo getAuthorInfo(AuthorId a) throws DbException;
/**
* Returns the {@link AuthorInfo} for the given author.
*/
AuthorInfo getAuthorInfo(Transaction txn, AuthorId a) throws DbException;
/**
* Returns the {@link AuthorInfo} for the given contact.
*/
AuthorInfo getAuthorInfo(Contact c) throws DbException;
/**
* Returns the {@link AuthorInfo} for the given contact.
*/
AuthorInfo getAuthorInfo(Transaction txn, Contact c)
throws DbException;
/**
* Returns the {@link AuthorInfo} for the {@link LocalAuthor}.
*/
AuthorInfo getMyAuthorInfo() throws DbException;
/**
* Returns the {@link AuthorInfo} for the {@link LocalAuthor}.
*/
AuthorInfo getMyAuthorInfo(Transaction txn) throws DbException;
}

View File

@@ -31,18 +31,18 @@ public interface IntroductionManager extends ConversationClient {
/**
* The current minor version of the introduction client.
*/
int MINOR_VERSION = 0;
int MINOR_VERSION = 1;
/**
* Sends two initial introduction messages.
*/
void makeIntroduction(Contact c1, Contact c2, @Nullable String text,
long timestamp) throws DbException;
void makeIntroduction(Contact c1, Contact c2, @Nullable String text)
throws DbException;
/**
* Responds to an introduction.
*/
void respondToIntroduction(ContactId contactId, SessionId sessionId,
long timestamp, boolean accept) throws DbException;
boolean accept) throws DbException;
}

View File

@@ -1,7 +1,7 @@
package org.briarproject.briar.api.introduction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.briar.api.identity.AuthorInfo;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
@@ -18,12 +18,12 @@ public class IntroductionRequest extends ConversationRequest<Author> {
private final AuthorInfo authorInfo;
public IntroductionRequest(MessageId messageId, GroupId groupId,
long time, boolean local, boolean read, boolean sent, boolean seen,
public IntroductionRequest(MessageId messageId, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, Author author, @Nullable String text,
boolean answered, AuthorInfo authorInfo) {
boolean answered, AuthorInfo authorInfo, long autoDeleteTimer) {
super(messageId, groupId, time, local, read, sent, seen, sessionId,
author, text, answered);
author, text, answered, autoDeleteTimer);
this.authorInfo = authorInfo;
}

View File

@@ -1,13 +1,13 @@
package org.briarproject.briar.api.introduction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.conversation.ConversationMessageVisitor;
import org.briarproject.briar.api.conversation.ConversationResponse;
import org.briarproject.briar.api.identity.AuthorInfo;
import javax.annotation.concurrent.Immutable;
@@ -25,9 +25,10 @@ public class IntroductionResponse extends ConversationResponse {
public IntroductionResponse(MessageId messageId, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accepted, Author author,
AuthorInfo introducedAuthorInfo, Role role, boolean canSucceed) {
AuthorInfo introducedAuthorInfo, Role role, boolean canSucceed,
long autoDeleteTimer, boolean isAutoDecline) {
super(messageId, groupId, time, local, read, sent, seen, sessionId,
accepted);
accepted, autoDeleteTimer, isAutoDecline);
this.introducedAuthor = author;
this.introducedAuthorInfo = introducedAuthorInfo;
this.ourRole = role;

View File

@@ -1,14 +0,0 @@
package org.briarproject.briar.api.messaging;
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 {
}

View File

@@ -7,22 +7,21 @@ public interface MessagingConstants {
/**
* The maximum length of a private message's text in UTF-8 bytes.
*/
int MAX_PRIVATE_MESSAGE_TEXT_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024;
int MAX_PRIVATE_MESSAGE_TEXT_LENGTH = MAX_MESSAGE_BODY_LENGTH - 2048;
/**
* The maximum length of an incoming private message's text in UTF-8 bytes.
* This is higher than MAX_PRIVATE_MESSAGE_TEXT_LENGTH for compatibility
* with older peers.
* <p>
* TODO: Remove after a reasonable migration period (added 2021-03-12).
*/
int MAX_PRIVATE_MESSAGE_INCOMING_TEXT_LENGTH =
MAX_MESSAGE_BODY_LENGTH - 1024;
/**
* The maximum number of attachments per private message.
*/
int MAX_ATTACHMENTS_PER_MESSAGE = 10;
/**
* The maximum length of an attachment's content type in UTF-8 bytes.
*/
int MAX_CONTENT_TYPE_BYTES = 50;
/**
* The maximum allowed size of image attachments.
* TODO: Different limit for GIFs?
*/
int MAX_IMAGE_SIZE = MAX_MESSAGE_BODY_LENGTH - 100; // 6 * 1024 * 1024;
}

View File

@@ -7,6 +7,8 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.attachment.AttachmentHeader;
import org.briarproject.briar.api.attachment.FileTooBigException;
import org.briarproject.briar.api.conversation.ConversationManager.ConversationClient;
import java.io.IOException;
@@ -30,13 +32,18 @@ public interface MessagingManager extends ConversationClient {
/**
* The current minor version of the messaging client.
*/
int MINOR_VERSION = 2;
int MINOR_VERSION = 3;
/**
* Stores a local private message.
*/
void addLocalMessage(PrivateMessage m) throws DbException;
/**
* Stores a local private message.
*/
void addLocalMessage(Transaction txn, PrivateMessage m) throws DbException;
/**
* Stores a local attachment message.
*
@@ -68,21 +75,8 @@ public interface MessagingManager extends ConversationClient {
String getMessageText(MessageId m) throws DbException;
/**
* Returns the attachment with the given message ID and content type.
*
* @throws InvalidAttachmentException If the header refers to a message
* that is not an attachment, or to an attachment that does not have the
* expected content type
* Returns the private message format supported by the given contact.
*/
Attachment getAttachment(AttachmentHeader h) throws DbException;
/**
* Returns true if the contact with the given {@link ContactId} does support
* image attachments.
*
* Added: 2019-01-01
*/
boolean contactSupportsImages(Transaction txn, ContactId c)
PrivateMessageFormat getContactMessageFormat(Transaction txn, ContactId c)
throws DbException;
}

View File

@@ -2,50 +2,73 @@ package org.briarproject.briar.api.messaging;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.briar.api.attachment.AttachmentHeader;
import java.util.List;
import javax.annotation.concurrent.Immutable;
import static java.util.Collections.emptyList;
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES;
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_IMAGES_AUTO_DELETE;
import static org.briarproject.briar.api.messaging.PrivateMessageFormat.TEXT_ONLY;
@Immutable
@NotNullByDefault
public class PrivateMessage {
private final Message message;
private final boolean legacyFormat, hasText;
private final boolean hasText;
private final List<AttachmentHeader> attachmentHeaders;
private final long autoDeleteTimer;
private final PrivateMessageFormat format;
/**
* Constructor for private messages in the legacy format, which does not
* support attachments.
* Constructor for private messages in the
* {@link PrivateMessageFormat#TEXT_ONLY TEXT_ONLY} format.
*/
public PrivateMessage(Message message) {
this.message = message;
legacyFormat = true;
hasText = true;
attachmentHeaders = emptyList();
autoDeleteTimer = NO_AUTO_DELETE_TIMER;
format = TEXT_ONLY;
}
/**
* Constructor for private messages in the current format, which supports
* attachments.
* Constructor for private messages in the
* {@link PrivateMessageFormat#TEXT_IMAGES TEXT_IMAGES} format.
*/
public PrivateMessage(Message message, boolean hasText,
List<AttachmentHeader> headers) {
this.message = message;
this.hasText = hasText;
this.attachmentHeaders = headers;
legacyFormat = false;
autoDeleteTimer = NO_AUTO_DELETE_TIMER;
format = TEXT_IMAGES;
}
/**
* Constructor for private messages in the
* {@link PrivateMessageFormat#TEXT_IMAGES_AUTO_DELETE TEXT_IMAGES_AUTO_DELETE}
* format.
*/
public PrivateMessage(Message message, boolean hasText,
List<AttachmentHeader> headers, long autoDeleteTimer) {
this.message = message;
this.hasText = hasText;
this.attachmentHeaders = headers;
this.autoDeleteTimer = autoDeleteTimer;
format = TEXT_IMAGES_AUTO_DELETE;
}
public Message getMessage() {
return message;
}
public boolean isLegacyFormat() {
return legacyFormat;
public PrivateMessageFormat getFormat() {
return format;
}
public boolean hasText() {
@@ -55,4 +78,8 @@ public class PrivateMessage {
public List<AttachmentHeader> getAttachmentHeaders() {
return attachmentHeaders;
}
public long getAutoDeleteTimer() {
return autoDeleteTimer;
}
}

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.api.messaging;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.briar.api.attachment.AttachmentHeader;
import java.util.List;
@@ -11,11 +12,29 @@ import javax.annotation.Nullable;
@NotNullByDefault
public interface PrivateMessageFactory {
/**
* Creates a private message in the
* {@link PrivateMessageFormat#TEXT_ONLY TEXT_ONLY} format.
*/
PrivateMessage createLegacyPrivateMessage(GroupId groupId, long timestamp,
String text) throws FormatException;
/**
* Creates a private message in the
* {@link PrivateMessageFormat#TEXT_IMAGES TEXT_IMAGES} format. This format
* requires the contact to support client version 0.1 or higher.
*/
PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
@Nullable String text, List<AttachmentHeader> headers)
throws FormatException;
/**
* Creates a private message in the
* {@link PrivateMessageFormat#TEXT_IMAGES_AUTO_DELETE TEXT_IMAGES_AUTO_DELETE}
* format. This format requires the contact to support client version 0.3
* or higher.
*/
PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
@Nullable String text, List<AttachmentHeader> headers,
long autoDeleteTimer) throws FormatException;
}

View File

@@ -0,0 +1,24 @@
package org.briarproject.briar.api.messaging;
public enum PrivateMessageFormat {
/**
* First version of the private message format, which doesn't support
* image attachments or auto-deletion.
*/
TEXT_ONLY,
/**
* Second version of the private message format, which supports image
* attachments but not auto-deletion. Support for this format was
* added in client version 0.1.
*/
TEXT_IMAGES,
/**
* Third version of the private message format, which supports image
* attachments and auto-deletion. Support for this format was added
* in client version 0.3.
*/
TEXT_IMAGES_AUTO_DELETE
}

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.api.messaging;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.attachment.AttachmentHeader;
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
import org.briarproject.briar.api.conversation.ConversationMessageVisitor;
@@ -19,8 +20,9 @@ public class PrivateMessageHeader extends ConversationMessageHeader {
public PrivateMessageHeader(MessageId id, GroupId groupId, long timestamp,
boolean local, boolean read, boolean sent, boolean seen,
boolean hasText, List<AttachmentHeader> headers) {
super(id, groupId, timestamp, local, read, sent, seen);
boolean hasText, List<AttachmentHeader> headers,
long autoDeleteTimer) {
super(id, groupId, timestamp, local, read, sent, seen, autoDeleteTimer);
this.hasText = hasText;
this.attachmentHeaders = headers;
}
@@ -37,5 +39,4 @@ public class PrivateMessageHeader extends ConversationMessageHeader {
public <T> T accept(ConversationMessageVisitor<T> v) {
return v.visitPrivateMessageHeader(this);
}
}

View File

@@ -2,7 +2,7 @@ package org.briarproject.briar.api.privategroup;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.briar.api.identity.AuthorInfo;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;

View File

@@ -1,7 +1,7 @@
package org.briarproject.briar.api.privategroup;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.briar.api.identity.AuthorInfo;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;

View File

@@ -8,21 +8,14 @@ import javax.annotation.concurrent.Immutable;
@NotNullByDefault
public class JoinMessageHeader extends GroupMessageHeader {
private final Visibility visibility;
private final boolean isInitial;
public JoinMessageHeader(GroupMessageHeader h, Visibility visibility,
boolean isInitial) {
public JoinMessageHeader(GroupMessageHeader h, boolean isInitial) {
super(h.getGroupId(), h.getId(), h.getParentId(), h.getTimestamp(),
h.getAuthor(), h.getAuthorInfo(), h.isRead());
this.visibility = visibility;
this.isInitial = isInitial;
}
public Visibility getVisibility() {
return visibility;
}
public boolean isInitial() {
return isInitial;
}

View File

@@ -12,6 +12,7 @@ import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
import java.util.Collection;
import java.util.List;
@NotNullByDefault
public interface PrivateGroupManager {
@@ -66,6 +67,11 @@ public interface PrivateGroupManager {
*/
void markGroupDissolved(Transaction txn, GroupId g) throws DbException;
/**
* Returns true if the given private group has been dissolved.
*/
boolean isDissolved(Transaction txn, GroupId g) throws DbException;
/**
* Returns true if the given private group has been dissolved.
*/
@@ -76,6 +82,12 @@ public interface PrivateGroupManager {
*/
GroupMessageHeader addLocalMessage(GroupMessage p) throws DbException;
/**
* Stores and sends a local private group message.
*/
GroupMessageHeader addLocalMessage(Transaction txn, GroupMessage p)
throws DbException;
/**
* Returns the private group with the given ID.
*/
@@ -91,26 +103,54 @@ public interface PrivateGroupManager {
*/
Collection<PrivateGroup> getPrivateGroups() throws DbException;
/**
* Returns all private groups the user is a member of.
*/
Collection<PrivateGroup> getPrivateGroups(Transaction txn)
throws DbException;
/**
* Returns the text of the private group message with the given ID.
*/
String getMessageText(MessageId m) throws DbException;
/**
* Returns the text of the private group message with the given ID.
*/
String getMessageText(Transaction txn, MessageId m) throws DbException;
/**
* Returns the headers of all messages in the given private group.
*/
Collection<GroupMessageHeader> getHeaders(GroupId g) throws DbException;
/**
* Returns the headers of all messages in the given private group.
*/
List<GroupMessageHeader> getHeaders(Transaction txn, GroupId g)
throws DbException;
/**
* Returns all members of the given private group.
*/
Collection<GroupMember> getMembers(GroupId g) throws DbException;
/**
* Returns all members of the given private group.
*/
Collection<GroupMember> getMembers(Transaction txn, GroupId g)
throws DbException;
/**
* Returns true if the given author is a member of the given private group.
*/
boolean isMember(Transaction txn, GroupId g, Author a) throws DbException;
/**
* Returns the group count for the given private group.
*/
GroupCount getGroupCount(Transaction txn, GroupId g) throws DbException;
/**
* Returns the group count for the given private group.
*/

View File

@@ -32,7 +32,7 @@ public interface GroupInvitationManager extends ConversationClient {
/**
* The current minor version of the private group invitation client.
*/
int MINOR_VERSION = 0;
int MINOR_VERSION = 1;
/**
* Sends an invitation to share the given private group with the given
@@ -43,7 +43,8 @@ public interface GroupInvitationManager extends ConversationClient {
* pending.
*/
void sendInvitation(GroupId g, ContactId c, @Nullable String text,
long timestamp, byte[] signature) throws DbException;
long timestamp, byte[] signature, long autoDeleteTimer)
throws DbException;
/**
* Responds to a pending private group invitation from the given contact.

View File

@@ -18,9 +18,10 @@ public class GroupInvitationRequest extends InvitationRequest<PrivateGroup> {
public GroupInvitationRequest(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, PrivateGroup shareable,
@Nullable String text, boolean available, boolean canBeOpened) {
@Nullable String text, boolean available, boolean canBeOpened,
long autoDeleteTimer) {
super(id, groupId, time, local, read, sent, seen, sessionId, shareable,
text, available, canBeOpened);
text, available, canBeOpened, autoDeleteTimer);
}
@Override

View File

@@ -15,9 +15,10 @@ public class GroupInvitationResponse extends InvitationResponse {
public GroupInvitationResponse(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accept, GroupId shareableId) {
SessionId sessionId, boolean accept, GroupId shareableId,
long autoDeleteTimer, boolean isAutoDecline) {
super(id, groupId, time, local, read, sent, seen, sessionId,
accept, shareableId);
accept, shareableId, autoDeleteTimer, isAutoDecline);
}
@Override

View File

@@ -15,9 +15,9 @@ public abstract class InvitationRequest<S extends Shareable> extends
public InvitationRequest(MessageId messageId, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, S object, @Nullable String text,
boolean available, boolean canBeOpened) {
boolean available, boolean canBeOpened, long autoDeleteTimer) {
super(messageId, groupId, time, local, read, sent, seen, sessionId,
object, text, !available);
object, text, !available, autoDeleteTimer);
this.canBeOpened = canBeOpened;
}

View File

@@ -11,8 +11,10 @@ public abstract class InvitationResponse extends ConversationResponse {
public InvitationResponse(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accepted, GroupId shareableId) {
super(id, groupId, time, local, read, sent, seen, sessionId, accepted);
SessionId sessionId, boolean accepted, GroupId shareableId,
long autoDeleteTimer, boolean isAutoDecline) {
super(id, groupId, time, local, read, sent, seen, sessionId, accepted,
autoDeleteTimer, isAutoDecline);
this.shareableId = shareableId;
}

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.api.sharing;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.briar.api.client.SessionId;
@@ -21,7 +22,7 @@ public interface SharingManager<S extends Shareable>
* including optional text.
*/
void sendInvitation(GroupId shareableId, ContactId contactId,
@Nullable String text, long timestamp) throws DbException;
@Nullable String text) throws DbException;
/**
* Responds to a pending group invitation
@@ -45,6 +46,12 @@ public interface SharingManager<S extends Shareable>
*/
Collection<Contact> getSharedWith(GroupId g) throws DbException;
/**
* Returns all contacts with whom the given group is shared.
*/
Collection<Contact> getSharedWith(Transaction txn, GroupId g)
throws DbException;
/**
* Returns true if the group not already shared and no invitation is open
*/

View File

@@ -0,0 +1,11 @@
package org.briarproject.briar.api.test;
import java.io.IOException;
import java.io.InputStream;
import javax.annotation.Nullable;
public interface TestAvatarCreator {
@Nullable
InputStream getAvatarInputStream() throws IOException;
}

View File

@@ -14,13 +14,16 @@ public interface TestDataCreator {
* @param numContacts Number of contacts to create. Must be >= 1
* @param numPrivateMsgs Number of private messages to create for each
* contact.
* @param avatarPercent Percentage of contacts
* that will use a random profile image. Between 0 and 100.
* @param numBlogPosts Number of blog posts to create.
* @param numForums Number of forums to create.
* @param numForumPosts Number of forum posts to create per forum.
*/
void createTestData(int numContacts, int numPrivateMsgs, int numBlogPosts,
int numForums, int numForumPosts);
void createTestData(int numContacts, int numPrivateMsgs, int avatarPercent,
int numBlogPosts, int numForums, int numForumPosts);
@IoExecutor
Contact addContact(String name) throws DbException;
Contact addContact(String name, boolean alias, boolean avatar)
throws DbException;
}

View File

@@ -0,0 +1,61 @@
package org.briarproject.briar.api.identity;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.briar.api.attachment.AttachmentHeader;
import org.junit.Test;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.attachment.MediaConstants.MAX_CONTENT_TYPE_BYTES;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.NONE;
import static org.briarproject.briar.api.identity.AuthorInfo.Status.VERIFIED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class AuthorInfoTest extends BrambleTestCase {
private final String contentType = getRandomString(MAX_CONTENT_TYPE_BYTES);
private final AttachmentHeader avatarHeader =
new AttachmentHeader(new GroupId(getRandomId()),
new MessageId(getRandomId()), contentType);
@Test
public void testEquals() {
assertEquals(
new AuthorInfo(NONE),
new AuthorInfo(NONE, null, null)
);
assertEquals(
new AuthorInfo(NONE, "test", null),
new AuthorInfo(NONE, "test", null)
);
assertEquals(
new AuthorInfo(NONE, "test", avatarHeader),
new AuthorInfo(NONE, "test", avatarHeader)
);
assertNotEquals(
new AuthorInfo(NONE),
new AuthorInfo(VERIFIED)
);
assertNotEquals(
new AuthorInfo(NONE, "test", null),
new AuthorInfo(NONE)
);
assertNotEquals(
new AuthorInfo(NONE),
new AuthorInfo(NONE, "test", null)
);
assertNotEquals(
new AuthorInfo(NONE, "a", null),
new AuthorInfo(NONE, "b", null)
);
assertNotEquals(
new AuthorInfo(NONE, "a", null),
new AuthorInfo(NONE, "a", avatarHeader)
);
}
}

View File

@@ -1,8 +1,10 @@
dependencyVerification {
verify = [
'junit:junit:4.13.2:junit-4.13.2.jar:8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3',
'org.codehaus.mojo.signature:java16:1.1:java16-1.1.signature:53799223a2c98dba2d0add810bed76315460df285c69e4f397ae6098f87dd619',
'org.codehaus.mojo:animal-sniffer-ant-tasks:1.16:animal-sniffer-ant-tasks-1.16.jar:890040976fbe2d584619a6a61b1fd2e925b3b5eb342a85eb2762c467c0d64e90',
'org.codehaus.mojo:animal-sniffer:1.16:animal-sniffer-1.16.jar:72be8bcc226ba43b937c722a08a07852bfa1b11400089265d5df0ee7b38b1d52',
'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
'org.ow2.asm:asm-all:5.2:asm-all-5.2.jar:7fbffbc1db3422e2101689fd88df8384b15817b52b9b2b267b9f6d2511dc198d',
]
}